Skip to content

skills: evaluate whether the published security/platform guidance must teach the app-capability vs system-permission distinction and the isDefault → everyone binding rule (after #17189) #17359

Description

@os-litant

Filed by the director seat (summon #21, session_01QVMnxyWBx8cAQMsV6akDV9) on the maintainer's instruction, verbatim and untranslated: 「17189 同意,但是同时评估是否需要改进skills」 (director chat, 2026-09-10T08:4xZ, replying to decision batch #110 item 1). Routed domain:skills under the maintainer direct-dispatch channel (the instruction names the work explicitly); pm:queue.

The question

After #17189 lands (ruling (i): an app-declared capability token is not a system permission for the everyone-anchor high-privilege check; ADR-0090 D5 amended), does any published skill under skills/** need to change so that an AI author writing a metadata app does not reproduce the shape hotclm hit?

Measured on origin/main 47863f4 (2026-09-10T08:3xZ)

git grep -n -iE 'isDefault|systemPermissions|capabilit|everyone|permission set' origin/main -- 'skills/**':

  • skills/objectstack-data/rules/security.md teaches definePermissionSet, the permissions: stack key, requiredPermissions as an ADR-0066 D3 AND-gate, and the platform-exclusive capabilities (manage_metadata, manage_platform_settings, …).
  • skills/objectstack-platform/SKILL.md teaches the capabilities stack key as a demand for a platform provider (the 28 PLATFORM_CAPABILITY_TOKENS) and requires:.
  • Zero hits for: isDefault: true on a permission set (the ADR-0090 D5 everyone auto-binding), the high-privilege refusal and what trips it, an app-declared capability token (ADR-0066 D1, scope: 'org') as distinct from a platform token, or the pattern "one default set that every employee holds, carrying the app's own navigation tokens". The only isDefault in the corpus is a list-view example.

⇒ Today the published guidance can teach an author to declare app capabilities (D1) and to gate navigation on them, and separately to write permission sets, but it says nothing about the one combination that failed in the field: the default set that carries app tokens. Whether that is a gap worth text, and where it lands (security.md vs platform SKILL.md), is this card's assessment.

Deliverable

  1. An assessment on this card: which skill file(s), which sentences, and whether a negative example (hotclm#11's shape: seven per-position bindings as a workaround) belongs in the text. If the answer is "no change needed", say why with the grep above as the control.
  2. If text is needed: the change lands after An app-declared capability with scope: 'org' counts as a high-privilege bit, so a set carrying only app capability tokens cannot bind to the everyone anchor #17189's fix merges, so it teaches the post-fix semantics (until then this card's deliverable is the assessment only). skills/** is a governed surface: contract-review tier build (skills seat), draft PR, ## 维护者速读(草稿) in the body, human merge; the dispatch carries a net-line budget.

Dedup

Open domain:skills cards read by title on 2026-09-10T08:3xZ (17): none about capability tokens, the everyone anchor, or permission-set defaults. Refs: #17189 (the fix and its ruling), hotclm#11, ADR-0090 D5/D9, ADR-0066 D1.


Generated by Claude Code

Activity

  1. added
    pm:queueReady for the PM dispatch loop
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 10, 2026
  2. self-assigned this
    on Sep 10, 2026
  3. os-litant commented on Sep 10, 2026

    @os-litant
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01YKEjmbYNvYWJvWGSWx26zK (GitHub os-litant, skills seat), claimed at 2026-09-10T09:03Z
    Branch: claude/issue-17359-skills-capability-guidance
    Worktree: objectstack-issue-17359
    Domain: domain:skills
    File surface: skills/objectstack-data/rules/security.md, skills/objectstack-platform/SKILL.md — READ-ONLY in this dispatch: deliverable 1 (the assessment on this card); ⛔ no edit to skills/** until #17189's fix merges (the card's own condition) (stop on breach; explain in the report)
    Container & model: M (a judgment card — the deliverable decides what a published skills/** surface will say; not mechanical), mode:subagent, model: claude-fable-5-1 — node scripts/pm/dispatch-gates.mjs --tier skills/objectstack-data/rules/security.md skills/objectstack-platform/SKILL.md at 706ad0f prints 「Model tier — MANDATORY: claude-fable-5-1 … 'skills/**' — clause ① (2026-09-10 ruling, verbatim 「必须 fable的还包括对外发布的skills」) … no one-line exemption applies under this root」; passed explicitly as the dispatch's model parameter.
    Clause-②: no — an assessment; no accept set or public surface moves (any later text is guidance on an already-ruled contract, #17189 (i)).
    Thread-read: none (0 comments on the card at claim time; body read in full; #17189's four comments incl. the ruling 5615806616 read).
    Serial constraints cleared: no open PR touches the two files and no other claim on this lane names them (git ls-remote at claim: the lane's only branch was the merged #17302's, deleted); action face git log -8 origin/main -- <the two files> newest b110578 (same day — the dev works from current origin/main e669e5e); #17189 has no PR (closed_by_pull_requests 0; spec seat vacant) ⇒ the text half stays blocked on it; H17 hold index names neither file; verify-lock free (--status: lock is free, queue empty).


    Generated by Claude Code

  4. added theissue type on Sep 10, 2026
  5. os-litant commented on Sep 10, 2026

    @os-litant
    ContributorAuthor

    Dispatched — R1, 2026-09-10T09:09Z, mode:subagent, build tier claude-fable-5-1 passed explicitly (clause ①: published skills/** is the surface under assessment). Claim 5616017852 is the dev's identity; branch claude/issue-17359-skills-capability-guidance. Scope of this dispatch = deliverable 1 only (the assessment comment; pr: null); ⛔ no edit to skills/** until #17189's fix merges. Disjoint from #17164 (objectos CLAUDE.md) and #17346 (check-clause2-carriers.mjs C4 + contract-review.md :35–:37). Patrol timer trig_012AMK9J7RnbBAeY1WNEtrLA fires 09:49Z.


    Generated by Claude Code

  6. os-litant commented on Sep 10, 2026

    @os-litant
    ContributorAuthor

    Assessment

    CHANGE NEEDED

    One 3-line construct in skills/objectstack-data/rules/security.md; skills/objectstack-platform/SKILL.md unchanged. The text lands only after #17189's fix merges, because it teaches ruling (i)'s semantics, not the pre-fix refusal.

    Ruling assessed against (#17189 comment 5615806616, verbatim): 「describeHighPrivilegeBits 多收一个输入——本 stack 声明过的应用能力名单——名单内的名字不计为系统权限;启动侧拒绝与 lint 规则同笔跟随;ADR-0090 D5 的 offending 清单相应收窄为「平台系统权限;带 package provenance 的应用声明 capability 令牌不计」,ADR 修订走独立受管 PR」. Maintainer's instruction for this card, verbatim: 「17189 同意,但是同时评估是否需要改进skills」.

    Control

    Tip read: origin/main = e669e5e (e669e5eee296410731c8a00cba366369f005bc96), read 2026-09-10T09:1xZ. The two candidate files last moved at b110578 (same day); both read at tip, in full for security.md (210 lines) and by section for the platform file.

    git grep -n -iE 'isDefault|systemPermissions|capabilit|everyone|permission set' origin/main -- 'skills/**' → 83 hits in 19 files: objectstack-data/references/data-hooks.md 23 · objectstack-platform/SKILL.md 14 · objectstack-data/SKILL.md 10 · objectstack-data/rules/security.md 9 · objectstack-ai/SKILL.md 4 · objectstack-upgrade/SKILL.md 3 · objectstack-ui/rules/pages.md 3 · objectstack-data/references/_index.md 3 · objectstack-ui/rules/navigation.md 2 · objectstack-platform/references/_index.md 2 · objectstack-automation/SKILL.md 2 · one each in objectstack-ui/rules/list-views.md, objectstack-ui/rules/actions.md, objectstack-ui/references/_index.md, objectstack-ui/SKILL.md, objectstack-formula/SKILL.md, objectstack-data/rules/indexing.md, objectstack-data/evals/README.md, skills/README.md.

    • isDefault: exactly one hit, skills/objectstack-ui/rules/list-views.md:122 (a list-view example).
    • everyone: skills/objectstack-data/SKILL.md:78-79 (sharing-model table) and skills/objectstack-formula/SKILL.md:409 only.
    • systemPermissions / system_permissions: zero. defineCapability / scope: 'org': zero (second grep, exit 1).
    • capabilities in skills/objectstack-platform/SKILL.md: the top-level key list at :76 (name only) and the requires: section :435-482, which teaches the 28 PLATFORM_CAPABILITY_TOKENS (kernel/platform-capabilities.ts) — a different registry from the capabilities: stack key (security/capabilities.ts, ADR-0066 D1).

    Positive control git grep -c definePermissionSet origin/main -- 'skills/**' → skills/objectstack-api/SKILL.md:1, skills/objectstack-data/rules/security.md:4 — identical to the PM's reading at e669e5e.

    Zone-2 assumptions: A holds (as above). B holds and is wider than the card's one combination: the published skills teach neither the DEFINE key (capabilities: / defineCapability) nor the GRANT key (systemPermissions); security.md:145's own requiredPermissions: ['view_pii'] names an app token that no skill shows declared or granted anywhere (view_pii is not among the 9 curated PLATFORM_CAPABILITIES). C is falsified in one half — see Reader.

    Reader

    The reader is an AI author writing a metadata app's permissions (and capabilities) into the post-(i) world. Under (i) a systemPermissions name is an app token only when it carries package provenance, i.e. when the stack declares it under capabilities: (boot side: the sys_capability row is managed_by:'package'; lint side: the stack's declaration list). The back-compat implicit derivation that ADR-0066 D1 keeps alive seeds an undeclared name as managed_by:'platform' with no package provenance (packages/plugins/plugin-security/src/bootstrap-declared-capabilities.ts :9-11, :230). So after the fix:

    • a declared app token on the isDefault: true set binds to everyone with no warning — hotclm's intended shape works;
    • an undeclared app token on that set still reads as 'system permissions': security-anchor-high-privilege (error) and the boot refusal are unchanged, and the lint's fix-it hint (packages/lint/src/validate-security-posture.ts :781-783, "Split the powerful bits into a separate set granted through ordinary positions") walks the author into exactly hotclm#11's seven-per-position workaround instead of the declaration;
    • a platform capability (manage_users, setup.access, … — the 9 curated names) or VAMA / delete / transfer / export on that set is refused, loudly, with the bit named.

    Value gate:

    ① Which decision the text changes: whether to declare the token under capabilities: before granting it via systemPermissions on the isDefault: true set. Shape produced today without the text: the skills name none of the three keys, so an author reaches systemPermissions from the schema alone (its .describe() is "System level capabilities") and writes the undeclared grant — the shape the skill's own view_pii example models. That shape still fails after the fix, and its diagnostic steers into the workaround. The plain "app tokens may ride on the default set" sentence (Zone 2 C) changes no decision post-fix — that shape simply works — so it is not what is written.

    ② Deletion or rewrite instead of addition: no. No existing sentence in either file names isDefault, systemPermissions or capabilities:, so there is nothing to rewrite; the only candidate neighbour (security.md:135-139, requiredPermissions, the REQUIRE side) is correct as written, and folding DEFINE/GRANT into it would be re-wrap paying for new content, which is not a currency.

    ③ Construct over prose: yes — one bullet in the permission-set key list naming the three keys, the anchor, and the two things refused there.

    Real-usage reading (axis ①, measured at e669e5e): examples/app-showcase declares two capabilities (showcase.export_data, showcase.restricted_ops, src/security/capabilities.ts :52, :77) and grants one on OpsPermissionSet (permission-sets.ts :220); its isDefault set showcase_member_default (:295-346) deliberately carries no systemPermissions. The DEFINE → GRANT → REQUIRE chain is taught only in that example's code comments (capabilities.ts :15-20), in no published skill. No other example carries the combination; the named consumer that does is hotclm (external, read through #17189's quotation — hotclm#11 itself answered 403 on both the API and the page from this seat).

    Four axes: business need — a named consumer hit the combination, and the post-fix failure mode is the undeclared variant an author reaches first from the schema; long-run — the rule is the permanent post-(i) contract ("declaration is what makes a token an app token"), not the pre-fix refusal, so it is not transitional; AI error — the construct closes the one silent-until-lint path; the contract-tightening alternative (retire the implicit derivation so an undeclared name is refused at defineStack) is a spec-lane decision outside this card and would not remove the need to name the three keys; startup focus — +3 lines, one file, no new section.

    Proposal

    skills/objectstack-data/rules/security.md — insert one bullet after line 33, inside the existing key list of "## Object-level permissions (RBAC)". Neighbours, verbatim at e669e5e:

    31: - Bits: `allowCreate` / `allowRead` / `allowEdit` / `allowDelete`, plus
    32:   `allowTransfer` (ownership change), `viewAllRecords` / `modifyAllRecords`
    33:   (super-user, bypass sharing).
    34: - Source: `node_modules/@objectstack/spec/src/security/permission.zod.ts`
    

    Proposed bullet (becomes lines 34-36; widths 81 / 82 / 90 — the file's longest existing lines are 93):

    - **`isDefault: true` = the `everyone` baseline (ADR-0090 D5).** It may carry app
      capabilities declared under `capabilities:` (`defineCapability`) and granted via
      `systemPermissions`; a platform capability or undeclared name there fails lint and boot.
    

    Net: +3 lines in security.md. It names the anchor key, the anchor, the DEFINE and GRANT keys, and the two things that may not ride: a platform capability and an undeclared name. VAMA / delete / transfer / export are not restated — they are the "super-user" bits named two lines above, and the lint names them precisely when they occur.

    skills/objectstack-platform/SKILL.md — no change (0 lines). Its "capability" vocabulary is the requires: service-plugin tokens; teaching app-declared capabilities there would put two registries under one word in one file. capabilities stays a listed key at :76 whose semantics live beside the GRANT key in security.md.

    Total net across both files: +3 — within budget.

    Negative example (hotclm#11's seven per-position bindings): not included. It is a pre-fix workaround, so text describing it is transitional (不渐进); an author following the construct never reaches it; it costs lines the budget does not have; and the one thing that steers a post-fix author toward it is the lint hint for the undeclared-name case, which lives in #17189's declared file surface (packages/lint/src/validate-security-posture*), not in a skill.

    Wording dependency on #17189's landing: the bullet is correct under ruling (i) as recorded. If the fix PR also retires the implicit derivation (undeclared names refused at authoring), the words "or undeclared name" become redundant with the contract and should be dropped at landing; the other two lines stand either way. Two pre-fix sentences outside skills/** that the fix PR should move in the same diff are listed in the dev report below (content/docs/permissions/permission-sets.mdx :223-225, examples/app-showcase/src/security/permission-sets.ts :290-291).

    Blocked-by

    Blocked-by: #17189


    Generated by Claude Code

  7. os-litant commented on Sep 10, 2026

    @os-litant
    ContributorAuthor

    os-dev-report

    {
      "issue": 17359,
      "status": "done",
      "branch": "claude/issue-17359-skills-capability-guidance",
      "pr": null,
      "premise_still_valid": true,
      "summary": "Assessment delivered as comment 5616225081 on #17359 (deliverable 1 only): verdict CHANGE NEEDED — one 3-line bullet in skills/objectstack-data/rules/security.md after line 33, skills/objectstack-platform/SKILL.md unchanged, negative example not included, Blocked-by: #17189. Zone-2 A and B hold (B is wider: the skills teach neither `capabilities:`/`defineCapability` nor `systemPermissions`); C is falsified in one half — under ruling (i) an UNDECLARED app token on the `isDefault` set still counts as a system permission (derived placeholders are managed_by 'platform', no package provenance), so the residual post-fix trap is two-directional and the construct names the declaration route. No file under skills/** edited; identity branch pushed empty; no PR by design.",
      "tests": "No code change; no test or build run. Control grep re-run at origin/main e669e5e: 83 hits / 19 files; isDefault only at skills/objectstack-ui/rules/list-views.md:122; everyone only at objectstack-data/SKILL.md:78-79 and objectstack-formula/SKILL.md:409; systemPermissions | defineCapability | scope: 'org' zero hits (exit 1). Positive control definePermissionSet: objectstack-api/SKILL.md:1, objectstack-data/rules/security.md:4. Decision-frame md5 22f2339f0acb64cdb50c7adc9db681c3 verified at e669e5e. Candidate bullet measured: 3 lines, widths 81/82/90 vs file max 93. dispatch-gates.mjs --commands on the branch: exit 2, 'this branch changes nothing against origin/main (merge base e669e5eee) — nothing to derive'.",
      "gates": [],
      "gates_reason": "empty diff — dispatch-gates.mjs derived nothing (exit 2, quoted in tests); verify lock not taken",
      "line_budget": { "skills/objectstack-data/rules/security.md": "+3 (proposed, not applied)", "skills/objectstack-platform/SKILL.md": "no edit", "total": "+3 of +3" },
      "files_changed": [],
      "deviations": [
        "no pnpm install in the worktree: assessment only — zero edits, zero gates to run",
        "hotclm#11 not read directly (REST 403 and page 403 from this seat); read through #17189's body quotation; add_repo read-attach answered git-only and was not used",
        "channel: every GitHub read and both writes went through repo-scoped REST (probe 200), GitHub MCP unused",
        "assessment comment read back: all section markers 1x, byte count equal (10027/10027); the only difference from the sent body is the footer block, which the platform re-laid (one rule line, one footer)"
      ],
      "mcp_calls": "0 — GitHub MCP unused; one Claude_Code_Remote add_repo call (not GitHub MCP)",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: published skills teach neither the DEFINE key (`capabilities:`/`defineCapability`) nor the GRANT key (`systemPermissions`); security.md:145 `view_pii` is an app token no skill shows declared or granted — 承接者: skills seat (the wider gap the card's combination sits inside)",
        "noted, not filed: packages/lint/src/validate-security-posture.ts:781-783 fix-it hint steers an undeclared-app-token author into the per-position workaround post-fix — a warning pointing at metadata the runtime honours but makes worse (boundary, not class c) — 承接者: #17189's implementing PR (file in its declared surface)",
        "noted, not filed: content/docs/permissions/permission-sets.mdx:223-225 lists 'system permissions' among anchor-forbidden bits and says 'nothing auto-binds', while PermissionSetSchema.isDefault .describe() says app-level sets are auto-bound at boot — pre-fix wording in a hand-written docs tree — 承接者: #17189's implementing PR",
        "noted, not filed: examples/app-showcase/src/security/permission-sets.ts:290-291 comment 'the D7 lint hard-blocks ... system permissions' — pre-fix wording — 承接者: #17189's implementing PR",
        "noted, not filed: the word 'capability' names two registries in skills/objectstack-platform/SKILL.md (`requires:` tokens vs the `capabilities:` key); a string array under `capabilities:` is refused loudly by the strict CapabilityDeclarationSchema, no failing probe — 承接者: skills seat"
      ]
    }

    Generated by Claude Code

  8. os-litant commented on Sep 10, 2026

    @os-litant
    ContributorAuthor

    ACCEPT (deliverable 1 — the assessment, comment 5616225081) — reviewed in-seat at the contract-review tier (skills seat, session session_01YKEjmbYNvYWJvWGSWx26zK, 2026-09-10T09:25Z).

    • Implemented-by: os-dev subagent on branch claude/issue-17359-skills-capability-guidance (claim 5616017852; build tier claude-fable-5-1 passed explicitly; mode:subagent). Reviewed-by: session_01YKEjmbYNvYWJvWGSWx26zK (the skills seat) — independence pair holds.
    • Checklist: no PR by design (pr: null, status: done, files_changed empty, gates: [] with the reason quoted from dispatch-gates.mjs — exit 2 on an empty diff); the identity branch sits at e669e5e with no commits; worktree removed; report shape correct; open_questions empty; report read back on the card (5616244069).
    • Spot-checked on origin/main (143c715 at 09:2xZ; the two skill files unchanged since b110578): security.md :31–:34 neighbours verbatim as quoted, 210 lines, widest line 93; packages/spec/src/security/capabilities.ts :86–:102 (a declaration carries managed_by:'package' + package_id; the implicit derivation still runs for back-compat); packages/plugins/plugin-security/src/bootstrap-declared-capabilities.ts :9–:11 and :230 (an undeclared name falls back to the derived placeholder with no package provenance); packages/lint/src/validate-security-posture.ts :778–:784 (the fix-it hint steers to the per-position split); security.md :145 requiredPermissions: ['view_pii']. The control grep at e669e5e matches this seat's own reading at 706ad0f.
    • Verdict accepted: CHANGE NEEDED — one +3-line bullet in skills/objectstack-data/rules/security.md after :33, skills/objectstack-platform/SKILL.md unchanged, no negative example; within the +3 budget. The value-gate reading carries the decision: under ruling (i) a DECLARED app token on the isDefault: true set binds to everyone, an UNDECLARED one still reads as a system permission, and no published skill names any of the three keys — so the text changes the author's decision to declare before granting. Zone-2 C half-falsified by the dev; accepted.
    • One wording correction carried into the text dispatch, ⛔ not a rework of the assessment: the bullet's 「fails lint and boot」 overstates the boot side — boot REFUSES THE BINDING with a warning (bindBaselineToEveryone), it does not fail; the landed sentence must say "is refused by lint and at boot" or equivalent. The dependency the dev names stands: if An app-declared capability with scope: 'org' counts as a high-privilege bit, so a set carrying only app capability tokens cannot bind to the everyone anchor #17189's PR also retires the implicit derivation, drop "or undeclared name" at landing.
    • Out-of-scope items (five noted, not filed; three-class test applied): none is class (a)/(b)/(c) — an undeclared-token grant still resolves (back-compat), so nothing is refused or dropped; the lint-hint item is the recorded boundary (a warning steering to worse metadata). Items 2–4 (the lint hint :778–:784; content/docs/permissions/permission-sets.mdx :223–:225; examples/app-showcase/src/security/permission-sets.ts :290–:291) are relayed to An app-declared capability with scope: 'org' counts as a high-privilege bit, so a set carrying only app capability tokens cannot bind to the everyone anchor #17189 for its implementing dev (the record stays 5616225081). Items 1 and 5 (DEFINE/GRANT keys untaught anywhere; the two "capability" registries in the platform skill) are this seat's — folded into the text dispatch's reading, ⛔ not into its budget.
    • State: pm:dispatched → pm:blocked; Blocked-by: #17189 appended to the body (the fix has no PR yet; the spec seat is vacant). Release: session session_01YKEjmbYNvYWJvWGSWx26zK; reason = deliverable 1 done, deliverable 2 waits on An app-declared capability with scope: 'org' counts as a high-privilege bit, so a set carrying only app capability tokens cannot bind to the everyone anchor #17189's fix merging; destination = pm:blocked, back to pm:queue by the unlock scan when An app-declared capability with scope: 'org' counts as a high-privilege bit, so a set carrying only app capability tokens cannot bind to the everyone anchor #17189 closes. Assignee cleared in the same act.
    • Re-dispatch shape (pre-written for the unlock): one dev at the contract-review tier (published skills/**), budget +3 lines in security.md only, the bullet from 5616225081 with the boot-wording correction above and the "undeclared" clause re-checked against the merged fix; governed ⇒ draft PR + 速读草稿, skills-seat review at tier, human merge.

    Generated by Claude Code

  9. added
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Sep 10, 2026
  10. removed their assignment
    on Sep 10, 2026
  11. os-justin commented on Sep 16, 2026

    @os-justin
    Collaborator

    pm:blocked → pm:queue — unlock scan, skills seat, session_01Gqi43smmqjJ5sUrhfoPeKu, 2026-09-16T20:44Z.

    Double-check on the last transition (5616301504, 2026-09-10T09:25Z: 「back to pm:queue by the unlock scan when #17189 closes」): ① #17189 is closed completed (2026-09-15T15:05Z, director exit 5682637828) — its fix PR #17811 merged 2026-09-14T04:19Z (d5c91dd6, files: packages/spec/src/security/high-privilege.ts + test + api-surface + changeset) after the ADR PR #17814 (2026-09-13T15:12Z, docs/adr/0090-…); ② no PR references this card (closed_by_pull_requests 0) ⇒ nothing newer to refuse on. Re-verified on origin/main 2496415: skills/objectstack-data/rules/security.md is untouched since the assessment (last touch 6a3bcd8, 211 lines; the :31–:34 neighbours read as quoted in 5616225081); bootstrap-declared-capabilities.ts's docblock still describes the implicit systemPermissions placeholder derivation (managed_by:'platform', claimed by an explicit declaration) ⇒ the 「or undeclared name」 clause of the proposed bullet is still live post-fix, subject to the dispatch's re-read of the merged predicate in high-privilege.ts. Blocked-by: #17189 removed from the body in the same act; the pre-written re-dispatch shape (5616301504) is executed next: one dev at the contract-review tier, +3 lines in security.md only, boot wording 「refused by lint and at boot」.


    Generated by Claude Code

  12. 8 remaining items

  13. added
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Sep 16, 2026
  14. os-justin commented on Sep 17, 2026

    @os-justin
    Collaborator

    Ruling recorded — the security.md token ceiling is raised to 2543. Skills seat, session_01Gqi43smmqjJ5sUrhfoPeKu, 2026-09-17T07:15Z. Maintainer, verbatim, in this seat's chat: 「security.md 允许增加到 2543」 — answering the 需裁 item put in the round report (park record 5704584550 on this card, park note 5704585750 on PR #18531: skills/objectstack-data/rules/security.md reads 2543 tokens on head 4ea43892, ceiling 2480, over by 63; recommendation A = raise).

    What this discharges: release condition ② of the park. The raise lands in PR #18531 itself: the ratchet row ['skills/objectstack-data/rules/security.md', 2480] in scripts/check-skills-token-ratchet.mjs becomes 2543 with this ruling quoted beside it, and the PR body quotes it — the ratchet's own rule (「the other direction lands only in a PR whose body quotes a maintainer ruling authorizing it」).

    What it does not discharge: release condition ① — #18535 (the declared app capability token is still refused at the everyone anchor because describeHighPrivilegeBits's consumers pass no declaredCapabilities), which the three lines describe as already true. #18535 is ownerless (bare finding, no lane, no assignee, 0 comments since filing); per SKILL.md 「阻塞项无主 ⇒ 被挡席认领做掉」 this seat claims and dispatches it next; PR #18531's single patch round (merge origin/main, the ceiling raise quoting this ruling, skills/** gates re-run) follows #18535's landing, then the four-piece.


    Generated by Claude Code

  15. os-justin commented on Sep 17, 2026

    @os-justin
    Collaborator

    Unparked — release condition ① discharged; the single patch round is dispatched. Skills seat, session_01Gqi43smmqjJ5sUrhfoPeKu, 2026-09-17T09:01Z. #18535 landed on origin/main as 21b7c12b4 at 2026-09-17T09:00:08Z (landing record 5711759365): the four consumers of the anchor predicate now pass the stack's declared capabilities, so the three lines PR #18531 adds to skills/objectstack-data/rules/security.md describe landed behaviour (「文档应该以实际实现为准」). Condition ② was ruled at 5710537499 (「security.md 允许增加到 2543」). Same act: pm:blocked → pm:dispatched (assignee unchanged), the Blocked-by: / Unlock-action: lines dropped from the body.

    Claim continues — patch round (the seat's re-dispatch on the same branch; round 2 of the original claim)
    Session: session_01Gqi43smmqjJ5sUrhfoPeKu
    Branch: claude/issue-17359-skills-capability-guidance (PR #18531, head 4ea43892 before the round)
    Worktree: objectstack-issue-17359
    Domain: domain:skills
    Seat: domain:skills#1
    File surface: skills/objectstack-data/rules/security.md (the three accepted lines, unchanged unless the merge of origin/main requires re-anchoring; re-count) · scripts/check-skills-token-ratchet.mjs (row :424 on 21b7c12b4, ['skills/objectstack-data/rules/security.md', 2480] → 2543 with the ruling quoted verbatim beside it, in the file's own raise-ritual form) · the PR body quotes the ruling (the ratchet's rule for a raise) (stop on breach; explain in the report). ⛔ No other skill file, ⛔ no other ceiling.
    Container & model: S(合 main + 抬上限引裁定), mode:subagent, model: claude-fable-5-1 — node scripts/pm/dispatch-gates.mjs --tier --repo objectstack-ai/objectstack skills/objectstack-data/rules/security.md scripts/check-skills-token-ratchet.mjs at 2026-09-17T09:01Z on the fast-forwarded tree: 「Model tier — MANDATORY: claude-fable-5-1」 (published skills/**); no downgrade exit taken
    Clause-②: no
    Thread-read: 5710537499
    Serial constraints cleared: security.md hot-file — no other open PR touches it (this seat's own PR #18531 is the carrier); the branch merges origin/main cleanly (git merge-tree at 2026-09-17T08:43Z: no conflict, 35 commits behind); os-verify-lock.sh --status at 2026-09-17T09:01Z: free; shared checkout fast-forwarded to origin/main 21b7c12b4.
    Ruling-ref: 5710537499


    Generated by Claude Code

  16. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Sep 17, 2026
  17. os-justin commented on Sep 17, 2026

    @os-justin
    Collaborator

    os-dev-report

    {
      "issue": 17359,
      "status": "done",
      "branch": "claude/issue-17359-skills-capability-guidance",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/18531",
      "head": "dfe355143c2e8debd21e886aa30c594d26e3be6e",
      "merge_commit": "68e1b07e18742a169ed93208d8d5c38c5b815628 — git merge --no-ff origin/main (21b7c12b4) into the branch; no rebase, no force-push, no new PR; clean (merge-tree exit 0, 37 commits behind); no os-regen-pending",
      "files": [
        "scripts/check-skills-token-ratchet.mjs (+10/−1: CEILINGS row 2480 → 2543 with the ruling quoted verbatim beside it, in the file's own raise-ritual form)",
        "skills/objectstack-data/rules/security.md (+3/−0 vs origin/main; byte-identical to 4ea43892 — no clause corrected)"
      ],
      "session": "session_01Gqi43smmqjJ5sUrhfoPeKu",
      "premise_still_valid": true,
      "summary": "Patch round on PR #18531 (draft, still draft). Merged origin/main 21b7c12b4 as merge commit 68e1b07e1 (#18535 landed, so the three security.md lines now describe landed boot and lint behaviour; re-read against declared-capability-context.ts, the boot bind in security-plugin.ts and the lint rule in validate-security-posture.ts — every clause true, none corrected). Re-counted security.md after the merge: 2543 tokens, not above the ruling, so the ratchet row was raised 2480 → 2543 (commit dfe355143) with the maintainer ruling 「security.md 允许增加到 2543」 (2026-09-17, record 5710537499) quoted verbatim beside the row and in the PR body's appended 'Patch round' section; the 速读 draft's 改了什么/风险/你要做的 carry a dated update; a status line marks the body's original Blocked-by paragraph as discharged. 40 derived gates all exit 0 (the previously expected-red ratchet now green); GOVERNED — landing stays the maintainer's. Assignee untouched (os-justin, set by the dispatch).",
      "measurements": {
        "tokens_security_md": "convention ceil(utf8 bytes / 4): origin/main 21b7c12b4 = 9913 bytes → 2479 (main did not touch the file); branch head before the round 4ea43892 = 10170 bytes → 2543; after the merge (68e1b07e1 and head dfe355143) = 10170 bytes → 2543 — not more than 2543, so the raise equals the ruling",
        "ratchet_row": "before: ['skills/objectstack-data/rules/security.md', 2480] (line 424 on 21b7c12b4); after: ['skills/objectstack-data/rules/security.md', 2543] (line 433 on dfe355143); comment beside it ends: Maintainer ruling 2026-09-17 (recorded on #17359 as comment 5710537499), verbatim and untranslated: 「security.md 允许增加到 2543」; +63 tokens, zero headroom, ceiling +63; no other row moved",
        "three_lines_reread": "clause 1 (isDefault: true = the everyone baseline, ADR-0090 D5): still true — packages/spec/src/security/permission.zod.ts:682 describe('[ADR-0090 D5] App baseline for the everyone position …'), ADR-0090 D5 at docs/adr/0090-…:46. clause 2 (may carry app capabilities declared under capabilities: (defineCapability) and granted via systemPermissions): now true at boot and in lint, protocol-only before #18535 — packages/plugins/plugin-security/src/declared-capability-context.ts readDeclaredCapabilityContext reads the stack's capabilities: declarations; security-plugin.ts:3592–3595 describeHighPrivilegeBits(boot, anchorContext); engine write gate :5503–5508; suggested-audience-bindings.ts:968–972; packages/lint/src/validate-security-posture.ts:439–443 builds anchorContext from stack.capabilities, :795 passes it. clause 3 (lint and boot refuse a platform capability or undeclared name there): still true — high-privilege.ts:70–74 platform floor (PLATFORM_CAPABILITY_NAMES never excused), :134 「Omission refuses」 (a token absent from declaredCapabilities stays offending); lint emits security-anchor-high-privilege at severity error (:795–808); boot logs '[security] refusing to bind fallback set to everyone — high-privilege bits' and skips the binding (:3595–3600). No clause corrected.",
        "line_readings": "security.md 211 → 214 lines (+3), widest line 93; package (10 SKILL.md + objectstack-data rules/references, 20 files) 8959 → 8962",
        "governed": "node scripts/pm/check-governed-merges.mjs --test security.md check-skills-token-ratchet.mjs → exit 3 「GOVERNED — a human merge is the review record for this PR」 (1 of 2 paths; skills/** rules layer)",
        "labels": "read back after the round: documentation, size/s, skip-changeset — no label written this round; skip-changeset still holds (repo-root gate script in the private root package; skills/** ships in no files[])",
        "pr_body": "PATCH /pulls/18531 → 200; read back: 'Patch round' section, the verbatim ruling, the status line, the 速读 update and the 40-line gate list all present; stored 20496 bytes = sent 20438 + 58 (the platform appended one bare footer beside the kept session-URL footer — the recorded REST-PATCH reading); draft unchanged true; 0 less-than characters; closing keyword only Fixes #17359"
      },
      "tests": "Gates on dfe355143 in worktree objectstack-issue-17359: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 40 (change set 2 paths vs merge base 21b7c12b4); all 40 run with redirect-then-$? capture; --ran reconcile 「40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN」 exit 0; all 40 exit 0. Named: node scripts/check-skills-token-ratchet.mjs → 「✓ check-skills-token-ratchet: skills/objectstack-data/rules/security.md is 2543 tokens (ceiling 2543; headroom 0).」 and 「34 authored bundle file(s) within their ceilings; 10 generator-owned file(s) measured, not ratcheted.」; --self-test 「65 cases pass」; pnpm check:ratchet-remedy-authority OK (255 scripts swept; 15 mark the expanding remedy ⛔ MAINTAINER-ONLY — unchanged); pnpm check:skill-frame-sync ✓ (14 self-test cases; frame coherent); check:skill-compatibility, check:skill-identifier-liveness, check:role-word, check:doc-authoring, check:corpus-claim-drift, check:nul-bytes, check:pm-governed-merges, check:pm-dispatch-gates (626 s, completed in the background after the foreground cap, exit 0 from the runner's own redirect), check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:watch-hint-literal and the rest → exit 0; pnpm --filter @objectstack/lint run check:doc-formula-expressions → exit 0 after building '@objectstack/lint...' under scripts/pm/os-verify-lock.sh (「VERDICT command-exit 0 · held the lock 136s · waited 0s」). Ablation from the committed head (trap-restored, absolute paths, no dist involved — the gate reads its own source): row reverted to 2480 on disk (grep counts 2480-row 1 / 2543-row 0) → gate exit 1 「✗ … is 2543 tokens; the ratchet ceiling is 2480 (over by 63) … ⛔ MAINTAINER-ONLY」; restored with git checkout HEAD -- path: git hash-object = HEAD blob 5b984866, git diff HEAD empty, git status --porcelain empty, gate exit 0 again. Control characters: grep -naP over both touched files → no match (exit 1). No ① dependency-closure build and no ② package test owed (no package touched); the artifact-roster / wide-population / pending-changeset families are CI's own. Pre-push hook: 「check:commit-card-trailers: … no card relation and no model identifier in the trailer pair」 on both pushes. Cleanup: node_modules deleted, git worktree remove exit 0 (no --force).",
      "mcp_calls": "0 — no MCP GitHub tool called; every GitHub read and write went through REST curl with GITHUB_TOKEN",
      "api_writes": "2 — PATCH /repos/objectstack-ai/objectstack/pulls/18531 (body), POST /repos/objectstack-ai/objectstack/issues/17359/comments (this report); plus 2 git pushes to the branch (68e1b07e1, dfe355143); no label write, no POST /pulls, no POST /issues, no assignee write",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed (承接者: 无): pnpm check:pm-dispatch-gates took 626 s on this shared box and overran the ~10-minute foreground cap (completed in the background, exit 0); platform-readings line 427 already records 430–450 s single-machine and prescribes detaching with tail --pid — the reading is low under contention, not wrong",
        "noted, not filed (承接者: the skills seat at the four-piece): the PR body's original top paragraph (Blocked-by #17189 step-②) is historical; a dated status line was inserted above it instead of rewriting it, so the original reasoning stays readable"
      ]
    }

    Generated by Claude Code

  18. os-justin commented on Sep 17, 2026

    @os-justin
    Collaborator

    ACCEPT (patch round) — in-seat contract-tier review of PR #18531 at head dfe355143 (report 5712105389) by the skills seat, 2026-09-17T09:31Z. Verified against GitHub and a scratch worktree at the head, ⛔ not against the report:

    • The construct is unchanged: skills/objectstack-data/rules/security.md on the head is byte-identical to the ACCEPTED head 4ea43892 (git diff empty) — the three lines after the RBAC Source: line (ACCEPT of the construct 5616301504, assessment 5616225081); +3 lines vs origin/main, 211 → 214. The seat re-read the three clauses against the landed 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 code (declared-capability-context.ts; security-plugin.ts boot bind and write gate; suggested-audience-bindings.ts; validate-security-posture.ts :439–:443 / :795) and high-privilege.ts (platform floor :70–:74, 「omission refuses」 :134): all three true on origin/main 21b7c12b4; none needed correction.
    • Merge: 68e1b07e1 merges origin/main 21b7c12b4 (no rebase, no force-push); merge base = origin/main; only the two intended files differ from main.
    • The ceiling raise is the ruling, in the ratchet's own form: scripts/check-skills-token-ratchet.mjs row ['skills/objectstack-data/rules/security.md', 2480] → 2543 with the raise comment quoting the maintainer verbatim and untranslated — 「security.md 允许增加到 2543」 (2026-09-17, record 5710537499) — and the PR body quoting it in its 「Patch round」 section; no other row moved. Measured on the head: 10170 bytes → 2543 tokens (ceil(utf8 bytes / 4)); check-skills-token-ratchet 「is 2543 tokens (ceiling 2543; headroom 0)」, --self-test 65 cases; check:skill-frame-sync 0; --pair 18531 → 0 (Clause-②: no). check-governed-merges --test → GOVERNED (skills/**, rules layer). The report's 40 derived gates all exit 0, re-derived here for the ratchet, the frame sync and the pair.
    • Dev's open questions: none. Out-of-scope notes (a 626 s check:pm-dispatch-gates under contention; the body's historical Blocked-by paragraph kept under a dated status line) — nothing to file.

    Rules layer (published skills/**) ⇒ the four-piece is hung on PR #18531 in the same act: 维护者速读(终稿), needs-user-decision, review requested from os-zhuang and hotlong. An authorized APPROVED lands it by ruling C (the CI head was still finishing one job at review time; the landing pre-check re-reads it); a human merge is equally the record.


    Generated by Claude Code

  19. os-justin commented on Sep 17, 2026

    @os-justin
    Collaborator

    Authorized approval received — ruling C: the seat lands it. Skills seat, session_01Gqi43smmqjJ5sUrhfoPeKu, 2026-09-17T09:37Z. Read on GitHub: PR #18531 (head dfe355143) carries review 5233769130 APPROVED by os-zhuang (in GOVERNED_APPROVERS) at 2026-09-17T09:37:20Z on the current head, and the same account flipped it ready at 2026-09-17T09:37:24Z. Landing pre-checks on this head: CI final 27 success / 15 rostered skips (check-expected-skips OK at 2026-09-17T09:34Z), --pair 18531 0, harness CURRENT (re-taken now), mergeable clean. Same act: needs-user-decision removed from the PR (the label leaves with the approval); the seat arms auto-merge SQUASH through the CCR route next unless the approver already enqueued it; the landing record follows merged_at.


    Generated by Claude Code

  20. os-justin commented on Sep 17, 2026

    @os-justin
    Collaborator

    Landing record — skills seat, session_01Gqi43smmqjJ5sUrhfoPeKu, 2026-09-17T09:54Z. PR #18531 (head dfe355143) MERGED through the merge queue at 2026-09-17T09:53:14Z (merged_at) as 7299b945a2fcdc649de1a59ac71a006c6f38ff9b — single parent d5e64d8d9 per git rev-list --parents (a squash); merged_by os-zhuang, the authorized approver who approved (5233769130), flipped ready and enqueued it by hand — ruling C completed by the approver's own act; the seat's part was the construct review (5616301504), the park and its discharge (5704584550 → 5711767613), the patch-round review (5712132917), the label strip (5712211637) and this record. Verified on origin/main by git at 2026-09-17T09:53:36Z: the squash is an ancestor; git log --oneline origin/main | grep -F '(#18531)' hits; skills/objectstack-data/rules/security.md carries the three lines (214 lines, 2543 tokens by ceil(utf8 bytes / 4)); the ratchet row reads ['skills/objectstack-data/rules/security.md', 2543] with the ruling 「security.md 允许增加到 2543」 quoted beside it; the queue ref is gone. Same act: pm:dispatched removed and the assignee cleared on this auto-closed card (Fixes #17359, completed); domain:skills stays. Downstream: #17189's rider is discharged (the published guidance now teaches the DECLARE/GRANT pair and the runtime + lint honour it since #18535); hotclm#11's workaround waits on the release that ships @objectstack/plugin-security / @objectstack/lint at minor.


    Generated by Claude Code

  21. removed their assignment
    on Sep 17, 2026
  22. added a commit that references this issue on Sep 28, 2026
    7299b94
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:skillsDomain lane — seat card indexed by label:pm:seat

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions