test(plugin-security): stop naming member_default as the plain-wildcard shape, and pin the relation (#6842) - #6958
Merged
Conversation
…card shape, and pin the relation (#6842) #5491 (PR #6684) removed `member_default`'s plain `'*'` wildcard grant. Three pieces of prose named that set as THE plain-wildcard example and all three went stale without a gate moving. #6696 / PR #6846 repaired the `packages/spec` JSDoc; the two `it()` titles in this package survived. Re-worded both so they no longer name `member_default` for a shape it does not have. Measured, `viewer_readonly`'s wildcard is read-ONLY, so the fixtures stay synthetic rather than being re-pointed at it — the assertions are unchanged, they already pin the correct predicate. Added `audience-anchor-set-claims.pin.test.ts` in the #6628 idiom: a classification of the sets the two watched prose surfaces name, closed in both directions and checked against the shipped `defaultPermissionSets` and the shipped predicate. `plugin-security` is the only possible home — the authority is the array itself, which `packages/spec` cannot import without inverting the dependency graph. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BM1tNf5U3nEbHKR4fo5qVQ
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckNo hand-written docs reference the 0 changed package(s). ✅ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #6842
What drifted
#5491 (PR #6684) removed
member_default's plain'*'wildcard grant. Three separate pieces of prose named that set as THE worked example of a plain wildcard, and all three went stale without a single gate moving. #6696 / PR #6846 repaired thepackages/specdescribeHighPrivilegeBitsJSDoc. The twoit()titles one package over survived, in the behavioural pin for that very function.Premise re-measured at this branch point
Re-measured at
68feaadd6by probing the real importeddefaultPermissionSetsagainst the real predicates — not a transcription of the card. Both stale names are still live at:65and:103, and the array says:The probe found a trap in the card's own suggested fix. #6842 offers "e.g. name
viewer_readonly" — but measured,viewer_readonly's wildcard isallowCreate: false, allowEdit: false, i.e. read-ONLY, while the fixture is read/create/edit. A straight substitution would have replaced one stale illustration with a differently stale one. Measured across all eight shipped sets, no set matches the fixture exactly: the three admin sets carry system permissions,mcp_agent_data_writecarries delete,member_defaultandmcp_agent_restrictedcarry no wildcard, andviewer_readonly/mcp_agent_data_readcarry read-only wildcards. The fixture is synthetic — it is whatmember_defaultwas before #5491 — so the naming now says exactly that.Option taken: B (A plus a guard)
A (the core). Both titles re-worded so they no longer name
member_defaultfor a shape it does not have.:65drops the— member_default's shapeclause;:103's title is kept verbatim because it is still true (member_defaultcarries noallowExportand still resolves anchor-safe), and only the comment is extended to say which of its two fixtures models the baseline and which does not.⛔ The assertions are byte-for-byte unchanged. They pin the correct predicate — D5 genuinely does not flag read/create/edit on
'*'. This was naming drift, not a coverage hole.B (the guard). New
packages/plugins/plugin-security/src/audience-anchor-set-claims.pin.test.ts, in the #6628 idiom.plugin-securityis the only possible home: the authority is thedefaultPermissionSetsarray itself, whichpackages/speccannot import without inverting the dependency graph — which is why #6696 deliberately shipped without one.The authority is machine-read (the real array, the real predicates). The prose is machine-read too — shipped set names are exact snake_case tokens, so scanning needs no heuristics. What is hand-written is only the classification: for each set the prose names, whether it is invoked as a wildcard carrier and whether it is claimed to stay anchor-bindable. Both directions are closed:
Two surfaces are watched: this package's
audience-anchors.test.ts, and thedescribeHighPrivilegeBitsJSDoc block inpackages/spec(anchored on the declaration, not on line numbers, with an explicit re-anchor message). Watching both is deliberate — one change staled three sentences, so a pin covering one site would leave the same hole.Reverse verification — direction predicted before running
viewer_readonly's'*'from the shipped arrayviewer_readonly: claimed wildcard=true, shipped wildcard=falsemember_defaultrow towildcard: trueviewer_readonlyrow while its name stays in the proseMutation 1 is the load-bearing reading: it is the #5491 drift replayed against the shipped array, and it turns red. Had this pin existed then, that PR could not have landed without flipping the row — and flipping the row is what forces an author to confront the three sentences the flip invalidates.
Honest deltas
member_defaulttwo lines from the word "wildcard" precisely in order to say it has none. What the pin buys is narrower and real: amember_default's*wildcard object grant (C/R/E) union-merges into every org member — app-side explicit-allow object gates are erased on three axes #5491-class change can no longer pass in silence, it must now write a false row on purpose. This limit is written into the pin's own header so it is not mistaken for more, and option A — not the pin — is what fixes today's text.Anti-vacuity: a floor on the shipped-array size plus an explicit assertion that each watched surface yields non-empty prose that names at least one set; two synthetic self-tests, one per closure direction, including a prefix-discipline case proving
organization_admin_no_bypasscannot answer fororganization_admin.Deliberately NOT done
packages/spec— this PR only reads that file's text. docs(spec): describeHighPrivilegeBits 的裸通配符举例换成仍带 '*' 的 viewer_readonly (#6696) #6846 already fixed it.skip-changesetapplied.Gates
pnpm --filter @objectstack/plugin-security testpnpm --filter @objectstack/plugin-security typechecktsc --noEmit, no output)pnpm lint(repo ESLint)check:nul-bytes+ targeted control-byte self-scancheck:doc-authoring,check:role-word,check:adr-anchors,check:wildcard-fallthrough,check:engine-double-contract,check:error-code-casing,check:route-envelope🤖 Generated with Claude Code
https://claude.ai/code/session_01BM1tNf5U3nEbHKR4fo5qVQ
Generated by Claude Code