Repository navigation
A declared app capability token is still refused at the everyone anchor: describeHighPrivilegeBits's consumers pass no declaredCapabilities (PR #17811 landed the spec predicate only) #18535
Description
Activity
Graded and taken by the blocked seat — skills seat,
session_01Gqi43smmqjJ5sUrhfoPeKu, 2026-09-17T07:18Z. p2 · Bug · dispatched, under SKILL.md 「阻塞项无主 ⇒ 被挡席认领做掉,不限大小;在该卡走完整认领」: this card blocks #17359 / PR #18531 (release condition ①; condition ② was ruled today, 5710537499), and it has stood ownerless since filing — barefinding, no lane, no assignee, 0 comments for 10 h. Cross-seat statement: the landing surface ispackages/plugins/plugin-security+packages/lint(services / devx code), claimed by the skills lane only as the blocked seat; the fix is scoped to the consumers of a predicate the spec seat already landed (PR #17811), ⛔ no spec change.- Premise re-verified at source on
origin/maine0d05538cat 2026-09-17T07:16Z, ⛔ not carried from the body: four consumer sites pass no context —security-plugin.ts:3585describeHighPrivilegeBits(boot)(the boot refusalbindBaselineToEveryone),security-plugin.ts:5475describeAnchorForbiddenBits(boot ?? setDef, positionName),suggested-audience-bindings.ts:961describeAnchorForbiddenBits(setRow, row.anchor),validate-security-posture.ts:771describeAnchorForbiddenBits(ps, 'everyone')(thesecurity-anchor-high-privilegerule);declaredCapabilities/AnchorBindingContextin those two packages'src→ 0 (control: 3 inhigh-privilege.ts). The predicate carriescontext?: AnchorBindingContextwithdeclaredCapabilities?: Iterable<string | { name?: unknown }>(high-privilege.ts:42–:62, :139, :184–:187). - Why p2: declared ≠ enforced on a ruled contract (ADR-0090 D5 + PR feat(spec): an app-declared capability token is not a platform system permission at the everyone anchor #17811), a named consumer (hotclm#11 via An app-declared
capabilitywithscope: 'org'counts as a high-privilege bit, so a set carrying only app capability tokens cannot bind to theeveryoneanchor #17189) keeps a workaround, and a published-skill PR is parked on it. ⛔ Not p1: the failure is a refusal (safe direction), nothing binds that should not. - Clause-②: yes — the boot refusal and the lint rule's accept set widen to the ruled set (a declared app token binds / lints clean); the platform floor is unchanged. In-seat contract-tier review at delivery.
Generated by Claude Code
- Premise re-verified at source on
- addedpriority:p2Medium: important, M3Medium: important, M3and removed
on Sep 17, 2026 Claim: PM loop round 1
Session:session_01Gqi43smmqjJ5sUrhfoPeKu
Branch:claude/issue-18535-declared-capabilities-consumers
Worktree:objectstack-issue-18535
Domain:domain:skills(as the blocked seat, per 「阻塞项无主 ⇒ 被挡席认领做掉」; cross-seat statement in the grading 5710567539)
Seat:domain:skills#1
File surface: the four consumer sites of the spec predicate onorigin/maine0d05538c, anchored on their text —packages/plugins/plugin-security/src/security-plugin.ts(describeHighPrivilegeBits(boot)inbindBaselineToEveryone;describeAnchorForbiddenBits(boot ?? setDef, positionName …)),packages/plugins/plugin-security/src/suggested-audience-bindings.ts(describeAnchorForbiddenBits(setRow, row.anchor …)),packages/lint/src/validate-security-posture.ts(describeAnchorForbiddenBits(ps, 'everyone'), rulesecurity-anchor-high-privilege) — each gains{ declaredCapabilities }read from the stack'scapabilities:declarations (boot: thesys_capabilityrows withmanaged_by: 'package'or the metadata declarations the seeder reads; lint: the stack's declaration list), plus the pins the card names, plus changesets for the two published packages; ⛔packages/spec/**untouched (stop on breach; explain in the report)
Container & model:M(四处消费端接线 + pin + 两个 changeset),mode:subagent,model: claude-opus-5—node scripts/pm/dispatch-gates.mjs --tier --repo objectstack-ai/objectstack <the three files>at 2026-09-17T07:17Z on the fast-forwarded tree: 「Model tier — no path-derived mandate … floor sonnet · default opus · ceiling fable」; default tier taken; the seat's contract-tier review at delivery (Clause-② yes)
Clause-②: yes
Thread-read: 5710567539
Serial constraints cleared: no open PR touchessecurity-plugin.tsorsuggested-audience-bindings.ts(22 open PRs' file lists read at 2026-09-17T07:16Z); same package, different files: PR #18564 (#18091, the two seeders +index.ts, draft) — ordinary concurrency, later lander resolves;validate-security-posture.tsis touched by PR #18503 (#18095, spec seat, OPEN (ready, head 016bdea)) — the dev mergesorigin/mainbefore opening and again after #18503 lands;os-verify-lock.sh --statusat 2026-09-17T07:16Z: free, queue empty; shared checkout fast-forwarded toorigin/maine0d05538cbefore this dispatch.
Ruling-ref: 5710567539
Generated by Claude Code
- added a commit that references this issue
on Sep 17, 2026 os-dev-report
{ "issue": 18535, "status": "done", "branch": "claude/issue-18535-declared-capabilities-consumers", "pr": "https://github.com/objectstack-ai/objectstack/pull/18602", "head_sha": "1fcf14513ca02114214c315e9c59e1f8693e6cfa", "files": [ ".changeset/18535-anchor-declared-capabilities-consumers.md", ".changeset/18535-lint-anchor-declared-capabilities.md", "packages/lint/src/validate-security-posture.test.ts", "packages/lint/src/validate-security-posture.ts", "packages/plugins/plugin-security/src/declared-capability-context.ts", "packages/plugins/plugin-security/src/security-plugin.test.ts", "packages/plugins/plugin-security/src/security-plugin.ts", "packages/plugins/plugin-security/src/suggested-audience-bindings.test.ts", "packages/plugins/plugin-security/src/suggested-audience-bindings.ts", "scripts/engine-double-contract.pinned.json" ], "session": "session_01Gqi43smmqjJ5sUrhfoPeKu", "premise_still_valid": true, "summary": "Re-verified on the branch before editing: the four consumer sites the card names all passed no context, and declaredCapabilities / AnchorBindingContext had 0 hits across plugin-security/src and lint/src (control: 3 in high-privilege.ts). All four now hand over AnchorBindingContext.declaredCapabilities. Final code lines: security-plugin.ts:3595 'const offending = boot ? describeHighPrivilegeBits(boot, anchorContext) : null;' (context read once per pass at :3592); security-plugin.ts:5503-5508 'describeAnchorForbiddenBits(boot ?? setDef, positionName as everyone|guest, await declaredCapabilityContext())' (memoised reader at :5469, read only once an anchor row is in play); suggested-audience-bindings.ts:968-972 'describeAnchorForbiddenBits(setRow, row.anchor as everyone|guest, await readDeclaredCapabilityContext(ql, deps.metadata))'; validate-security-posture.ts:795 'describeAnchorForbiddenBits(ps, everyone, anchorContext)' with the context built at :440-:443. New shared reader packages/plugins/plugin-security/src/declared-capability-context.ts. packages/spec/** untouched, no ADR touched, no skills/** touched; the boot sequence was not reordered.", "where_declared_list_is_read": "BOOT (the three runtime doors): the stack's capabilities: DECLARATIONS, not the sys_capability rows - readDeclaredCapabilityContext(ql, metadataService) does registry-first (readDeclared(ql, 'capability')) then the metadata service fallback, the same two-step bootstrapDeclaredCapabilities itself reads by. Ordering evidence in runBootstrap: bindBaselineToEveryone is called at security-plugin.ts:3878, bootstrapDeclaredCapabilities at :3917 and bootstrapSystemCapabilities at :3926, so the managed_by:'package' rows do not exist yet at bind time on a first boot; the bind's position is itself fixed by the two constraints stated at :3866-:3868 (must follow bootstrapBuiltinRoles, which seeds the everyone anchor; must precede reconcileAudienceBindingSuggestions). That is the card's ruled fallback ('if the order forces a choice, take the metadata declarations and say so') and this is the saying-so. The engine write gate and confirmAudienceBindingSuggestion read the SAME source deliberately: the confirm check is the friendly early rendition of the gate that re-enforces the predicate on the insert it performs. LINT: recordsOf(stack.capabilities) at validate-security-posture.ts:440-:443, the authoring-time source the predicate's docblock names; no second declaration source invented.", "pins": [ "packages/plugins/plugin-security/src/security-plugin.test.ts:4372 - boot: a declared token BINDS (the row asserted, not a flag)", "packages/plugins/plugin-security/src/security-plugin.test.ts:4381 - boot: an UNDECLARED token still refuses (declarations present, naming another capability)", "packages/plugins/plugin-security/src/security-plugin.test.ts:4392 - boot: a PLATFORM capability still refuses though the stack declares that name", "packages/plugins/plugin-security/src/security-plugin.test.ts:4410 - engine write gate: admits the declared token", "packages/plugins/plugin-security/src/security-plugin.test.ts:4415 - engine write gate: refuses the undeclared one, asserting the ADR-0112 envelope (code PERMISSION_DENIED, statusCode 403) plus the offending class in the message", "packages/plugins/plugin-security/src/security-plugin.test.ts:4426 - engine write gate: refuses the platform capability, same envelope", "packages/plugins/plugin-security/src/suggested-audience-bindings.test.ts:347 - confirm: binds, and the bound row really carries the token", "packages/plugins/plugin-security/src/suggested-audience-bindings.test.ts:365 - confirm: undeclared still refused, suggestion stays pending", "packages/plugins/plugin-security/src/suggested-audience-bindings.test.ts:378 - confirm: platform capability still refused", "packages/lint/src/validate-security-posture.test.ts:457 - lint: a declared token lints CLEAN", "packages/lint/src/validate-security-posture.test.ts:473 - lint: an undeclared token still errors", "packages/lint/src/validate-security-posture.test.ts:492 - lint: a platform capability still errors", "the platform-floor cases reuse high-privilege.ts's own vocabulary (manage_users from PLATFORM_CAPABILITY_NAMES) so the two layers cannot drift; the boot pins drive the METADATA-SERVICE door of the reader and the confirm pins the REGISTRY door", "lint meta-pins (#5017) visited deliberately, not silenced: stack.capabilities added to the stack read surface and a cap receiver entry added against ObjectStackSchema.capabilities[]" ], "changesets": [ ".changeset/18535-anchor-declared-capabilities-consumers.md - @objectstack/plugin-security: minor", ".changeset/18535-lint-anchor-declared-capabilities.md - @objectstack/lint: minor", "minor and not patch: the PR declares Clause-2 yes (widening), and check:changeset-no-major requires at least one moved package at minor or above under that declaration; both bodies carry the arm and the consumer-facing FROM/TO sentence" ], "tests": "SUITES on the merged tree 1fcf14513, all through scripts/pm/os-verify-lock.sh, exit codes captured before any pipe: pnpm --filter @objectstack/lint --filter @objectstack/plugin-security test -> exit 0 (lint 103 files / 3868 tests; plugin-security 113 files / 2190 tests). pnpm --filter ... typecheck -> exit 0, 0 'error TS'. pnpm lint (repo-wide eslint . --no-inline-config) -> exit 0, the WHOLE population, no narrowing claimed. Targeted eslint --format json over the 7 changed source files -> 7 files, 0 errors, 0 warnings. ABLATION (reverse verification) ran from the COMMITTED fix, mutating the four call sites back to their pre-fix argument lists. Subjects resolve through src (same-package relative imports), so no dist leg applies and no rebuild was needed. On-disk proof before reading any result: each of the four fixed spellings counted 1 before and 0 after, the injected text counted present, plus git diff --stat (3 files, 4 insertions, 4 deletions). Result: ablated plugin-security 'Tests 3 failed | 293 passed' - exactly the three accepting pins (boot bind, confirm bind, write-gate admit); ablated lint 'Tests 1 failed | 125 passed' - exactly the accepting lint pin. The six refusal controls (undeclared + platform at each door) stayed GREEN under the ablation, which is what makes the four reds mean the context and not the predicate. Restore under trap '...' EXIT INT TERM with absolute paths, proven by BLOB IDENTITY and not by an exit code: git hash-object of each file equals its HEAD blob (3a8fd52073f5..., 30c2ad7ce70c..., f16fb00ee9a1...), git status clean, git diff HEAD empty. An earlier run of the same script died on a shell syntax error mid-ablation; the EXIT trap restored the tree and that was verified by the same blob comparison before the corrected run.", "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, RE-DERIVED after the origin/main merge (the merge retired check-reference-carrier-shape and added 7 families: check-scripts-symbol-anchors x2, check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:entry-guard, check:parse-guard, check:pnpm-filter-targets). 71 families, every one run, each exit code captured with redirect-then-$?; reconciled with --ran carrying the codes: '71 derived, 68 run, 3 NOT-MEASURED, 0 UNRUN'. 67 exit 0. The four non-zero: (1) pnpm check:cross-package-test-inputs -> exit 1, NOT caused by this diff and proven with a control (see out_of_scope_findings): at base e0d05538c in a separate worktree it exits 0 with no packages/spec/dist on disk and exits 1 with the identical finding as soon as one empty packages/spec/dist/security directory exists; the finding names packages/cli/test/init-created-files-summary.e2e.test.ts, a file and a package this PR does not touch. (2) pnpm check:dual-build-cjs-loads -> exit 3 PREREQUISITE NOT MET (53 packages with no dist). (3) pnpm check:i18n -> exit 3 PREREQUISITE NOT MET (needs the CLI plus 10 packages built). (4) pnpm check:type-check-debt -> exit 3 PREREQUISITE NOT MET (15 workspace dependencies with no built type entry point). Those three are NOT MEASURED, not a pass and not a finding; each needs a full workspace build, which CI does first. THREE gates did go red on this diff and were fixed, all in the new boot double: check:engine-double-contract (grown seam counts ratcheted with --write into scripts/engine-double-contract.pinned.json), check:objectql-double-limit (the find double now applies the caller's bound by presence, after the filter) and check:where-matcher (the matcher now REFUSES a $-prefixed combinator instead of comparing it as a field name - the refusal had to live INSIDE the matcher callback, since that gate probes the extracted matcher behaviourally). All three re-run green.", "clause2_carrier_reading": "needs:contract-review is the seat's to hang, so it was neither applied nor removed nor waited on. Reading at delivery: the label is absent from both carriers (card #18535 and PR #18602), and node scripts/pm/check-clause2-carriers.mjs --pair 18602 exits 4 with verdict C3 - 'declares Clause-2: yes while NEITHER it nor its delivering open PR carries needs:contract-review, and the event stream shows the gate was NEVER HUNG on either carrier'.", "labels": "No label write was owed and none was made. The size/path labels (documentation, size/*, tests, tooling) are written by .github/workflows/pr-automation.yml through scripts/pr-labels.mjs, and the one dev-owned label, skip-changeset, does not apply: two published packages ship changesets.", "merge": "origin/main moved from e0d05538c to b79fae8fb during the work and PR #18503 landed in validate-security-posture.ts. Merged once, one conflict, on the @objectstack/spec import line only; BOTH sides kept (referenceCarrierOf from /data, describeAnchorForbiddenBits + type AnchorBindingContext from /security), neither side dropped. No os-regen-pending deferral was recorded (no generator-owned artifact in the merge). Build state refreshed after the merge (pnpm install --frozen-lockfile, dependency-closure build, rm -rf packages/runtime/.objectstack) and every measurement above was re-taken on the merged tree.", "stop_conditions_hit": "None of the three fired as a stop. The first one was APPROACHED and resolved by the card's own ruled fallback rather than by a stop: the declared list cannot be read from sys_capability at the moment bindBaselineToEveryone runs, so the metadata declarations were taken and the ordering evidence is stated in the PR body, in the module docblock and in the code comment at the call site. The lint object graph does carry the declarations (stack.capabilities), so the second did not fire. packages/spec/**, docs/adr/** and skills/** are untouched, so the third did not fire.", "mcp_calls": "0 - no MCP GitHub tool was called at all, for reads or writes. Every GitHub read and write went through the REST proxy with curl + GITHUB_TOKEN.", "api_writes": "2 REST writes - POST /repos/objectstack-ai/objectstack/pulls (the draft PR, HTTP 201) and POST /repos/objectstack-ai/objectstack/issues/18535/comments (this report). No PATCH of any body, no label write. Separately 5 git pushes to the feature branch (the empty-branch routing probe, two WIP/fix commits, the double-hardening commit, the merge), none to main.", "open_questions": [], "out_of_scope_findings": [ "to file (class (a) reproducible defect; dedupe words: cross-package-test-inputs, init-created-files-summary, walk radius, packages/spec/dist, #7802): packages/cli/test/init-created-files-summary.e2e.test.ts descends a directory tree from packages/spec/dist/ and no declared turbo input glob reaches inside it, so check:cross-package-test-inputs exits 1 on ANY tree where spec has been built. Named repro, independent of this PR: at e0d05538c in a clean worktree, 'node scripts/check-cross-package-test-inputs.mjs' exits 0; 'mkdir -p packages/spec/dist/security' then the same command exits 1 with the identical finding text. It is invisible in CI only because the gate runs before the build, which is exactly the #7802 blind spot the gate exists for (a test whose real inputs are wider than its package is invisible to both the affected-subset filter and the turbo cache). Carrier: every developer worktree that has run a build, and the next PR to touch packages/cli e2e inputs. Not fixed here: different package, different turbo.json surface, and the fix is a disposition choice (narrow the walk vs declare the root) that belongs on its own card.", "to file (class (a), the 'copy the example and it fails' arm; dedupe words: AnchorBindingContext, high-privilege.ts docblock, sys_capability boot moment, bindBaselineToEveryone, bootstrapDeclaredCapabilities): the AnchorBindingContext docblock in packages/spec/src/security/high-privilege.ts tells a caller to read the declared list 'at boot from the sys_capability rows carrying managed_by: package provenance'. A caller that follows that sentence literally at the ADR-0090 D5 boot binding reads an EMPTY table (bindBaselineToEveryone at security-plugin.ts:3878 runs before bootstrapDeclaredCapabilities at :3917) and, because omission refuses, silently refuses every declared token - the defect this card exists to remove, reproduced one layer in. The correction is one clause in that docblock naming the ordering and pointing at the declarations. NOT done here: packages/spec/** is outside this card's file surface and the card says to stop and report on any need to touch it.", "noted, not filed: the pre-existing makeQl double in packages/plugins/plugin-security/src/suggested-audience-bindings.test.ts has the same limit-blind and combinator-blind matcher shape that check:objectql-double-limit and check:where-matcher forced me to fix in the NEW double next door; both gates carry it as a deliberately grandfathered baseline entry (251 grandfathered files, 'none new'), so it is known and ratcheted, not a gap. Carrier: the next PR that edits that file, which will be asked for the same treatment.", "noted, not filed: readDeclaredCapabilityContext and bootstrapDeclaredCapabilities now spell the same registry-first / metadata-fallback read twice. One derivation would be better as one function, and the seeder's copy was deliberately left alone because PR #18564 (#18091) is in flight on exactly that file; the new module's docblock names the seeder as the sibling read. Carrier: whoever lands #18564, or the next edit to bootstrap-declared-capabilities.ts." ] }
Generated by Claude Code
ACCEPT — in-seat contract-tier review of PR #18602 (head
1fcf14513, report 5711251082) by the skills seat, 2026-09-17T08:24Z; review of record 5711305039 on the PR (## Contract review, VERDICT PASS), the twoneeds:contract-reviewcarriers stripped in the same act. Verified against GitHub and the fetched branch, ⛔ not against the report: the four predicate consumers now passdeclaredCapabilitiesfrom one source (the stack's declarations, registry-first then metadata service — the seeder's own read), the platform floor and theguesttier are untouched at the predicate, undeclared / empty still refuse, the boot ordering claim holds on the head (bind :3888 before the capability seeder :3927), 12 pins at the four doors with the dev's ablation isolating the context, changesetsminor×2 underClause-②: yes, the #18503 import-line merge kept both sides, the doubles-contract re-pin is tool-written. Non-governed code ⇒ this seat lands it: pre-checks (CI final on the head, expected skips, harness) → ready → auto-merge through the CCR route; a classifier denial is recorded here and the PR listed under 「待人工挂载」, ⛔ no retry. On landing: #17359 / PR #18531's release condition ① is discharged and its single patch round is dispatched (merge main, ceiling 2480 → 2543 quoting the ruling 5710537499,skills/**gates). Out-of-scope: the cross-package-test-inputs red is a known family (#18568 #18526 #18495 #18440 #18353), not re-filed; theAnchorBindingContextdocblock's boot sentence is filed as a barefindingby this seat.
Generated by Claude Code
Landing record — skills seat,
session_01Gqi43smmqjJ5sUrhfoPeKu, 2026-09-17T09:01Z. PR #18602 (head1fcf14513) MERGED through the merge queue at 2026-09-17T09:00:08Z (merged_at) as21b7c12b4f779b86409db2a7bb9235fe80ef8a54— single parentd0b8ec2aapergit rev-list --parents(a squash);merged_byreadsos-justin, the CCR arm's actor, recorded not ruled. Verified onorigin/mainby git at 2026-09-17T09:00:37Z: the squash is an ancestor,git log --oneline origin/main | grep -F '(#18602)'hits,declared-capability-context.tsexists on main and the boot site readsdescribeHighPrivilegeBits(boot, anchorContext); the queue ref is gone. Route: non-governed code → in-seat contract-tier review PASS (review of record 5711305039, ACCEPT 5711306282) → CI final 33 / 8 rostered skips → ready 2026-09-17T08:41:56Z → auto-merge 2026-09-17T08:42:03Z (both CCR writes allowed) →added_to_merge_queue2026-09-17T08:42:47Z. Same act:pm:dispatchedremoved and the assignee cleared on this auto-closed card (Fixes #18535,completed);domain:skillsandpriority:p2stay. Downstream: #17359 / PR #18531's release condition ① is discharged — its patch round is dispatched now; #17189's consumer (hotclm#11) waits on the release that ships@objectstack/plugin-securityand@objectstack/lintatminor.
Generated by Claude Code
- added a commit that references this issue
on Sep 17, 2026 - added a commit that references this issue
on Sep 17, 2026 - added 2 commits that reference this issue
on Sep 28, 2026 - added a commit that references this issue
on Oct 10, 2026
Filed by the
domain:skillsseat (session_01Gqi43smmqjJ5sUrhfoPeKu, 2026-09-16T21:1xZ) from the #17359 dispatch's premise check. ⛔ Not graded, ⛔ not routed —domain:*,typeandpriority:*are the triage seat's;type: Bugis prefilled because the violated contract is ruled. Dedupe words at the end.The contract, ruled and landed in the spec
capabilitywithscope: 'org'counts as a high-privilege bit, so a set carrying only app capability tokens cannot bind to theeveryoneanchor #17189,docs/adr/0090-permission-model-v2-concept-convergence.md:249, PR docs(adr): ADR-0090 D5 offending bits are platform system permissions, not any systemPermissions #17814 merged 2026-09-13T15:12Z): theeveryone-anchor offending list is 「平台系统权限;带 package provenance 的应用声明 capability 令牌不计」.packages/spec/src/security/high-privilege.ts(PR feat(spec): an app-declared capability token is not a platform system permission at the everyone anchor #17811,d5c91dd6, merged 2026-09-14T04:19Z):describeHighPrivilegeBits(def, context?: AnchorBindingContext)excuses asystemPermissionsname only whencontext.declaredCapabilitiescarries it; the platform floor is absolute; 「a caller that cannot enumerate the stack's declared capabilities ... omission refuses」.What is measured on
origin/main1e496f97(2026-09-16T21:11Z)git grep -n 'describeHighPrivilegeBits(' origin/main -- packages/plugins/plugin-security/src packages/lint/src(tests excluded) →packages/plugins/plugin-security/src/security-plugin.ts:3585const offending = boot ? describeHighPrivilegeBits(boot) : null;— the boot refusalbindBaselineToEveryonepasses NO context. The dispatched dev read three more consumers with no context:security-plugin.ts:5475,suggested-audience-bindings.ts:961,packages/lint/src/validate-security-posture.ts:771(thesecurity-anchor-high-privilegerule) — reported, re-verify the spelling at the fix.git grep -n -E 'declaredCapabilities|AnchorBindingContext' origin/main -- packages/plugins/plugin-security/src packages/lint/src(tests excluded) → 0; control: the predicate file carriesdeclaredCapabilities3 times.domain:services48,domain:spec99,domain:devx100,security19 open cards read by title+body fordeclaredCapabilities/AnchorBindingContext/describeHighPrivilegeBits→ 0 hits (2026-09-16T21:11Z).⇒ Today a permission set with
isDefault: truethat grants an app token the stack DECLARED undercapabilities:is still refused at boot (warning, no binding) and by lint (error) — the exact shape #17189 was filed on (hotclm#11), now declared-≠-enforced: the ADR and the spec say it binds, the consumers say it does not.What is asked
Wire the declared list into the consumers in the ruled order — the boot refusal and the lint rule pass
{ declaredCapabilities }read from the stack'scapabilities:declarations (boot: thesys_capabilityrows withmanaged_by: 'package'; lint: the stack's declaration list), with the platform floor unchanged — and pin it: a declared app token on theisDefaultset binds and lints clean, an undeclared name and a platform capability still refuse. The consumer for hotclm's unlock is release-installable, per #17189's own criterion.Downstream
isDefault→everyonebinding rule (after #17189) #17359 / PR docs(skills): teach the isDefault everyone baseline and its app-capability rule in objectstack-data security.md #18531 (the publishedskills/**guidance that says the declared token may ride on the default set) is parkedpm:blockedon this card: 「文档应该以实际实现为准」.capabilitywithscope: 'org'counts as a high-privilege bit, so a set carrying only app capability tokens cannot bind to theeveryoneanchor #17189's consumer hotclm#11 keeps its seven-per-position workaround until this lands AND ships.查重词
describeHighPrivilegeBits·declaredCapabilities·AnchorBindingContext·bindBaselineToEveryone·security-anchor-high-privilegeGenerated by Claude Code