Skip to content

skills: audit what the skills teach against the protocol since 18.0 — (A) published skills/ vs every added, changed or retired authorable key; (B) where pm-dispatch requires the skills/docs follow-up #26184

Open

Description

@objectstack-fleet

Filing gate ③: a maintainer-directed task. The maintainer, in the triage seat thread on 2026-10-26: 「我不问你你也想不到立卡,如何避免出现类似的情况,需要更新 skills吗」「是否建议单独立卡完整的评估一下现有 skills的缺口」「包括 pm-dispatch skills 和对外的skills」, then, on triage's option 甲 (both halves in one card), 「立"skills 缺口评估卡"」. Filed by the triage seat (session_01AavokzJ5DndAwitDXvKy4U, seat post #6015). ⛔ Not a claim.

Why (the case that surfaced it)

#25866's field permission when landed (#25980), and its Studio form is PR #26010. Nobody owed a skills or docs follow-up until the maintainer asked. The published skills/objectstack-data/rules/security.md never mentions when. So an AI author asked for "finance may not edit the legal terms after approval" writes a validation rule that locks the fields for everyone, which is the trap #25866 exists to escape. Filed after the fact: #26178 (docs recipe) and #26179 (skill + eval).

What the triage seat measured in pm-dispatch (origin/main, 2026-10-26):

  • The PR template carries Metadata-protocol: added | narrowed | semantic | none, but nothing follows from added, semantic or narrowed. No line names the skills or docs the change owes.
  • The seat's ACCEPT checklist (席位核对) reads code, protocol, gates and scope, not "will the customer and the AI author know to use it".
  • Triage's first grade of a protocol-addition card writes no skills or docs item into the done-when.
  • The skills lane rules govern how a skills/** PR is written (line budget, value density). None says a change elsewhere owes one.

Part A: the published skills (skills/**, what customers' AI authors read). p1

Mechanical, not recalled:

  1. The surface diff. packages/spec/authorable-surface/*.json at the tag @objectstack/spec@18.0.0 against main. List every key added, every key whose shape or semantics changed, and every key retired or narrowed. The generated surface is the source; the changesets' Metadata-protocol: lines are a cross-check.
  2. Coverage. For each added or changed key, check whether skills/** (rules, references, examples) teaches it and whether an eval exercises it. A key a skill must teach is any key an author picks between options for, such as when against a validation rule. A purely mechanical key may be covered by the spec's .describe() alone; say which, per key.
  3. The reverse direction (stale advice is worse than none). Find every place skills/** still teaches a retired or narrowed form: the ≤16.x kits retired by PR feat(spec,cli)!: retire the ≤16.x retirement kits; the strict unknown-key refusal names the protocol upgrade guide #26138, the position-name fold retired by PR fix(plugin-security)!: retire the position-name fold; a namesake set is reported, never granted (#24757) #26064 (Setup: a position's same-named permission set is in force but invisible — the set's Assigned Users panel is empty and the position reads as granting nothing #24757), and anything else the diff names. Also check the skills' references/_index.md symbol anchors.
  4. The objectui skill bundle moving into skills/ (aftercare(ui-merge): move the objectui skill bundle into the root skills/ catalog (decision C): token pricing, reserved-word uses, visibleOn alias, internal flag (parent #25677, Tier H) #25832): it is audited in the same pass once it is there, or listed as pending if it is not.
  5. Output: one gap table (key × skill file × taught? × eval? × stale?), posted on this card. Then one fix card per skill package, batched and graded p2 unless a gap is on an 18.2 headline feature (p1). skills(objectstack-data): teach the field permission when and when to pick it over a validation rule, so an AI author locks a field per role and stage instead of for everyone #26179 is the first known row.

Part B: pm-dispatch (.claude/skills/pm-dispatch/**, .claude/agents/os-dev.md). p2

Find where the follow-up belongs, and draft the rule text for the maintainer to rule on. Triage's candidate is a review item, not a new gate (「新增门禁默认否」):

  • A PR whose Metadata-protocol is added, semantic or narrowed carries one more line, Skills-docs: updated here | follow-up #N | none — <reason>.
  • The seat's 席位核对 checks that line. Missing means no ACCEPT.
  • Triage's first grade of a protocol-addition card writes "skills + docs + eval" into its done-when.

Sequencing: the skills lane already holds six pm-dispatch edits today (#25991, #26066, #26121, #26122, #26143, #26155). Part B drafts against main after those land, or rides the same holder, so the rule text does not collide.

Acceptance

  • Part A's table is posted, its fix cards are filed, and each row cites the surface diff line it came from.
  • Part B's rule draft is posted for the maintainer's ruling. Once ruled, it lands as one governed PR.
  • Nothing is removed from skills/** in this card. Fixes ride the per-package cards.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — tooling · documentation · priority:p1 · domain:skills · area:devpath · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T15:00Z

    ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatch order · domain:skills#2 · session_01LqKsGyMNFwwnbF5FTAqyPn · 2026-10-26T19:23Z

    You are the auditing agent for exactly ONE card: #26184, in your own card thread. This card is an AUDIT: its deliverables are comments on the card, ⛔ not a PR and ⛔ not an edit to skills/** or .claude/** (the card: 「Nothing is removed from skills/** in this card. Fixes ride the per-package cards.」). Still read .claude/agents/os-dev.md in the objectstack clone IN FULL and follow its reading, writing and reporting discipline (hand-back JSON, api_writes / mcp_calls counts, 3–5 dedupe words per finding, ⛔ dev 不立卡 — you propose cards, the seat files them); read the repo-root AGENTS.md and pm-dispatch references/untrusted-text.md and references/filing-gate.md before you write. Read the card's full body and every comment yourself (REST: curl -sS -X GET "https://api.github.com/repos/objectstack-ai/objectstack/issues/26184" -H "Authorization: Bearer $GH_TOKEN" and /comments?per_page=100), and the two seed cards it names (/issues/26179, /issues/26178). ⛔ Never print the value of any environment variable (test presence with [ -n "${X+x}" ]).

    Identity and branch: the seat's Claim: comment on this card is your identity; ⛔ post no claim of your own, ⛔ never write the card's assignee. You push nothing: no worktree is needed beyond a fresh clone/fetch of origin/main and the tags; if your thread was given a push branch, leave it untouched and say so in the report.

    Writes: comments only, through scripts/pm/post-stamped.mjs --comment=26184 --file=F from the clone root (stamps: {{NOW}} for this act, {{WAS:YYYY-MM-DDThh:mmZ}} for any quoted reading; a bare timestamp is refused). ⛔ GitHub MCP writes of every kind; ⛔ no card filing (the seat files from your proposals). Report both counts.

    Ruling (cannot be re-ruled)

    Maintainer's words in the card body, verbatim: 「我不问你你也想不到立卡,如何避免出现类似的情况,需要更新 skills吗」「是否建议单独立卡完整的评估一下现有 skills的缺口」「包括 pm-dispatch skills 和对外的skills」「立"skills 缺口评估卡"」. Triage first grade 6419307365: Part A is p1 (18.2's protocol additions — field permission when, report and block translations, list grouping orderBy, the inlineTitle slot, hook-refusal keys), Part B is p2 and sequences after the lane's in-flight pm-dispatch edits.

    PM mechanism hypotheses (measure before you act; falsification is welcome)

    Read on origin/main at 2026-10-26T19:23Z:

    1. The floor tag is not where the card says. git ls-remote --tags origin lists @objectstack/spec@18.0.0-next.5 and @objectstack/spec@18.1.0 but NO @objectstack/spec@18.0.0; packages/spec/package.json on main reads 18.1.0. Measure the floor: the first main commit where packages/spec/package.json read "version": "18.0.0" (git log --format=%h -S'"version": "18.0.0"' -- packages/spec/package.json), or the 18.0.0 entry in packages/spec/CHANGELOG.md; state which commit you diff from and why. The surface files are packages/spec/authorable-surface/*.json (ai, api, automation, data, identity, integration, kernel, marketplace, qa, security).
    2. The surface diff is mechanical: diff each authorable-surface/*.json floor → main; list every key added, changed (shape or .describe() semantics) or retired/narrowed, with the surface file and line. Cross-check against .changeset/*.md history and merged PR bodies' Metadata-protocol: lines (git log --grep='Metadata-protocol: added' and semantic / narrowed on main since the floor).
    3. Coverage per key: for each added/changed key, grep skills/** (rules, references, examples, references/_index.md anchors) and the evals under skills/*/evals/*.json; classify taught / eval'd / mechanical-only (the spec's .describe() suffices) / gap. A key an author chooses between options for (e.g. when vs a validation rule) is never mechanical-only.
    4. Reverse direction: every place skills/** still teaches a retired or narrowed form — the ≤16.x kits retired by PR feat(spec,cli)!: retire the ≤16.x retirement kits; the strict unknown-key refusal names the protocol upgrade guide #26138, the position-name fold retired by PR fix(plugin-security)!: retire the position-name fold; a namesake set is reported, never granted (#24757) #26064 (Setup: a position's same-named permission set is in force but invisible — the set's Assigned Users panel is empty and the position reads as granting nothing #24757), and anything the surface diff names as retired; check references/_index.md symbol anchors resolve.
    5. objectui bundle (aftercare(ui-merge): move the objectui skill bundle into the root skills/ catalog (decision C): token pricing, reserved-word uses, visibleOn alias, internal flag (parent #25677, Tier H) #25832): audited in the same pass if it is under skills/ on main; else one line "pending".
    6. Output A (the p1 deliverable): ONE comment on this card carrying the gap table (key × skill file × taught? × eval? × stale?), each row citing the surface-diff file:line it came from, then a 「Proposed fix cards」 section: one per skill package, each with title, body (filing-gate form: 谁付代价, measured premise with file:line, Wanted, Acceptance, dedupe words), proposed grade (p2; p1 only for an 18.2 headline-feature gap) — skills(objectstack-data): teach the field permission when and when to pick it over a validation rule, so an AI author locks a field per role and stage instead of for everyone #26179 is the known first row of objectstack-data, ⛔ do not re-propose it, reference it.
    7. Output B (p2, after A): ONE comment carrying the rule-text draft for the maintainer's ruling — where the skills/docs follow-up belongs in pm-dispatch: the Skills-docs: updated here | follow-up #N | none — <reason> PR-body line for Metadata-protocol: added|semantic|narrowed, the 席位核对 item that reads it (no ACCEPT without it), and triage's done-when item for protocol-addition cards. Name the exact files and lines on main where each would live (.claude/agents/os-dev.md PR-body section, .claude/skills/pm-dispatch/SKILL.md 核对六项 / 报告契约, references/triage-duties.md), measure each file's ratchet headroom (scripts/pm/check-skill-line-ratchet.mjs CEILINGS), and write the draft so each addition is paid in-file (name the line it would retire). ⛔ No new gate (triage: 「新增门禁默认否」). ⛔ Do not edit anything: this is a draft for a ruling; the seat puts it in the decision box.

    Card-specific clauses

    • Hand-back: post the os-dev-report JSON as a comment on this card (first line os-dev-report; pr: null, files_changed: [], status: "done" once A and B are posted, with the two comment ids in summary), then send the seat thread 「Dispatch the skills lane」 one message: the two comment ids and the number of proposed fix cards. Keep your thread open for a follow-up question.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (fifth wave) · 2026-10-26T19:27Z
    Session: session_01LqKsGyMNFwwnbF5FTAqyPn (seat; audit by card thread session session_01C2Uuz8d9KeZ7qEYm6ZYWHL, mode:thread)
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-fbjk6r (the card thread's harness push branch, self-reported; this card pushes nothing — its deliverables are comments on the card)
    Worktree: none — a read-only clone of origin/main and its tags in the card thread
    Domain: domain:skills
    Seat: domain:skills#2 (seat post #19287)
    File surface: none edited. Read surface: packages/spec/authorable-surface/*.json (floor → main), .changeset/** history, skills/** (rules, references, evals, references/_index.md), .claude/skills/pm-dispatch/** and .claude/agents/os-dev.md for the Part B draft. Outputs: Part A gap table + proposed fix cards (one comment), Part B rule draft for the maintainer's ruling (one comment). ⛔ No PR, ⛔ nothing removed from skills/** (the card's own acceptance). (stop on breach; explain in the report)
    Container & model: L, mode:thread, model: default judgement tier (dispatch-gates --tier: no path mandate — the surface is read, not written; the skills/** edits ride the per-package fix cards, each dispatched at its own mandated tier), effort: high. The dispatch order is comment 6425274137 on this card and the thread's opening message points to it (the coordinator channel caps at 2,000 characters).
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (filing gate ③: the maintainer's 「立"skills 缺口评估卡"」, quoted verbatim in the body)
    Thread-read: 6419307365
    Premise: holds with one correction, recorded for the thread: no @objectstack/spec@18.0.0 tag exists on origin (only 18.0.0-next.5 and 18.1.0; packages/spec/package.json on main reads 18.1.0), so the floor is the first main commit where the spec read 18.0.0, measured by the thread and stated in its table. The surface files, the seed cards (#26179, #26178) and the two retirement PRs named in the body are present.
    Serial constraints cleared: n/a — no file is written. Part B's draft is a ruling input, not an edit; the lane's in-flight pm-dispatch PR (#26286) and the queued #26155 do not collide with a comment.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Audit Part A: the published skills against the protocol since 18.0 · gap table and proposed fix cards · session_01C2Uuz8d9KeZ7qEYm6ZYWHL · 2026-10-26T19:43Z

    Audit for the dispatch order 6425274137, under the claim 6425345339 (branch claude/project-thread-fbjk6r, nothing pushed). ⛔ Not a claim. ⛔ Nothing filed: the cards below are proposals for the seat to file.

    Trees read. Floor 06cab4849a = tag @objectstack/spec@18.0.0 → origin/main at be531f685e (2026-10-26T18:08Z), 699 commits apart. The clone was unshallowed first; both ancestry legs answer exit 0 (06cab4849a and the control @objectstack/spec@18.0.0-next.0 are both ancestors of origin/main).

    Premise corrections.

    • Hypothesis 1 is falsified: git ls-remote --tags origin lists refs/tags/@objectstack/spec@18.0.0 (tag object 08420c3383, peeled to 06cab4849a, "chore: version packages (chore: version packages #24524)"). It is also the oldest commit git log -S'"version": "18.0.0"' -- packages/spec/package.json returns, so the tag and the version bump agree. The diff runs from that tag.
    • There are 14 surface files, not 10: shared, studio, system and ui exist at both ends. shared and studio did not change.
    • The surface ratchet records key NAMES only. A changed meaning, a narrowed value, a new slot type or a widened executor set leaves no surface line, so rows without a surface line come from the cross-check (commit messages' line-initial Metadata-protocol:, and spec-touching commits from before the line existed) and say so.

    The surface diff. 48 lines added and 66 removed across 7 files: 42 new keys, 6 keys relabelled [RETIRED] (tombstoned), and 60 keys deleted whole (12 api/ApiTestingUiConfig:* and 48 kernel/* package-upgrade keys).

    The cross-check, as one number. 60 commits since the floor carry a line-initial Metadata-protocol: added | semantic | narrowed. 3 of them touched skills/**, and all three only anchors or a key list: 493a6c4a5f (two _index.md lines), f00e8d5c85 (one key-list line), fa44dd2559 (one _index.md line). None added a sentence that teaches the change. 26 of the 60 touched hand-written content/docs/**.

    Legend. Taught: yes / partial / no. Eval: whether any skills/*/evals/*.json exercises it. Stale: whether a skill teaches a form the change refused or made wrong. Kind: choice (an author picks between options, so .describe() alone is never enough) or mechanical (.describe() suffices). Surface lines are packages/spec/authorable-surface/FILE.json:LINE on main unless marked @floor.

    objectstack-data

    # Key or change (surface line) Commit Skill file Taught Eval Stale Kind
    D1 security/FieldPermission:when (security.json:105) c8cb510a5e added rules/security.md no no no choice. Known row: #26179, not re-proposed
    D2 data/Object:membershipKeys (data.json:686); security/MembershipKey:description, filter, label, userField, valueField (security.json:106-110) dc532e8c1c added; b531016f6d narrowed; e5eab0658e semantic rules/security.md:112 names the current_user.KEY placeholder only; the declaration is untaught partial no no choice (membership key vs positions vs a sharing rule)
    D3 data/Object:sharing, i.e. sharing.controlledByParent.ownerMayEdit (data.json:695) 5e113b395a added rules/relationships.md:16, SKILL.md:76 teach controlled_by_parent; no word on ownerMayEdit no no no choice
    D4 data/Seed:columns (data.json:907), data/SeedColumn:applyOn (data.json:914) 493a6c4a5f added references/seeds.md:51-63 (option table has no columns) no no no choice (a create-only column survives a re-seed)
    D5 A position grants only the sets its permissionSets names; the namesake fold is gone. No surface line 733b3c849a declared Metadata-protocol: none, Clause-②: yes (narrowing) rules/security.md:1-60 covers sets and assignment rows; no skill declares a position or its permissionSets no no no choice (a set named after a position now grants nothing by itself)
    D6 The external organization role for portal users. No surface line (a role value) 9019af9fe6 added; 45f996231e, 4a251927c2 semantic rules/security.md no no no choice (external vs member)
    D7 { type: 'lookup', reference: 'user' } at references/examples-objects.md:42 and :88 names an object that does not exist (the identity object is sys_user). The 18.x form is type: 'user', which always resolves sys_user and refuses any other reference 2069b81c26 narrowed references/examples-objects.md:42, :88 wrong form no yes example

    No stale form found for: f6ba1343ba (allowDelete: false beside modifyAllRecords: true), fe0ec2bb9e / bda53bb0ba (an external binding on a managed datasource; rules/datasources.md:16-18 agrees), c5915b2bbd (a validation reading parent), 02ad31a0c3 (the controlled_by_parent master reference), 386f60f8fb (select string shorthand), 23540582f4 (data/TursoConfig:encryptionKey [RETIRED], data.json:1001, 0 skill hits), 4034f47bd0 (composite and repeater are untyped JSON; rules/field-types.md:116-117 already says so).

    objectstack-ui

    # Key or change (surface line) Commit Skill file Taught Eval Stale Kind
    U1 ui/GroupingField:orderBy (ui.json:671) b00fc55c7d added rules/list-views.md: list-view grouping itself is untaught (0 hits) no no no choice. 18.2 headline (triage 6419307365)
    U2 ui/DatasetMeasure:duration (ui.json:419), ui/DatasetMeasureDuration:from, to, unit (ui.json:425-427) d1663ba182 added rules/dashboards.md:69-72 puts "scalar math on raw fields" outside the envelope and :90-92 sends computed columns to a stored field; neither names the duration measure no no partial: time between two datetime fields of a record is now a measure, not a hook-kept stored number. The leave-days example at :93-99 stays right, because the measure takes datetime fields only choice
    U3 ui/DatasetDimension:nullLabel (ui.json:414) 7c68b10825 added none no no no mechanical
    U4 Action copy (confirmText, successMessage, errorMessage, and the bulk confirmText) is a template slot: {{ }} holes over the roots the runner binds; a ${…} token, a single-brace token, a blank sentence or a hole holding logic is refused at os validate, compile and publish. No surface line (a slot type) 925fd0772c, 384bb7ba02 semantic; ecb4e69951, 0c81694006, d7273482ba narrowed rules/actions.md:20-21 teaches the three keys as plain copy, with no word on holes, roots or the refusals no no no stale example, but a trap: "Lead ${record.name} reassigned" fails os validate choice
    U5 onSuccess on a type: 'flow' action (navigate after a run that completes). No surface line (the executor set widened) dc71845414 added rules/actions.md:64-69 (the flow action example has no onSuccess) no no no choice
    U6 ui/AddRecordConfig:mode, formView [RETIRED] (ui.json:164-165) fde7456352 0 skill hits n/a n/a no n/a
    U7 record:details hideEmpty: false renders the heading and one fold row 2af790ffaa semantic none no no no mechanical

    objectstack-automation

    # Key or change (surface line) Commit Skill file Taught Eval Stale Kind
    A1 automation/Flow:requiredPermissions (automation.json:169), api/CreateFlowRequest:requiredPermissions (api.json:364) f1ddace887 added SKILL.md (0 hits in the package; requiredPermissions is taught only per field and per action elsewhere) no no no choice (who may start a flow)
    A2 automation/ApprovalNodeConfig:excludeSubmitter (automation.json:39); refused beside onEmptyApprovers: 'auto_approve' 49653f9181 added; 4bcc4df649 narrowed references/state-machines-and-approvals.md:344-351 (the approval config table has no excludeSubmitter) no no no choice (segregation of duties)
    A3 automation/NotifyEmailFieldRecipient:emailField (automation.json:279); a CEL value that evaluates to an address no user holds now fails the node at run time; a written-out address is an author constant 6021b5e837 added; d1e329e96d narrowed; 52f3f518e1 semantic SKILL.md:107 lists recipients as "id, list, or envelope" no no trap: to mail an applicant who is not a user, an author writes an envelope over record.applicant_email, which now fails at run time; the answer is { emailField } choice
    A4 A flow screen field typed file collects an upload and the run resumes with the file id. No surface line 6d9d3ef857 semantic SKILL.md does not enumerate screen field types no no no choice
    A5 escalateTo naming a membership tier is refused at registration 9993165bb9 narrowed references/state-machines-and-approvals.md:351 already says a position name or a user id, never a membership tier yes no no n/a
    A6 An api start node's config.secretRef fa44dd2559 added SKILL.md:343 yes no no n/a

    No stale form found for: 303aef069e (get_record limit is a positive integer), a285ff29a1 (a system run writes no identity assignment; the runAs section at SKILL.md:144-192 teaches no such write).

    objectstack-i18n

    # Key or change (surface line) Commit Skill file Taught Eval Stale Kind
    I1 system/TranslationData:reports (system.json:1332), PlatformTranslationData:reports (:915), TranslationItem:reports (:1363) dd5e3554f0 added SKILL.md:169-172: the enumerated top-level groups omit reports no no partial: the list reads as complete choice. 18.2 headline (report translations, triage 6419307365)
    I2 TranslationData:positions, permissions (system.json:1331, :1329), and the same two on PlatformTranslationData (:914, :912) and TranslationItem (:1362, :1360) 47af3dde42 added the same list omits both no no partial choice
    I3 A form section entry's label, placeholder, helpText under _sections.SECTION.fields.FIELD. No surface line (nested shape) 42d9fe8f5b added SKILL.md:165 says _sections holds label, description only no no partial choice
    I4 A form view's title under _views.VIEW.title eddffc3390 (before the line existed) SKILL.md:163: the _views row omits title no no partial choice
    I5 pages.PAGE.components.TABS.items.VALUE.label; flows.FLOW.approvals.NODE.label 30d21f6321, b9a79efcd1 (before the line existed) SKILL.md:172 names the pages and flows groups only no no no mechanical if the extract scaffold writes the key (NOT MEASURED), else choice
    I6 A locale must be a BCP-47 tag 39a78b151d narrowed the naming table (BCP-47); evals/bundles-locales-coverage.json:21 must_not_contain ja_JP yes yes no n/a

    objectstack-query

    # Key or change (surface line) Commit Skill file Taught Eval Stale Kind
    Q1 data/NowAnchor:$now, addDays (data.json:653-654): a comparand of now shifted by days a field of the record holds be531f685e added (the newest commit on main) rules/filters.md:40-56 ($field) and :124-145 (date macros) teach the two halves separately; the combination is untaught. objectstack-formula/SKILL.md:146,159 teach the CEL addDays(), a different surface no no no choice (vs a stored formula field)

    objectstack-platform

    # Key or change (surface line) Commit Skill file Taught Eval Stale Kind
    P1 system/DemoStaff:email, name, permissionSets, position (system.json:296-299) f00e8d5c85 added SKILL.md:52 names demoStaff beside devLogins in the top-level key list and nothing more (that PR's one-line skills edit) no no no choice (demoStaff creates dev-only accounts with a position and sets that seed data is dealt to; devLogins is banner text)
    P2 api/AuthFeaturesConfig:cloudManaged (api.json:209) f4112a704b added none no no no mechanical (an operator flag a cloud deployment sets; an app author never picks it)

    objectstack-api

    # Key or change (surface line) Commit Skill file Taught Eval Stale Kind
    API1 api/FieldMappingEntry:applyOn (api.json:652): an import column written on create only b77bb37eb2 added SKILL.md:253 names the import route only no no no choice
    API2 api/FlowFailureDetails:errorMessage, innerRefusal, summary; api/FlowInnerRefusal:code, message (api.json:683-687) 045858f32a added none (FLOW_FAILED untaught) no no no low: a client that shows why a flow failed reads innerRefusal
    API3 A form open to anonymous intake that declares a file field is refused 6ad226aa2a narrowed SKILL.md:75-100 (public forms) is silent no no no low: the refusal names it
    API4 api/ApiDocumentationConfig:ui [RETIRED] (api.json:110), api/OpenApiGenerationConfig:uiFramework, uiPath [RETIRED] (api.json:1226-1227), api/ApiTestingUiConfig:* deleted (api.json@floor:176-187) 14e7239e73 0 skill hits n/a n/a no n/a

    objectstack-upgrade

    # Key or change (surface line) Commit Skill file Taught Eval Stale Kind
    UP1 The 16.x-and-older retirement kits leave and the migration floor rises to 17. Not on main: PR #26138 is open, and its file list touches no skills/** PR #26138 (narrowed) SKILL.md:64-66, :101-103 ("support floor, 16 today"), :141-147 (--from 16 recipes), :178 (a stored row replays the full chain at read); evals/protocol-major-upgrade.json:10 must_contain "os migrate meta --from 16" yes, for main today yes becomes stale the moment #26138 lands choice
    UP2 kernel/package-upgrade.zod.ts retired whole (kernel.json@floor:300-305, 641-646, 754-789) 557973dbcc narrowed 0 skill hits n/a n/a no n/a

    Passes with no row

    Proposed fix cards

    One card per skill package: 8 cards. Each card's reader is the domain:skills lane, one PR to skills/PACKAGE/** (Tier H). Shared acceptance for all 8: every new teaching gets an eval prompt in that package's evals file; check:skill-docs, check:skill-refs and check:skill-examples are green; the PR body reports the whole-file and whole-package before/after line counts, and the additions are paid for in that package; nothing is removed beyond the stale lines a card names. Filing gate for all 8: ③, a follow-up the maintainer's 「立"skills 缺口评估卡"」 on this card ordered (quoted in the body above).

    Card 1 · objectstack-data · p2

    Title: skills(objectstack-data): teach membership keys, ownerMayEdit, create-only seed columns, the position-to-set binding and the external role, and fix the reference: 'user' example

    • Who pays: an AI author building a portal or a roster-scoped app. Without these rules they write per-row policies by hand, expect a position-named set to grant itself, or re-seed over an admin's edit. The reference: 'user' example copies straight into a lookup to an object that does not exist.
    • Measured: rows D2–D7 above, each with its file:line.
    • Wanted: in rules/security.md, how to declare membershipKeys (userField, valueField, filter) and when to choose it over positions or a sharing rule; that a position grants only the sets its permissionSets names; the external role for portal users. In rules/relationships.md, sharing.controlledByParent.ownerMayEdit. In references/seeds.md, columns.FIELD.applyOn: 'create'. In references/examples-objects.md:42,88, the type: 'user' form.
    • Acceptance: the shared clauses, plus one eval for "a portal user reads only the rows of the accounts they belong to", whose expected output names membershipKeys and current_user.KEY.
    • Not in scope: the field permission when, which is skills(objectstack-data): teach the field permission when and when to pick it over a validation rule, so an AI author locks a field per role and stage instead of for everyone #26179.
    • Dedupe words: membershipKeys skill, ownerMayEdit, seed applyOn, position permissionSets, reference user lookup example.

    Card 2 · objectstack-ui · p1 (U1 is an 18.2 headline)

    Title: skills(objectstack-ui): teach list-view grouping and orderBy, the duration measure, action copy holes, and a flow action's onSuccess

    • Who pays: an AI author building lists, dashboards and actions on 18.2. They cannot group a list by stage in pipeline order. They send "average time to close" to a hook-kept field. They write ${record.name} into a toast and fail os validate. They cannot take the user to the record a flow created.
    • Measured: rows U1, U2, U4, U5.
    • Wanted: rules/list-views.md: grouping.fields[] and orderBy. rules/dashboards.md:69-72: a duration measure for the time between two datetime fields (from, to, unit), and a correction to the escalation advice for that case. rules/actions.md:20-21: the {{ }} holes, the roots per key, the bulk count and params roots, and the refused shapes. rules/actions.md:64-69: onSuccess on a flow action, reading ${result.output.VAR}.
    • Acceptance: the shared clauses, plus evals for "group opportunities by stage in pipeline order" and "Lead NAME reassigned toast".
    • Dedupe words: grouping orderBy skill, duration measure skill, action copy template holes, flow action onSuccess.

    Card 3 · objectstack-automation · p2

    Title: skills(objectstack-automation): teach flow-level requiredPermissions, excludeSubmitter, the { emailField } recipient and screen file fields

    • Who pays: an AI author of approvals and notifications. Without excludeSubmitter a submitter approves their own request. Mailing an applicant through a CEL envelope now fails the run.
    • Measured: rows A1–A4.
    • Wanted: SKILL.md:107: the fourth recipient form { emailField }, and that a computed address no user holds fails the node. The approval config table at references/state-machines-and-approvals.md:344-351: excludeSubmitter, refused beside auto_approve. A short section on flow requiredPermissions and on screen fields typed file.
    • Acceptance: the shared clauses, plus an eval "email the applicant when the application is approved" that expects recipients: { emailField: … }.
    • Dedupe words: emailField recipient skill, excludeSubmitter, flow requiredPermissions skill, screen file field.

    Card 4 · objectstack-i18n · p1 (I1 is an 18.2 headline)

    Title: skills(objectstack-i18n): the translation bundle's top-level groups and object sub-keys as of 18.2: reports, positions, permissions, section field entries, form view titles, page tab items, approval step labels

    • Who pays: an AI author shipping a zh-CN pack. The skill's enumerated lists read as complete, so reports, positions and permission sets ship untranslated and nothing reports a missing key.
    • Measured: rows I1–I5.
    • Wanted: SKILL.md:169-172 lists every top-level group; :163 adds title; :165 adds fields.FIELD (label, placeholder, helpText); one line each for the page tab items and approval step label paths, or a pointer to the scaffold if it writes them.
    • Acceptance: the shared clauses, plus an eval that translates a report and a permission set.
    • Dedupe words: translation reports group skill, positions permissions translation, _sections fields translation, form view title translation.

    Card 5 · objectstack-query · p2

    Title: skills(objectstack-query): teach the now-anchored comparand { $now: true, addDays: FIELD }

    • Who pays: an AI author asked for "overdue by each record's own grace days". They reach for a stored formula field and a hook.
    • Measured: row Q1.
    • Wanted: one subsection in rules/filters.md between Field References and Date Filtering Patterns, with the one example, and where the comparand is accepted and refused.
    • Acceptance: the shared clauses, plus one eval.
    • Dedupe words: $now addDays skill, now anchored comparand, relative date per record.

    Card 6 · objectstack-platform · p2

    Title: skills(objectstack-platform): teach demoStaff and when to pick it over devLogins

    • Who pays: an AI author preparing a demo. They declare banner logins and hand-write user seed rows instead of demoStaff.
    • Measured: row P1.
    • Wanted: one short section beside the bootstrap docs: demoStaff (dev boot only, never in the built artifact, position and permissionSets per account) against devLogins.
    • Acceptance: the shared clauses, plus one eval.
    • Dedupe words: demoStaff skill, devLogins demo accounts.

    Card 7 · objectstack-api · p2

    Title: skills(objectstack-api): teach import applyOn, read FLOW_FAILED's innerRefusal, and the anonymous-form file refusal

    • Who pays: an AI author of import jobs, who overwrites a column an admin owns on every re-import, and a client author, who shows "flow failed" instead of the real reason.
    • Measured: rows API1–API3.
    • Wanted: SKILL.md:253 neighbourhood: import column applyOn: 'create'; the error-envelope section: FLOW_FAILED details with innerRefusal; SKILL.md:75-100: a public form declares no file field.
    • Acceptance: the shared clauses, plus one eval for the import.
    • Dedupe words: import applyOn skill, FLOW_FAILED innerRefusal, anonymous form file field.

    Card 8 · objectstack-upgrade · p1 when it lands, Blocked-by: #26138

    Title: skills(objectstack-upgrade): the migration floor is 17 and 16.x-and-older rows are no longer rewritten at read, once the 16.x retirement kits leave

    Batch: 8 cards (fewer than 10, so no Batch-of: line is owed). Part B (where pm-dispatch should ask for this follow-up) is the next comment.

  5. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Audit Part B: where pm-dispatch owes the skills/docs follow-up · rule draft for the maintainer's ruling · session_01C2Uuz8d9KeZ7qEYm6ZYWHL · 2026-10-26T19:44Z

    ⛔ A draft, not an edit: nothing was changed. The seat puts it in the decision box. Read against origin/main at be531f685e. Triage's 「新增门禁默认否」 holds: every item below is something a seat reads and checks, and no script reads it.

    What the draft rests on (measured)

    • Nothing follows from the kind today. Since the 18.0.0 tag, 60 commits carry a line-initial Metadata-protocol: added | semantic | narrowed. 3 touched skills/**, only anchors or a key list (Part A, cross-check). The gap table in Part A is what that produces: 26 rows owe teaching across 8 packages.
    • Premise correction: there is no PR template. git ls-files | grep -i pull_request_template on main returns nothing. The Metadata-protocol: line lives in the claim template (.claude/skills/pm-dispatch/SKILL.md:313), and .claude/agents/os-dev.md:279-280 copies it into the PR body and every changeset. So the new line goes where those two are copied. There is no template file to edit.
    • The card's trigger misses one measured row. Row D5 (a position grants only the sets its permissionSets names) came from a PR declared Metadata-protocol: none and Clause-②: yes (narrowing). A trigger on the kind alone would not have asked it for a skill line. The narrowing arm would have.
    • Every file the draft touches is at its ceiling (node scripts/pm/check-skill-line-ratchet.mjs, exit 0): os-dev.md 404/404, SKILL.md 319/319, references/review-checklist.md 77/77, references/triage-duties.md 103/103, all with headroom 0. So the draft adds 0 net lines: each item widens an existing line in place and deletes nothing. The one place where a separate line would read better names the line it would retire.
    • No reader parses the new line. scripts/pm/clause2-line.mjs reads exactly the Clause-②: and Metadata-protocol: keys and nothing else, so a third line-initial key changes no gate verdict.

    Decision for the maintainer: which PRs owe the line

    • A. The card's trigger: Metadata-protocol: is added, semantic or narrowed.
    • B. A, plus any PR whose Clause-②: line carries the (narrowing) arm. Recommended: it catches the D5 case, a runtime narrowing of what an author must write that its PR declared as kind none. The cost is one Skills-docs: none — REASON line on breaking PRs that change nothing an author writes.

    The draft below is written for B. For A, drop the words 或带 (narrowing) and "or a (narrowing) arm" from items 1–4.

    1 · The line itself: claim template, .claude/skills/pm-dispatch/SKILL.md:313 (0 net lines)

    Before:

    Metadata-protocol: added | narrowed | semantic | none (the kind of change to what a metadata author can write; the level table is AGENTS.md's Post-Task Checklist step 3; the dev copies it beside `Clause-②:` into the PR body and every changeset body)
    

    After (the parenthetical gains one clause):

    Metadata-protocol: added | narrowed | semantic | none (the kind of change to what a metadata author can write; the level table is AGENTS.md's Post-Task Checklist step 3; the dev copies it beside `Clause-②:` into the PR body and every changeset body; a kind other than `none`, or a `(narrowing)` arm, owes the PR body a third line the dev writes from the diff: `Skills-docs: updated here | follow-up owed — FILES | follow-up #N | none — REASON`)
    

    2 · The dev writes it: .claude/agents/os-dev.md:279, Definition of done (0 net lines)

    Before:

    - 认领的 `Clause-②:`、`Metadata-protocol:` 两行照抄进 PR 正文行首;无则零写,⛔ 不自造。
    

    After:

    - 认领的 `Clause-②:`、`Metadata-protocol:` 两行照抄进 PR 正文行首;无则零写,⛔ 不自造;种类非 `none` 或带 `(narrowing)` 再按 diff 自写 `Skills-docs:` 行(取值住认领模板),欠后续写 `follow-up owed — FILES`,卡由席位立。
    
    • follow-up owed keeps the dev inside its rules: the dev files no card, and writes the PR body once with no PATCH. The seat files the card (filing-gate.md: follow-ups owed by landed work are filed), then rewrites the line to follow-up #N before ACCEPT, the existing 「事后要改的报告点名改法,席位代写」 path.
    • Separate-line variant, if preferred: +1 line, paid by retiring os-dev.md:284 (the three example spellings of a safe non-closing sentence). The principle stays at :282-283 and the seat's copy at review-checklist.md:10.

    3 · The seat checks it: no ACCEPT without it (0 net lines)

    .claude/skills/pm-dispatch/SKILL.md:191, before:

    - 核对六项(席位读此):形态/前提实测/门禁 check-runs/接受的偏差/范围外去向/落地条款。
    

    After:

    - 核对六项(席位读此):形态/前提实测/门禁 check-runs/接受的偏差/范围外去向(含 `Skills-docs:` 行)/落地条款。
    

    .claude/skills/pm-dispatch/references/review-checklist.md:17 (〈范围与 changeset〉), before:

    - 三条判据:无 `content/docs/releases/` 改动、用户可见改动有 changeset、无与卡无关的文件。
    

    After:

    - 四条判据:无 `content/docs/releases/` 改动、用户可见改动有 changeset、无与卡无关的文件、种类非 `none` 或带 `(narrowing)` 时 `Skills-docs:` 行在且属实(`updated here` 即 diff 触 `skills/**` 或手写文档并带 eval;`follow-up owed` 立卡改写为 `#N`),缺即 ⛔ 不 ACCEPT。
    

    4 · Triage grades it in: the done-when of a protocol card (0 net lines)

    .claude/skills/pm-dispatch/references/triage-duties.md:58, before:

    - 每张留一条英文审计评论(`Triage: lands in …; rationale: …`),可选带 `Size/model suggestion:` 行。
    

    After:

    - 每张留一条英文审计评论(`Triage: lands in …; rationale: …`),可选带 `Size/model suggestion:` 行;会改作者可写面(种类非 `none` 或收窄)的卡,done-when 写 skills + docs + eval 三项。
    

    What the draft deliberately does not do

    • ⛔ No gate, no script and no ledger: the line is read by the seat (items 3 and 4). check:pm-skill-id-lint holds, because no draft line cites an issue number.
    • ⛔ No change to AGENTS.md (1112/1112, headroom 0). Its Post-Task Checklist step 3 keeps defining the two declaration lines; the third line is a pm-dispatch review item, so it lives in pm-dispatch.
    • ⛔ No back-fill of landed PRs. Part A's 8 proposed cards are the back-fill.

    Sequencing

    The draft overlaps two in-flight edits in the same lane. Card #26155 rewrites the os-dev.md PR-body block next to :279 (:288-289, the brief) and is queued. PR #26286 (open) edits one line of os-dev.md and references/execution-duties.md. Once ruled, the draft lands as one governed PR (Tier S, all .claude/**), rebased onto both of those, or rides #26155's PR because it edits the same section. The line numbers above are main at be531f685e. The PR re-measures them and the ratchet on its own head.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 26184,
    "status": "done",
    "branch": "claude/project-thread-fbjk6r",
    "pr": null,
    "files_changed": [],
    "session": "session_01C2Uuz8d9KeZ7qEYm6ZYWHL",
    "premise_still_valid": true,
    "summary": "Audit only, as ordered: Part A (gap table + 8 proposed fix cards, one per skill package) is comment 6425678185; Part B (rule-text draft for the maintainer's ruling) is comment 6425690779. Floor = tag @objectstack/spec@18.0.0 at 06cab48, which exists on origin, so dispatch hypothesis 1 is falsified; diffed to origin/main be531f6 across 14 surface files (not 10): 42 new keys, 6 relabelled [RETIRED], 60 deleted whole. 26 rows owe teaching; 60 protocol-kind commits since the floor added 0 teaching sentences to skills/** (3 touched only anchors or a key list). Proposed grades: objectstack-ui and objectstack-i18n p1 (18.2 headline rows U1, I1), objectstack-upgrade p1 on landing with Blocked-by #26138, the other five p2; #26179 is referenced, not re-proposed. Card premise corrected: there is no PR template on main; the Metadata-protocol line lives in the claim template (SKILL.md:313) and os-dev.md:279-280. The push branch was left untouched: no commit, no push.",
    "tests": "No code was changed, so no test was owed. Readings: git fetch --unshallow (rev-list origin/main 50 -> 17968), then merge-base --is-ancestor 06cab48 origin/main exit 0, control @objectstack/spec@18.0.0-next.0 exit 0 (both legs exit 1 on the shallow clone before deepening); git diff -U0 06cab48 origin/main -- packages/spec/authorable-surface/ (48 +, 66 -); per-key git log -S provenance; per-key git grep over skills/** and skills//evals/; a script resolving all 175 _index.md spec paths and 231 named exports on main (0 missing).",
    "gates": "No local gate family owed (no file edited). Read-only run: node scripts/pm/check-skill-line-ratchet.mjs exit 0, used for Part B headroom (os-dev.md 404/404, SKILL.md 319/319, review-checklist.md 77/77, triage-duties.md 103/103). post-stamped --dry-run exit 0 on both bodies before each write.",
    "dogfood_battery": "n/a: no PR",
    "mcp_calls": "0: ToolSearch loaded GitHub MCP read schemas, but no GitHub MCP tool was called; every read was REST GET via gh api",
    "api_writes": "3: comments on #26184 via scripts/pm/post-stamped.mjs through the fleet-write relay (6425678185 Part A, 6425690779 Part B, and this report); each read back byte-identical",
    "open_questions": [
    {
    "question": "Which PRs owe the Skills-docs line (Part B)?",
    "options": [
    "A: Metadata-protocol added, semantic or narrowed (the card's trigger)",
    "B: A, plus any PR whose Clause-② line carries the (narrowing) arm"
    ],
    "recommendation": "B, because the measured row D5 (position-to-set binding) came from a PR declared Metadata-protocol: none with Clause-②: yes (narrowing), which A would not have asked for a line"
    },
    {
    "question": "objectstack-upgrade (row UP1): card or rider?",
    "options": [
    "A: PR #26138 carries the skills edit itself (Tier H)",
    "B: file proposed card 8 with Blocked-by: #26138, landing before or with the release that ships it"
    ],
    "recommendation": "A if the maintainer reviews #26138 by hand anyway, else B; the seat decides"
    }
    ],
    "out_of_scope_findings": [],
    "deviations": "Part A (6425678185) was posted without the bare attribution footer; its opening line carries the session id as durable attribution, and it was not re-posted (no footer re-post loops). The clone was unshallowed (git fetch --unshallow origin main) because the shallow ancestry legs both read exit 1, and PR #26138's head was fetched into a local ref refs/audit/pr26138 to read its changeset; neither is a write to GitHub."
    }


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Filed · domain:skills#2 · session_01LqKsGyMNFwwnbF5FTAqyPn · 2026-10-26T19:56Z

    The audit's eight proposed fix cards (Part A, comment 6425678185) are filed by the seat, one per published skill package, each citing this card and the audit rows it rests on, pre-labelled documentation only (triage grades and routes):

    package card proposed grade
    objectstack-ui #26295 p1 (list grouping orderBy, 18.2 headline)
    objectstack-i18n #26296 p1 (translation groups, 18.2 headline)
    objectstack-data #26297 p2 (the when row is #26179, referenced)
    objectstack-automation #26298 p2
    objectstack-api #26299 p2
    objectstack-query #26301 p2
    objectstack-platform #26302 p2
    objectstack-upgrade #26303 p1 on landing, Blocked-by: #26138

    Dedupe, run by the seat before filing: REST listing of every issue updated since 2026-10-01T00:00Z (505 open + closed), title and body grep per card's dedupe words — the hits are the product or spec cards the rows teach (named in each body), no open skills card among them. Batch of 8 announced through write-pace.mjs (fewer than 10, no Batch-of: line owed).

    Part B (comment 6425690779) is in the decision box: the maintainer rules the trigger (A kind-only, or B kind-or-(narrowing), the audit's recommendation); once ruled it lands as one Tier S PR, sequenced after the lane's in-flight os-dev.md edits. This card stays open for that landing.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade of the eight audit fix cards · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T19:56Z

    ⛔ Not a claim, ⛔ not a dispatch. One anchor for the batch; each card carries its labels. All eight are documentation · domain:skills, Tier H (skills/** is a published surface). Grades follow Part A's proposal, read against 「发版本优先的都p1」.

    Card Package Grade Area State
    #26295 objectstack-ui p1 (list grouping orderBy is an 18.2 headline) area:devpath pm:queue
    #26296 objectstack-i18n p1 (reports, positions, permissions groups are 18.2 headline rows) area:i18n pm:queue
    #26303 objectstack-upgrade p1 (a wrong sentence on the release that carries #26138) area:devpath pm:blocked on PR #26138
    #26297 objectstack-data p2 area:access pm:queue
    #26298 objectstack-automation p2 area:workflow pm:queue
    #26299 objectstack-api p2 area:api pm:queue
    #26301 objectstack-query p2 area:records pm:queue
    #26302 objectstack-platform p2 area:devpath pm:queue

    Generated by Claude Code

  9. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (sixth wave) — Part B landing · 2026-10-27T00:38Z
    Session: session_01LqKsGyMNFwwnbF5FTAqyPn (seat; implementation by an in-session os-dev subagent, mode:subagent)
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-1r3slx (the seat container's only pushable branch — the measured platform exception to claude/issue-N-slug; reset to origin/main after PR #26327 merged)
    Worktree: objectstack-issue-26184-partb
    Domain: domain:skills
    Seat: domain:skills#2 (seat post #19287)
    File surface: .claude/skills/pm-dispatch/SKILL.md (the claim template's Metadata-protocol: line and the 核对六项 line), .claude/agents/os-dev.md (the declaration-copy line in Definition of done; the 「两声明行后」 wording of the brief line if a third declaration line makes it false), .claude/skills/pm-dispatch/references/review-checklist.md (〈范围与 changeset〉 判据 line), .claude/skills/pm-dispatch/references/triage-duties.md (the audit-comment line). All .claude/**; 0 net lines, every file at its ratchet ceiling. (stop on breach; explain in the report)
    Container & model: S, mode:subagent (in-session; a rule-text edit of four lines), model: CONTRACT_REVIEW_TIER (dispatch-gates --tier: MANDATORY — .claude/skills/pm-dispatch/SKILL.md is in the surface, clause ①), effort: xhigh. Tier S (.claude/** only): draft PR, the seat's independent contract review, then the seat lands it through the queue; ⛔ the dev never readies, arms or enqueues it.
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (the audit card's Part B: a pm-dispatch rule change the maintainer ruled on)
    Thread-read: 6425930271
    Premise: holds — Part B's draft (comment 6425690779) is written for trigger B; the maintainer chose B on the seat thread's decision card at 2026-10-27T00:33Z (tap label 「B:种类非 none 或带 (narrowing)」); on origin/main after PR #26327 (aea34436) the os-dev.md PR-body block was respelled (285–289) and the line the draft's separate-line variant would retire (old 284) is already gone, so only the in-place variant remains; the four files are at ceiling (404/404, 319/319, 77/77, 103/103); scripts/pm/clause2-line.mjs reads only the two existing keys.
    Serial constraints cleared: PR #26327 (same os-dev.md section) MERGED before this claim; no open PR touches the four files (REST scan of open PRs' file lists at claim time by the seat's premise read); the audit card's own Part A claim 6425345339 (thread session) is closed out by the report 6425719027 — this claim is the card's second half.
    Resume-from: none


    Generated by Claude Code

  10. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 26184,
    "status": "done",
    "branch": "claude/project-thread-1r3slx",
    "pr": "#26381",
    "pr_number": 26381,
    "head": "72b08a34cb776a955439fd51dce0227cdea30b01",
    "files_changed": [
    ".claude/skills/pm-dispatch/SKILL.md",
    ".claude/agents/os-dev.md",
    ".claude/skills/pm-dispatch/references/review-checklist.md",
    ".claude/skills/pm-dispatch/references/triage-duties.md"
    ],
    "session": "session_01LqKsGyMNFwwnbF5FTAqyPn",
    "premise_still_valid": true,
    "summary": "Part B landed as draft PR #26381 (Tier S, all .claude/, 4 files, +7/-7, 0 net lines per file) under the ruled trigger B: a PR whose Metadata-protocol kind is added/semantic/narrowed, or whose Clause-② carries the (narrowing) arm, owes a PR-body line Skills-docs: updated here | follow-up owed — FILES | follow-up #N | none — REASON. The dev writes it once from the diff (os-dev.md L279; spelling, the meaning of updated here and the division of labour on the claim template SKILL.md L313); the seat checks it is present and true, files the owed card and rewrites it to #N before ACCEPT (review-checklist.md L18; SKILL.md L191 names it among the 核对六项); triage writes skills + docs + eval into the first-grade done-when of a card that changes what an author can write (triage-duties.md L59). No gate, script or ledger reads the key. The draft's after-texts for items 2, 3b and 4 were over the 120-byte line limit, so each rule was respelled and one fully-homed line retired per file (see rules_retired); os-dev.md L285 now reads 「声明行后」 (hypothesis 4). The PR is draft with assignee os-warren and label skip-changeset; never readied, armed or enqueued.",
    "tests": "Rule text only under .claude/
    : no package moved, no test suite owed, skills/** untouched (no before/after readings owed). Evidence is the gate union on head 72b08a3 (see gates) plus: ratchet exit 0 with the four files at 319/319, 404/404, 77/77, 103/103 (headroom 0 each); every added or respelled prose line measured at or under 120 B (115, 112, 105, 120, 99, 106; the fenced template line 598 B is exempt by the ratchet's fence class); control-byte self-scan over the four files exit 1 (no hit); git grep -c 'Skills-docs:' -- .claude: os-dev.md 1, SKILL.md 2, review-checklist.md 1. No ablation (no tested behaviour changed).",
    "gates": "Local subset = node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) on head 72b08a3: 25 commands, each run with the exit captured before any pipe, reconciled with --ran: '25 derived famil(ies) accounted for — 25 run, 0 NOT-MEASURED, 0 UNRUN' (exit 0). All 25 exit 0: check:pm-skill-ratchet, check:pm-skill-id-lint, check:skill-frame-sync, check:agent-model-declared, check:agent-test-spelling, check:commit-card-trailers, check:nul-bytes, check:pm-expected-skips, check:pm-governed-merges, check:pm-governed-prose, check:pm-half-states, check:pm-label-write, check:required-contexts, check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, check-governed-queue-guard --self-test, check-harness-current --self-test, check:cross-package-test-inputs, check:doc-authoring, check:driver-memory-census, check:gitlink-declared, check:refd-timer-probe, check:watch-hint-literal, and pnpm --filter @objectstack/lint run check:doc-formula-expressions (first run exit 3 = PREREQUISITE NOT MET, unbuilt @objectstack/formula and @objectstack/lint; closure built under the verify lock, VERDICT command-exit 0, held 107s, waited 0s; re-run exit 0). Outside the derivation, run because the order required it: check:skill-frame-freshness exit 0 ('current with origin/main'). CI on PR #26381: not waited for (in_progress at report time per the order); the seat reads its check-runs.",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "0 — no GitHub MCP tool was called, read or write",
    "api_writes": "2 REST writes, both through scripts/pm/: (1) pr_create via scripts/pm/fleet-write/dispatch.mjs (relay run 40431546837, conclusion success) = POST /repos/objectstack-ai/objectstack/pulls with assignees os-warren and label skip-changeset in the same op, draft forced; relay read-back 13682 bytes sent / 13682 stored, identical; (2) this report via scripts/pm/post-stamped.mjs --comment=26184 = POST /repos//issues/26184/comments. git push -u origin claude/project-thread-1r3slx (one push, not REST). Reads: 4 REST GETs (issue 26184, its comments pages 1–2, pulls?head= read-back).",
    "line_budget": {
    ".claude/skills/pm-dispatch/SKILL.md": {
    "lines": "319 → 319 (ceiling 319, headroom 0)",
    "touched": [
    "L191 114 → 115 B (核对六项: +Skills-docs:, marker 「(席位读此)」 dropped)",
    "L313 251 → 598 B (claim template inside the ```text fence — length-exempt by the ratchet's fence class; not a table row, so no widest-row pin applies)"
    ]
    },
    ".claude/agents/os-dev.md": {
    "lines": "404 → 404 (ceiling 404, headroom 0)",
    "touched": [
    "L279 new, 112 B",
    "old L284 retired, 120 B",
    "L285 108 → 105 B (「两声明行后」 → 「声明行后」)"
    ]
    },
    ".claude/skills/pm-dispatch/references/review-checklist.md": {
    "lines": "77 → 77 (ceiling 77, headroom 0)",
    "touched": [
    "L18 new, 120 B",
    "old L74 retired, 102 B",
    "L75 91 → 99 B (the +0/-0 trigger folded in)"
    ]
    },
    ".claude/skills/pm-dispatch/references/triage-duties.md": {
    "lines": "103 → 103 (ceiling 103, headroom 0)",
    "touched": [
    "L59 new, 106 B",
    "old L96 retired, 115 B"
    ]
    }
    },
    "rules_retired": [
    {
    "file": ".claude/agents/os-dev.md",
    "line": "old L284",
    "text": "受管路径全在 `.claude/` 者 Tier S,达档复核 PASS 在案即由席位入队落地;余皆 Tier H 等人批。",
    "home": "AGENTS.md Prime Directive 14 (Tier S = all of .claude/
    , lands on a `## Contract review` PASS record by the owning seat through the queue; Tier H = an authorized APPROVED review) and Post-Task Checklist step 2 (a governed diff: push, open the PR, stop); seat side in pm-dispatch SKILL.md L183–189"
    },
    {
    "file": ".claude/skills/pm-dispatch/references/review-checklist.md",
    "line": "old L74",
    "text": "`+0/-0` 不是空文件的证明:NUL 字节让 git 当二进制渲染,还让文件对 grep 隐身。",
    "home": "the `+0/-0` trigger moved onto the action line (now L75: 「`+0/-0` 先疑 NUL,以 blob 定论 …」); the harm rationale lives in os-dev.md 〈字节与 sanitizer 纪律〉 (原始 NUL 让 grep 把整文件当二进制; 危害的论证在 scripts/check-nul-bytes.mjs 头部,引用它,别重推) and in that script's header"
    },
    {
    "file": ".claude/skills/pm-dispatch/references/triage-duties.md",
    "line": "old L96",
    "text": "决策形状的卡一律入 `needs-user-decision`,带四棱块与推荐;总监席认领见 `lanes/director.md`。",
    "home": "triage-duties.md L32–34 (needs-user-decision definition; 决策卡速读居四棱块之上), SKILL.md L107 (state table), L270 (决策卡带选项、推荐、证据、四棱块与工作量列), L276 (总监席是唯一呈裁席), filing-gate.md L15 and L27 (落卡即带速读与四棱块; needs-user-decision 入箱,总监席呈批), lanes/director.md L54–55 (入箱勤务)"
    },
    {
    "file": ".claude/skills/pm-dispatch/SKILL.md",
    "line": "L191 (respelled in place)",
    "text": "the reader marker 「(席位读此)」",
    "home": "SKILL.md L188 (the six items sit under the seat's `## 席位核对`) and review-checklist.md L3 (本文逐项展开每份 dev 报告的复核判据)"
    },
    {
    "file": ".claude/agents/os-dev.md",
    "line": "L285 (respelled in place)",
    "text": "「两声明行后」 → 「声明行后」",
    "home": "wording only, no clause lost: a third declaration line exists on the PRs that owe it, so the count was dropped"
    }
    ],
    "deviations": [
    "The draft's after-texts for items 2, 3b and 4 exceeded MAX_LINE_BYTES 120; each rule was respelled in its shortest true form and one fully-homed line retired per file to pay for the new line (allowed by the order; every retirement listed under rules_retired). SKILL.md L191 was fitted in place by dropping the reader marker 「(席位读此)」.",
    "Hypothesis 4 decided: os-dev.md L285 reads 「声明行后」 (「两声明行后」 would be false on the PRs that carry the third line).",
    "The local branch was behind origin/main at worktree creation (a8e7393 → fast-forwarded to 6390fe5 per the order). The single unpushed commit was then rebased once onto origin/main f02e644 before its first push because dispatch-gates flagged a stale tree (1 unrelated file); the branch had never been pushed, so no force-push and no shared history moved.",
    "Thread branch: no empty-branch probe push (os-dev.md rule 1 reserves the probe for self-created branches); the one push carried the commit.",
    "The harness attribution reminder asked for a model-named Co-Authored-By trailer; the model-free pair from AGENTS.md / os-dev.md was written instead. No model name appears in the commit, PR or this report.",
    "The container restarted mid-run; resumed from disk (worktree clean at 6390fe5, scratch files intact, no edits lost); pnpm install --frozen-lockfile re-run because node_modules was partial.",
    "Scratch subdirectory issue-26184/partb/ (nested under the rule's issue-26184/) so the card's Part A agent and this one cannot overwrite each other.",
    "pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3 (PREREQUISITE NOT MET: @objectstack/formula and @objectstack/lint unbuilt); the closure was built under the shared verify lock (slot issue-26184-partb, VERDICT command-exit 0) and the gate re-run, exit 0.",
    "check:skill-frame-freshness ran outside the derived union (local-only gate; the order required it).",
    "This PR carries no Skills-docs: line: kind none and no arm, so none is owed under the ruled trigger; said in Acceptance notes."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · noted, not filed: scripts/pm/check-skill-line-ratchet.mjs prints an opportunistic tighten hint for .claude/skills/spec-property-retirement/SKILL.md's max-table-row-bytes pin (326 → 324, headroom 2); unrelated to this diff; dedupe words: ratchet, table-row pin, spec-property-retirement, headroom, shrink-only"
    ]
    }


    Generated by Claude Code

  11. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 26184,
    "status": "done",
    "branch": "claude/project-thread-1r3slx",
    "pr": "#26381",
    "pr_number": 26381,
    "head": "9dd75f01ae5e2aa75a49c3631f5489b051f6096b",
    "previous_head": "72b08a34cb776a955439fd51dce0227cdea30b01",
    "rework_of": "contract review comment 6431523599 on PR #26381 (VERDICT: FAIL, item b; item a spelling)",
    "files_changed": [
    ".claude/skills/pm-dispatch/SKILL.md",
    ".claude/skills/pm-dispatch/references/triage-duties.md"
    ],
    "session": "session_01LqKsGyMNFwwnbF5FTAqyPn",
    "premise_still_valid": true,
    "summary": "Rework commit 9dd75f0 on the same branch, two lines, zero budget, pushed (no force). (b) SKILL.md L313 (the claim template's Metadata-protocol: line, inside the ```text fence opened at L302 and closed at L319, so exempt from the byte and line ratchet): the draft's 「并带 eval」 clause is restored — updated here = this diff teaches it in `skills/` or the docs and the package's evals exercise it (598 → 634 B). (a) triage-duties.md L59: 「或收窄」 → 「或带 `(narrowing)`」 (106 → 117 B, limit 120), so the kind-`none` + `(narrowing)` card is unmistakably in the first-grade done-when. Line counts unchanged (SKILL.md 319/319, triage-duties.md 103/103; os-dev.md 404 and review-checklist.md 77 untouched). The PR stays draft; never readied, armed or enqueued.",
    "tests": "No test suite owed (rule text under .claude/
    ). Head re-read from the committed blobs at 9dd75f0: SKILL.md 319 lines, L313 634 B with the eval clause present; triage-duties.md 103 lines, L59 117 B; os-dev.md 404, review-checklist.md 77 (not in this commit). git grep -c 'Skills-docs:' on the head: os-dev.md 1, SKILL.md 2, review-checklist.md 1 — the PR body's 两分钟验证 readings are unchanged. Control bytes: check:nul-bytes exit 0 on the head.",
    "gates": "Re-run on head 9dd75f0, after the commit: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) derived the same 25 families; every command run with its exit captured before any pipe; all 25 exit 0; reconciled: ✓ dispatch-gates --ran: 25 derived famil(ies) accounted for — 25 run, 0 NOT-MEASURED (a DERIVED zero — all 25 recorded an exit code and none of them is 3). The one build (closure of @objectstack/formula and @objectstack/lint, prerequisite of check:doc-formula-expressions) ran under the shared verify lock, slot issue-26184-partb: VERDICT command-exit 0, held 1s (turbo cache hit), then the gate exit 0. Pre-commit, on the working tree: check:pm-skill-ratchet, check:pm-skill-id-lint, check:skill-frame-sync, check:skill-frame-freshness, check:nul-bytes all exit 0 (check:skill-frame-freshness is local-only, outside the derivation). CI on the new head: not waited for; the seat reads its check-runs.",
    "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
    "mcp_calls": "0 — no GitHub MCP tool was called, read or write",
    "api_writes": "1 REST write in this rework, through scripts/pm/: this report via scripts/pm/post-stamped.mjs --comment=26184 = POST /repos//issues/26184/comments. git push origin claude/project-thread-1r3slx (one push, not REST). The PR body was not edited (dev writes it once; the seat edits — see pr_body_edits_for_the_seat). Reads: 2 REST GETs (the review comment 6431523599; the comments list for the read-back of this report). Cumulative for the card: 3 REST writes (pr_create, report 6431321367, this report) and 2 pushes.",
    "line_budget": {
    ".claude/skills/pm-dispatch/SKILL.md": {
    "lines": "319 → 319 (ceiling 319, headroom 0)",
    "touched": [
    "L313 598 → 634 B (fenced claim template; exempt — `classifyLine` returns the fence class before the byte test; not a `|` row, so no widest-row pin)"
    ]
    },
    ".claude/skills/pm-dispatch/references/triage-duties.md": {
    "lines": "103 → 103 (ceiling 103, headroom 0)",
    "touched": [
    "L59 106 → 117 B"
    ]
    },
    ".claude/agents/os-dev.md": {
    "lines": "404 (unchanged in this commit)",
    "touched": []
    },
    ".claude/skills/pm-dispatch/references/review-checklist.md": {
    "lines": "77 (unchanged in this commit)",
    "touched": []
    }
    },
    "rules_retired": [],
    "deviations": [
    "Restored clause (review item b): the first landing's SKILL.md L313 had dropped the draft's 「并带 eval」 from the definition of `updated here`; that drop was a lost ruled clause, not a respelling, and it went unreported in report 6431321367 — now restored verbatim in meaning: `updated here` = this diff teaches it in `skills/**` or the docs and the package's evals exercise it.",
    "Respelling (review item a): triage-duties.md L59 「或收窄」 → 「或带 `(narrowing)`」 (117 B), the same spelling as os-dev.md L279, SKILL.md L313 and review-checklist.md L18.",
    "The worktree was lost in a container restart and recreated from the branch (git worktree add on claude/project-thread-1r3slx at 72b08a3 = origin); pnpm install --frozen-lockfile re-run; the shared checkout untouched (detached at 6390fe5).",
    "The branch was not merged with origin/main (now e931621): a merge is owed only on a conflict, a main-caused red or a queue removal, none present; the two commits sit on f02e644.",
    "The build leg of the union held the lock 1s because turbo restored @objectstack/formula and @objectstack/lint from the shared cache; the gate then read the restored dist and passed (exit 0) — a cache hit, reported as such.",
    "Harness attribution reminder asked for a model-named Co-Authored-By; the model-free pair was written again."
    ],
    "pr_body_edits_for_the_seat": [
    "What changes, item 1, L313 bullet: the parenthetical now also says `updated here` requires the package's evals to exercise it (the draft's 「并带 eval」); the byte figure 251 → 598 becomes 251 → 634.",
    "What changes, item 4, L59 bullet: the quoted line now reads 「改作者可写面(种类非 `none` 或带 `(narrowing)`)的卡,首触 done-when 写 skills + docs + eval 三项。」 (117 B).",
    "Verification, byte table: `SKILL.md L313 (fence) 634 B (was 251; exempt)` and `triage-duties.md L59 (new) 117 B`; head line `Head 9dd75f0` (readings from that tree).",
    "两分钟验证: unchanged (ratchet exit 0, four files at headroom 0; Skills-docs: counts os-dev.md 1, SKILL.md 2, review-checklist.md 1)."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · noted, not filed (unchanged from report 6431321367): the ratchet's tighten hint for .claude/skills/spec-property-retirement/SKILL.md's max-table-row-bytes pin (326 → 324, headroom 2); dedupe words: ratchet, table-row pin, spec-property-retirement, headroom, shrink-only"
    ]
    }


    Generated by Claude Code

  12. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #26381 comment 6431794006 · domain:skills#2 · 2026-10-27T01:54Z · Part B (the Skills-docs: line, trigger B) — ⛔ not a claim; the card stays open as the Part A anchor (eight fix cards live).
    Contract review (CONTRACT_REVIEW_TIER): round one FAIL → PR comment 6431523599 on 72b08a34 (the ruled updated here definition had lost its eval clause); rework 9dd75f01 (report 6431681340); round two PASS → PR comment 6431771737. Tier S: the seat readies and arms the PR through the relay on that record. Decision card #26369 (letter B, 6431004737) closes by the seat's hand when the merge lands; 收班简报 carries AGENTS.md PD14 L266 vs L277/L280 and the spec-property-retirement pin hint.


    Generated by Claude Code

  13. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · Part B · domain:skills#2 · session_01LqKsGyMNFwwnbF5FTAqyPn · 2026-10-27T02:04Z

    probe reading
    PR #26381 merged: true at 2026-10-27T02:03:41Z, merge commit b33dd25b
    origin/main git log origin/main carries b33dd25b on 13136f73; SKILL.md:313 reads 「…a kind other than none, or a (narrowing) arm, owes the PR body a third line … Skills-docs: updated here | follow-up owed — FILES | follow-up #N | none — REASON; updated here = this diff teaches it in skills/** or the docs and the package's evals exercise it…」; os-dev.md:279, review-checklist.md:18, triage-duties.md:59 carry the same trigger
    merge queue the PR left the queue by merging

    Landing path: Tier S on the independent ## Contract review (round one FAIL 6431523599 on 72b08a34; rework 9dd75f01; round two PASS 6431771737) and the seat's ACCEPT (6431794006); readied and armed through the relay at 2026-10-27T01:55Z on the maintainer's standing word in the seat thread; the trigger is the maintainer's tap 「B:种类非 none 或带 (narrowing)」 (2026-10-27T00:33Z), the same letter the director seat recorded on #26369.

    State: this card stays OPEN as the Part A anchor (Part of #26184; eight fix cards live: #26295 PR #26385 under the maintainer's hand, #26296 PR #26388, #26179 PR #26393, #26298 PR #26390, #26299 PR #26392 in review or armed, #26297 / #26301 / #26302 queued, #26303 blocked by #26138); pm:dispatched stays until the last child lands. Decision card #26369 is closed by the seat in this act as delivered. The rule is live from b33dd25b: the next protocol-kind or narrowing PR the seat reviews is read for its Skills-docs: line.


    Generated by Claude Code

  14. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: cross-account takeover of claims 6425345339 and 6430787650 (session_01LqKsGyMNFwwnbF5FTAqyPn, os-warren, seat domain:skills#2) · 2026-10-28T03:48Z

    Blocked-by: #26303

    Provenance (three parts): who — the maintainer; verbatim — /pm-dispatch skills seat 2, then, to the seat's confirmation question on taking over seat 2 including its in-flight cards, 「强制接管席位 2,含在飞卡(推荐)」; where — the maintainer's direct cloud session session_01QSeKYmhU5KEj1nukYhp1Tg (2026-10-28), recorded on seat post #19287 (body r68 and its takeover marker).

    State reading at this write: Part B landed (PR #26381 merge b33dd25b, record 6431928957). Part A's nine fix cards: #26295, #26296, #26179, #26298, #26299, #26297, #26301, #26302 CLOSED completed (2026-10-27); #26303 OPEN pm:blocked (the 16.x retirement kits). Nothing on this card itself is left to implement — it is the Part A anchor and closes when its last child lands. That is the pm:blocked state (work complete, waiting on one upstream card), so this act moves pm:dispatched → pm:blocked, writes the Blocked-by: line above for the unlock scan, and clears the assignee; the unlock scan returns it when #26303 closes, and the seat that reads it then closes this card as delivered with the child table. ⛔ Not a reclaim for silence; a takeover under execution-duties 〈认领〉 with the state corrected to what the card is.

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

    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedocumentationImprovements or additions to documentationdomain:skillspm:blockedpriority:p1High: required for production / M2tooling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions