Skip to content

docs(pm-dispatch,os-dev): a PR whose metadata-protocol kind is not none, or whose Clause-② carries (narrowing), owes a Skills-docs line - #26381

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-1r3slx
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-1r3slx

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Part of #26184
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:pm-dispatch 规则文本新增一条 PR 正文声明行 Skills-docs:——元数据协议种类非 none,或 Clause-②: 带 (narrowing) 的 PR,dev 按 diff 写明技能与文档是「已随本 PR 更新 / 欠后续(列文件) / 已有后续卡 / 不欠(写原因)」;席位核对该行、代立后续卡并把它改写成卡号;分诊给会改作者可写面的卡写 skills + docs + eval 三项 done-when。四个 .claude/** 文件各 0 净行;无门禁、无脚本读它。
  • 为什么改:维护者在席位线程的决策卡上选了「B:种类非 none 或带 (narrowing)」;此前协议变了之后没有任何一行要求技能与文档跟上——字段权限 when 落地后技能里一字未提,就是本卡的起因。
  • 风险与回滚:只改四个规则文件,不发布、不改代码、不加门禁;每个新增一行的文件退掉一行,退掉的每一条都在别处有家(见 What changes);回滚 = revert 本 PR 的一个提交。
  • 先看:① .claude/agents/os-dev.md L279(dev 何时写、拼法在哪)与被退掉的 Tier S/H 一行;② .claude/skills/pm-dispatch/references/review-checklist.md L18(缺即 REWORK)与被退掉的 NUL 理由行(其 +0/-0 触发词并入 L75);③ .claude/skills/pm-dispatch/SKILL.md L313 认领模板(取值、updated here 判据、席位改写 #N)。
  • 两分钟验证:pnpm check:pm-skill-ratchet 预期退出 0 且四个文件各印 headroom 0;git grep -c 'Skills-docs:' -- .claude 预期 os-dev.md 1、SKILL.md 2、review-checklist.md 1,别无命中。
  • 需要你做的:无,席位落地。

What changes

The maintainer chose trigger B on the seat thread's decision card (tap label quoted verbatim in the brief above). The content is Part B's draft, comment 6425690779 on #26184, items 1–4, written for B; triage's 「新增门禁默认否」 holds — the line is read by the seat and by triage, by nothing mechanical.

All four files sit at their line ceilings (SKILL.md 319, os-dev.md 404, review-checklist.md 77, triage-duties.md 103; headroom 0), and every prose line is held to 120 bytes. The draft's after-texts for items 2, 3b and 4 were far over that, so each rule is said once in its shortest true form, and where a rule could not fit in place one line was retired in that file — every clause of a retired line already lives elsewhere, named below.

1. .claude/skills/pm-dispatch/SKILL.md (319 → 319)

  • L313, the claim template's Metadata-protocol: line (inside the ```text fence, so length-exempt; 251 → 634 B): the parenthetical now states the trigger (a kind other than none, or a `(narrowing)` arm), the third line's spelling `Skills-docs: updated here | follow-up owed — FILES | follow-up #N | none — REASON`, what `updated here` means (this diff teaches it in `skills/**` or the docs and the package's evals exercise it), and the division of labour (the dev writes it from the diff; the seat files the owed card and rewrites `owed — FILES` to `#N` before ACCEPT).
  • L191, 核对六项 (114 → 115 B): 范围外去向 becomes 范围外去向+Skills-docs:``. To fit, the reader marker 「(席位读此)」 is dropped — L188 already names this block the seat's (## 席位核对), and review-checklist.md L3 says whose checklist it expands.

2. .claude/agents/os-dev.md (404 → 404)

  • +L279 (112 B): 「种类非 none 或带 (narrowing) ⇒ 按 diff 加写 Skills-docs: 行;拼法与分工住认领模板。」 — the dev writes it once, in the PR body, from the diff; never files the card.
  • −old L284 (120 B), the Tier S / Tier H landing summary: every clause is homed in AGENTS.md Prime Directive 14 (Tier S = all of .claude/**, landed by the owning seat on a ## Contract review PASS record; Tier H = an authorized APPROVED review) and Post-Task Checklist step 2 (a governed diff: push, open the PR, stop), and on the seat side in SKILL.md L183–189.
  • L285 (108 → 105 B): 「两声明行后」 → 「声明行后」. A third declaration line now exists on exactly the PRs that owe it, so "after the two" would be false there; "after the declaration lines" is true on every PR.

3. .claude/skills/pm-dispatch/references/review-checklist.md (77 → 77)

  • +L18 (120 B): 「种类非 none 或带 (narrowing):Skills-docs: 行在且属实;follow-up owed 立卡改 #N;缺 ⇒ REWORK。」 — the seat's check, with the verdict word this file uses.
  • −old L74 (102 B), the NUL harm rationale (+0/-0 is no proof of an empty file; NUL makes git render binary and hides the file from grep): its trigger token +0/-0 moves onto the action line (L75, 91 → 99 B, now 「+0/-0 先疑 NUL,以 blob 定论 …」); the rationale itself is homed in os-dev.md 〈字节与 sanitizer 纪律〉 and in the header of scripts/check-nul-bytes.mjs, which os-dev.md names as the authority on the harm argument.

4. .claude/skills/pm-dispatch/references/triage-duties.md (103 → 103)

  • +L59 (117 B): 「改作者可写面(种类非 none 或带 (narrowing))的卡,首触 done-when 写 skills + docs + eval 三项。」
  • −old L96 (115 B), decision-shaped cards go to needs-user-decision with the four-axis block and a recommendation, the director seat claims them: homed in this file's L32–34, SKILL.md L107 (state table), L270 (决策卡带选项、推荐、证据、四棱块) and L276 (总监席是唯一呈裁席), filing-gate.md L15 and L27, and lanes/director.md L54–55 (入箱勤务).

Deliberately not done: no gate, script or ledger reads the new key (scripts/pm/clause2-line.mjs and record-recognisers.mjs still read only Clause-②: and Metadata-protocol:); AGENTS.md is untouched (1112/1112); no back-fill of landed PRs (Part A's eight cards are the back-fill).

Tests

Rule text only, all under .claude/**: no package moves, no test suite is owed, and skills/** is untouched (no before/after readings owed). The surface is held by gates — the local union is the dispatch-gates --commands derivation at head 72b08a34, re-run on the rework head 9dd75f01 (25 derived / 25 run / 0 NOT-MEASURED), every command run with its exit captured before any pipe and reconciled with --ran (25 derived / 25 run / 0 NOT-MEASURED / 0 UNRUN). check:skill-frame-freshness (local-only, outside the derivation) also ran. Dogfood battery: n/a — no ! in the title and no (narrowing) arm.

Acceptance notes

  • This PR does not owe a Skills-docs: line itself: Metadata-protocol: none, no arm.
  • Dispatch hypotheses, measured on origin/main at f02e6443: (1) the draft's line numbers had moved — every target was re-found by its text (SKILL.md L191/L313, os-dev.md L278 as the insertion anchor, review-checklist.md L17, triage-duties.md L58); (2) the separate-line variant's payer (the old three-safe-spellings line) is already gone, so only in-place or retire-to-pay remained; (3) MAX_LINE_BYTES 120 binds; fence lines are exempt (the template line widened in place) and table rows carry their own widest-row pin (none touched); (4) 「声明行后」 chosen, reason above; (5) nothing parses a third line-initial key — keyLineRegex is used only for Reviewed-by, Served-tier, Local-runs; Skills-docs had zero hits repo-wide before this PR; #N is not an issue id for check:pm-skill-id-lint (pattern # + three digits); (6) who does which is on the template line and the seat's checklist line.
  • Branch: the seat container's thread branch, per the claim (the measured platform exception to claude/issue-N-slug). It was behind origin/main at worktree creation and was fast-forwarded; the single commit was then rebased once onto f02e6443 before its first push because the derivation flagged a stale tree — the branch had never been pushed, so no force-push.
  • Commit trailers are the model-free pair; the harness-side attribution reminder asked for a model-named trailer and was not followed, per os-dev.md.
  • Out of scope, noted not filed: the ratchet prints a tighten hint for spec-property-retirement/SKILL.md's table-row pin (326 → 324 headroom 2), unrelated to this diff. carrier: none.

Verification

Head 9dd75f01 (rework commit on 72b08a34: SKILL.md L313 restores the eval clause of updated here, triage-duties.md L59 spells 「或带 (narrowing)」, per the contract review 6431523599); readings below are from that tree, the two reworked lines re-read on it.

Ratchet, id-lint and frame gates — exit 0 each
pnpm check:pm-skill-ratchet :: exit 0
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 319 lines (ceiling 319; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/review-checklist.md is 77 lines (ceiling 77; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/triage-duties.md is 103 lines (ceiling 103; headroom 0).
✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 404 lines (ceiling 404; headroom 0).
pnpm check:pm-skill-id-lint :: exit 0
✓ check-skill-id-lint: 104 file(s) clean (pattern /#[0-9]{3,}/g).
pnpm check:skill-frame-sync :: exit 0
✓ check-skill-frame-sync: the one declared copy of the decision frame is internally coherent (.claude/skills/pm-dispatch/SKILL.md; no second copy to compare — the cross-copy comparison is discharged until a second COPIES entry is declared)
pnpm check:skill-frame-freshness :: exit 0
✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
pnpm check:nul-bytes :: exit 0
check-nul-bytes: OK (scanned 21521 text file(s) -- 21521 tracked, 0 untracked-not-ignored; skipped 102 binary; no raw ASCII control bytes).
grep -naP control-byte self-scan over the four files :: exit 1 (no hit)
Derived union — 25 families, each exit captured before any pipe, reconciled with --ran
pnpm check:pm-skill-ratchet :: exit 0
pnpm check:pm-skill-id-lint :: exit 0
pnpm check:skill-frame-sync :: exit 0
pnpm check:skill-frame-freshness :: exit 0
pnpm check:agent-model-declared :: exit 0
pnpm check:agent-test-spelling :: exit 0
pnpm check:commit-card-trailers :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:pm-expected-skips :: exit 0
pnpm check:pm-governed-merges :: exit 0
pnpm check:pm-governed-prose :: exit 0
pnpm check:pm-half-states :: exit 0
pnpm check:pm-label-write :: exit 0
pnpm check:required-contexts :: exit 0
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0
node scripts/pm/check-harness-current.mjs --self-test :: exit 0
pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:doc-authoring :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:watch-hint-literal :: exit 0
---
Run reconciliation — 25 derived, 25 run, 0 NOT-MEASURED, 0 UNRUN.
✓ 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 (prerequisite of check:doc-formula-expressions), under the shared verify lock
OS_VERIFY_LOCK_SLOT=issue-26184-partb bash scripts/pm/os-verify-lock.sh -c 'NODE_OPTIONS=--max-old-space-size=4096 pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2'
os-verify-lock: VERDICT command-exit 0 · held the lock 107s (1m47s) · waited 0s · ⚠ SHARED-BOX SECONDS — this lock excluded other LOCKED runs, NOT unlocked sibling work (`check:*` gates and the rest), so these are not idle-box figures
pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 (first run exit 3 = PREREQUISITE NOT MET, not measured; re-run after the build)
✓ check:doc-formula-expressions self-test: 61 cases passed
✓ check:doc-formula-expressions: 23 record-scoped formula example(s) across 492 files / 1516 TS blocks judged clean by @objectstack/formula.
✓ check:doc-formula-expressions (spec TSDoc, #6763): 9 @example(s) judged clean across 2210 packages/spec/src files — rls-predicate=8, hook-record-condition=1, record-formula=0; 0 exempt.
✓ check:doc-formula-expressions (field-level `*When`, #11407): 15 predicate(s) on a statically determinable field layer judged clean; 6 skipped as undeterminable.
Byte table of every added or respelled line (limit 120; fence lines exempt)
SKILL.md L191                 115 B  (was 114)
SKILL.md L313 (fence)         634 B  (was 251; exempt)
os-dev.md L279 (new)          112 B
os-dev.md L285                105 B  (was 108)
review-checklist.md L18 (new) 120 B
review-checklist.md L75       99 B   (was 91; the +0/-0 trigger folded in)
triage-duties.md L59 (new)    117 B
retired: os-dev.md old L284 (120 B), review-checklist.md old L74 (102 B), triage-duties.md old L96 (115 B)
Nothing parses the new key
git grep -n 'keyLineRegex(' -- scripts
  scripts/pm/record-recognisers.mjs: Reviewed-by, Served-tier, Local-runs (and the self-test pins of those three)
git grep -n -E 'readMetadataProtocolLine|readClause2Line' -- scripts .github
  scripts/pm/clause2-line.mjs (the one reader), check-adr-0087-registration.mjs, check-changeset-no-major.mjs, post-stamped.mjs — two keys only
git grep -i 'skills-docs' (before this PR) :: no hit
git grep -c 'Skills-docs:' -- .claude (after) :: os-dev.md 1 · SKILL.md 2 · review-checklist.md 1

Generated by Claude Code

…ne, or whose Clause-② carries (narrowing), owes a Skills-docs line

The dev writes `Skills-docs: updated here | follow-up owed — FILES | follow-up #N | none — REASON`
into the PR body from the diff (spelling and division of labour on the claim template); the
seat checks the line is present and true, files the owed card and rewrites it to `#N` before
ACCEPT; triage writes skills + docs + eval into the done-when of a card that changes what an
author can write. No gate or script reads the line.

0 net lines in every file (all four at their ratchet ceiling): one line retired per file that
takes a new one, each retired clause already homed elsewhere; the brief line now reads
「声明行后」 because a third declaration line exists on the PRs that owe it.

Claude-Session: https://claude.ai/code/session_01LqKsGyMNFwwnbF5FTAqyPn
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Reviewed at 2026-10-27T01:33Z — PR #26381 (card #26184, Part B), an independent contract review of the committed tree; inputs were the card body and its ten comments, the PR body, file list and REST diff, the head's check-runs read three times, the cited files on origin/main and on the head via git show, and the ratchet and parser scripts. Nothing was built, run or re-run.

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 72b08a34cb776a955439fd51dce0227cdea30b01
Local-runs: none
Scope: .claude/agents/os-dev.md, .claude/skills/pm-dispatch/SKILL.md, .claude/skills/pm-dispatch/references/review-checklist.md, .claude/skills/pm-dispatch/references/triage-duties.md + AGENTS.md, scripts/check-nul-bytes.mjs, scripts/pm/check-skill-line-ratchet.mjs, scripts/pm/clause2-line.mjs, scripts/pm/record-recognisers.mjs, scripts/pm/check-half-states.mjs, scripts/pm/post-stamped.mjs, scripts/pm/check-governed-merges.mjs, .claude/skills/pm-dispatch/references/filing-gate.md, .claude/skills/pm-dispatch/references/lanes/director.md, .claude/skills/pm-dispatch/references/lanes/skills.md, .claude/skills/pm-dispatch/references/execution-duties.md, .claude/skills/pm-dispatch/references/contract-review.md

Gate verdicts read on the head (the check-runs endpoint, per_page=100). First read at 2026-10-27T01:22Z: 43 runs, 24 success, 18 skipped, 1 in progress (Lint · PM dispatch-gates). Second read at 2026-10-27T01:24Z and third at 2026-10-27T01:30Z: 44 runs, 26 success, 18 skipped, 0 in progress, 0 failure; the run added since the first read is the Lint & Repo Gates aggregate, success at 2026-10-27T01:23Z. TypeScript Type Check success, Lint · repo & tooling gates (the lane that runs check:pm-skill-ratchet and check:pm-skill-id-lint, lint.yml L993 and L1003) success at 2026-10-27T01:21Z, Governed Surface Queue Guard success, Check Changeset success, Part-of PR must not also close its card success. Every run names head 72b08a34.

① Derived judgments

The ruling the text must say. The maintainer tapped 「B:种类非 none 或带 (narrowing)」 on the seat thread's decision card at 2026-10-27T00:33Z: a Metadata-protocol: kind of added, semantic or narrowed, OR a Clause-②: line carrying the (narrowing) arm, owes the line. The content is the Part B draft (comment 6425690779, items 1–4, written for B).

(a) Trigger B, one meaning — right in three files, ambiguous in the fourth. os-dev.md L279 「种类非 none 或带 (narrowing)」, SKILL.md L313 "a kind other than none, or a (narrowing) arm", review-checklist.md L18 「种类非 none 或带 (narrowing)」 all state B exactly, no wider and no narrower. triage-duties.md L59 「改作者可写面(种类非 none 或收窄)的卡」 is ambiguous: in pm-dispatch's own vocabulary 收窄 names the Clause-② narrowing (contract-review.md L8 and L12 「收窄申报」, execution-duties.md L105, lanes/spec.md L20–21), but the kind narrowed is 收窄 in plain Chinese and already sits inside 非 none, so a triage reader can take the parenthesis as redundant and write no skills/docs/eval done-when for a kind-none + (narrowing) card, which is the D5 case the maintainer's B exists for. Tolerable in a first-grade done-when line because review-checklist.md L18 makes the line owed at review time regardless, so the backstop holds; but the unambiguous spelling 「或带 (narrowing)」 fits (106 B → 117 B, limit 120) and should ride the rework below.

(b) The line's values and the division of labour — one ruled clause lost. FAIL. The values (updated here | follow-up owed — FILES | follow-up #N | none — REASON), the dev writing it once from the diff and filing no card (os-dev.md L279, L283 untouched), the seat filing the owed card and rewriting owed — FILES to #N before ACCEPT (SKILL.md L313), and the seat's check 「在且属实;缺 ⇒ REWORK」 (review-checklist.md L18) all match the draft. The definition of updated here does not: the draft's item 3 reads 「updated here 即 diff 触 skills/** 或手写文档并带 eval」; the landed SKILL.md L313 reads "updated here = this diff teaches it in skills/** or the docs" — 「并带 eval」 is gone. Three findings on the head make it a lost clause and not a respelling. One, it was not forced by the budget: L313 sits inside the ```text fence opened at L302 and closed at L319, and classifyLine (ratchet L2698) returns the exempt `fence` class before the byte test, so the clause costs no line and no byte. Two, nothing a seat reads at review time says otherwise: `eval` occurs in pm-dispatch exactly once, triage-duties.md L59, a first-grade done-when written only for a card triage recognises before any PR exists; os-dev.md, review-checklist.md, execution-duties.md 〈复核〉 and lanes/skills.md carry no eval rule; Part A's shared acceptance (comment 6425678185) binds the eight fix cards alone, whose own PRs are kind `none` and owe no line. So a seat applying L18 「属实」 against L313's definition can ACCEPT `Skills-docs: updated here` on a diff that adds one teaching sentence and no eval — the pattern Part A measured (three of sixty protocol commits touched `skills/`, none with an eval). Three, it is unreported: the drop is in neither `deviations` nor `rules_retired` of report 6431321367, and the PR body says the content is "items 1–4, written for B". Remedy (zero budget): on L313, `updated here` = this diff teaches it in `skills/` or the docs and the package's evals exercise it (the draft's 「并带 eval」); if the seat means to drop the eval requirement instead, that is a change to the ruled text and goes back to the maintainer, not into a respelling.

(c) The three retirements are payments. (i) os-dev.md old L284 「受管路径全在 .claude/** 者 Tier S,达档复核 PASS 在案即由席位入队落地;余皆 Tier H 等人批。」: every clause is on the dev's mandatory reading — os-dev.md L19 makes AGENTS.md binding before the first edit, and AGENTS.md Prime Directive 14 L261–262 (Tier S by the owning seat on a contract-tier review of record), L276–283 (Tier H = every register row except .claude/**, an APPROVED review; Tier S = all of .claude/**, the seat lands it through the queue on a ## Contract review PASS record for the current head) and Post-Task Checklist step 2 L1077–1080 (a governed diff: push, open the PR, stop; landing waits for its tier's record) say it; the seat side is SKILL.md L204 and contract-review.md L37. The dev-side consequence (never ready, arm or enqueue) is stated where the dev reads. Paid. (ii) review-checklist.md old L74: the +0/-0 trigger and the action survive on L75 (suspect NUL first, decide on the blob, require escapes on the source side); the grep harm is os-dev.md L391 and check-nul-bytes.mjs header L35–38; the git blind spot (binary-ness decided on the first 8000 bytes) is that header's L43–45, which os-dev.md L393 names as the authority. The seat's own file keeps the operative line and loses only the why, which is one pointer away. Paid. (iii) triage-duties.md old L96: the membership rule is this file's L32–34 and the 「一律」 is L80 (人工地板 恒呈维护者) with SKILL.md L269 (需裁决先落 needs-user-decision 卡); the four-prong block and recommendation are SKILL.md L270, filing-gate.md L15, director.md L54 and lanes/skills.md L21; the director seat as the one presenting seat is SKILL.md L276 and filing-gate.md L27, with the pointer to lanes/director.md at SKILL.md L55 and triage-duties.md L5. Paid.

(d) In-place respellings lose nothing. SKILL.md L191: the six items sit under L188's 「其下 ## 席位核对」 and review-checklist.md L3 names whose checklist expands them, so 「(席位读此)」 was redundant; 「范围外去向+Skills-docs:」 is the draft's 「范围外去向(含 Skills-docs: 行)」. os-dev.md L285 「声明行后」 is true on two-line and three-line PRs where 「两声明行后」 would be false on the latter; L277–278 still say the two claim lines are copied into the PR body and the changeset, which stays right (the third line is written from the diff, PR body only, as the draft says). Right.

(e) Ratchet, byte limit, id-lint. git show 72b08a34:PATH | wc -l: os-dev.md 404, SKILL.md 319, review-checklist.md 77, triage-duties.md 103, equal to CEILINGS (ratchet L1546, L407, L1199, L1307); the four blobs are identical on the merge-base f02e6443, on the PR's base.sha 61c07986 and on origin/main 756220c4, so the counts hold against main too. Touched prose lines measured by wc -c: SKILL.md L191 115 B, os-dev.md L279 112 B and L285 105 B, review-checklist.md L18 120 B and L75 99 B, triage-duties.md L59 106 B — the report's figures; the widest non-fence, non-table line in each file is 120 B. SKILL.md L313 at 598 B is inside the fence: exempt by classifyLine (L2698, before the byte test), counted only under exempt by scanLineLengths (L2719), and the widest-row pin (MAX_TABLE_ROW_BYTES, scanTableRows) meters | rows only, so neither rule reaches it. No # followed by three digits in any added line; #N carries no digit. The gate verdict agrees: Lint · repo & tooling gates success, Lint & Repo Gates success.

(f) No script keys on the new line. clause2-line.mjs reads two key lines only (CLAUSE2_KEY_LINE L145, METADATA_PROTOCOL_KEY_LINE L528) and its near-miss patterns name only those keys; record-recognisers.mjs builds keyLineRegex for Reviewed-by, Served-tier and Local-runs; check-half-states.mjs reads Seat:, Thread-read:, Clause-② (through readClause2Line) and Reviewed-by; post-stamped.mjs refuses a claim on Seat:, Thread-read:, Clause-②: and Container & model: and a record on Local-runs:. None names Skills-docs, none counts line-initial keys, none refuses a third. git grep Skills-docs on origin/main: no hit; on the head: the four rule lines only. The template line is inside the fence of SKILL.md 〈模板与表〉, a file and not a claim comment, so no claim checker sees it, and a claim copies Metadata-protocol: none without the parenthetical. The other readers of the kind line (check-changeset-no-major.mjs, check-adr-0087-registration.mjs, pr-automation.yml) import the same reader.

(g) The PR body dogfoods the current shape. Line 1 Part of #26184 — right: the card carries pm:dispatched, an assignee and eight live Part A children, and comment 6425927987 says it stays open for this landing; the seat closes it by hand after landing (review-checklist.md L12–13) or says it stays open as the anchor. Lines 2–3 are line-initial Clause-②: no and Metadata-protocol: none. 维护者速读 carries the six fixed lines with 需要你做的 = 「无,席位落地」 (Tier S). What changes / Tests / Acceptance notes / Verification are present, the log readings folded. The body's own claim that it owes no Skills-docs: line is correct under B: kind none, no arm. The 两分钟验证 readings reproduce on the head: git grep -c 'Skills-docs:' -- .claude gives os-dev.md 1, SKILL.md 2, review-checklist.md 1, nothing else.

(h) Claim surface and report shape. Claim 6430787650 names exactly the four files; the PR's file list is those four, +7/−7 in one commit. Report 6431321367 carries files_changed (4), deviations (10), line_budget (4 files) and rules_retired (5). Branch claude/project-thread-1r3slx is the claim's branch, the measured platform exception. Base: the PR's base.sha 61c07986 is main's tip when the PR opened at 2026-10-27T01:16Z; the merge-base of origin/main and the head is f02e6443, the report's rebase point; f02e6443 is an ancestor of 61c07986, which is on origin/main, and the four files did not change between them, so the REST diff and git diff f02e6443 72b08a34 are the same +7/−7 (the scratch copy and the REST diff compare identical). The commit carries the model-free trailer pair os-dev.md L283 asks for.

② Semver level

Right. The diff is .claude/** only, which publishes nothing; the PR carries skip-changeset and no .changeset/*.md (execution-duties.md L179 does not bind); Check Changeset is success on the head. Both declaration lines are line-initial on the PR body: Clause-②: no, Metadata-protocol: none.

③ Boundary flags

  • The dev's out-of-scope finding — the ratchet's tighten hint for .claude/skills/spec-property-retirement/SKILL.md's table-row pin (326 → 324, headroom 2) — is a shrink-only pin hygiene reminder: filing-gate.md L18 and L20 keep it out of a card; it goes in the skills lane's 收班简报 and rides the next PR that touches that file. carrier: none.
  • triage-duties.md L59 「或收窄」: respell as 「或带 (narrowing)」 in the rework (fits at 117 B); see (a).
  • AGENTS.md Prime Directive 14 L266 says the listed surfaces are "all Tier H" while L277 and L280 of the same directive say .claude/** is Tier S — a pre-existing contradiction on origin/main, outside this diff; AGENTS.md is Tier H at 1112/1112, so a one-line 收班简报 note for the maintainer, not this PR.
  • Landing to-do for the seat once this lands: Part of leaves 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; close it by hand with the pm:dispatched removal, or record that it stays open as the Part A anchor.

Implemented-by: claude/project-thread-1r3slx (the seat's in-session os-dev subagent, mode:subagent)
Reviewed-by: session_01LqKsGyMNFwwnbF5FTAqyPn (independent contract-review subagent)

VERDICT: FAIL — item (b): the ruled definition of updated here lost its eval clause on SKILL.md L313 (budget-free to restore; unreported as a deviation), so a seat could ACCEPT an eval-less updated here with no rule saying otherwise. Everything else holds; fix (b) and the (a) spelling on the same head and re-review is a re-read of two lines.

…rcise it; the triage done-when trigger spells `(narrowing)`

Rework from the contract review of the previous head, zero budget:

- the claim template's definition of `updated here` (inside the ```text fence,
  so exempt from the byte and line ratchet) had lost the draft's 「并带 eval」
  clause; it now reads "this diff teaches it in `skills/**` or the docs and the
  package's evals exercise it", so a seat cannot ACCEPT an eval-less
  `updated here` under the 「属实」 check;
- triage-duties.md's first-grade done-when line spells the second arm of the
  trigger as `(narrowing)` instead of 收窄 (106 → 117 B), so a kind-`none` card
  whose Clause-② narrows is unmistakably in.

Claude-Session: https://claude.ai/code/session_01LqKsGyMNFwwnbF5FTAqyPn
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Reviewed at 2026-10-27T01:52Z — PR #26381 (card #26184, Part B) on the rework head, an independent contract review of the committed tree; supersedes record 6431523599 (VERDICT: FAIL on the previous head). Inputs: the rework report 6431681340, the PR body as the seat patched it, the file list and REST diff, git diff 72b08a34 9dd75f01 and the blob ids of the four files on both heads, the head's check-runs read three times, and the ratchet script. Nothing was built, run or re-run.

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 9dd75f01ae5e2aa75a49c3631f5489b051f6096b
Local-runs: none
Scope: .claude/agents/os-dev.md, .claude/skills/pm-dispatch/SKILL.md, .claude/skills/pm-dispatch/references/review-checklist.md, .claude/skills/pm-dispatch/references/triage-duties.md + AGENTS.md, scripts/check-nul-bytes.mjs, scripts/pm/check-skill-line-ratchet.mjs, scripts/pm/check-expected-skips.mjs, scripts/pm/clause2-line.mjs, scripts/pm/record-recognisers.mjs, scripts/pm/check-half-states.mjs, scripts/pm/post-stamped.mjs, scripts/pm/check-governed-merges.mjs, .claude/skills/pm-dispatch/references/filing-gate.md, .claude/skills/pm-dispatch/references/lanes/director.md, .claude/skills/pm-dispatch/references/lanes/skills.md, .claude/skills/pm-dispatch/references/execution-duties.md, .claude/skills/pm-dispatch/references/contract-review.md

What moved between the heads. 9dd75f01 is one commit whose parent is 72b08a34 (no force-push; the branch history before it is untouched). git diff 72b08a34 9dd75f01 touches two paths and nothing else in the tree: SKILL.md L313 (one hunk) and triage-duties.md L59 (one hunk), +2/−2. Blob ids: os-dev.md 42d30a3f on both heads (identical), review-checklist.md 38dfb316 on both heads (identical), SKILL.md 4f98f599 → 079cadcb and triage-duties.md c0361838 → 4af797a4, each differing in exactly the one line named. So items (c), (d), (f) and (h) of record 6431523599 carry over by reference: every cited home of the three retirements, the two in-place respellings, the parser readings and the claim surface sit on lines these two hunks do not touch.

Gate verdicts read on the head (the check-runs endpoint, per_page=100). Three reads at 2026-10-27T01:48Z, 2026-10-27T01:49Z and 2026-10-27T01:50Z, all identical: 45 runs, 28 success, 17 skipped, 0 in progress, 0 failure, every run naming head 9dd75f01. Lint & Repo Gates aggregate success at 2026-10-27T01:44Z; Lint · repo & tooling gates (the lane that runs check:pm-skill-ratchet and check:pm-skill-id-lint) success at 2026-10-27T01:43Z; Lint · PM dispatch-gates success; TypeScript Type Check success; Governed Surface Queue Guard success; Test Core and Dogfood Regression Gate success; Part-of PR must not also close its card, No other open PR may claim the same single-writer path and The card this PR closes must claim this branch success on both the push event and the body-edit event. Check Changeset reads skipped on both of this head's runs: that is the listed expected skip in check-expected-skips.mjs (gate: label skip-changeset — every run after the label lands reads skipped; the first head's opened run concluded success before the label was visible). Check PR Size success on the push event and skipped on the edited event (the listed event-gate skip). The remaining skips (Build Core, Build Docs, Build UI Deps, Lint UI, Type Check UI, Temporal Conformance, the matrix shards, the two opt-in harnesses) are the same path- and label-gated set the first head showed.

① Derived judgments

(a) Trigger B, one meaning, now in one spelling. triage-duties.md L59 reads 「改作者可写面(种类非 none 或带 (narrowing))的卡,首触 done-when 写 skills + docs + eval 三项。」 — the same arm spelling as os-dev.md L279, SKILL.md L313 and review-checklist.md L18; a kind-none card whose Clause-② narrows is unmistakably inside the first-grade done-when. Measured by wc -c without the newline: 117 B (limit 120). Right.

(b) The ruled definition of updated here is restored. SKILL.md L313 now reads "updated here = this diff teaches it in skills/** or the docs and the package's evals exercise it" — the draft's 「并带 eval」 (comment 6425690779, item 3) in meaning, placed on the template line that review-checklist.md L18 「属实」 is judged against, so a seat can no longer ACCEPT an eval-less updated here under the rule as written. The rest of the parenthetical (the trigger, the four values, the dev writing it from the diff, the seat filing the owed card and rewriting owed — FILES to #N before ACCEPT) is byte-identical to the first head. The line is 634 B inside the ```text fence opened at L302 and closed at L319; classifyLine returns the exempt `fence` class before the byte test and the widest-row pin meters `|` rows only, so no ratchet rule reaches it. Report 6431681340 names the restoration under `deviations` and `rework_of`, and `rules_retired` is empty — nothing was paid for, nothing was lost. Right; the FAIL item is closed.

(c) The three retirements — unchanged lines on both sides (os-dev.md and review-checklist.md identical blobs; triage-duties.md differs only at L59, so L5, L32–34 and L80 stand as cited); paid, by reference to record 6431523599.

(d) In-place respellings — SKILL.md L191 and os-dev.md L285 are untouched by the rework; right, by reference.

(e) Ratchet, byte limit, id-lint, re-read on this head. git show 9dd75f01:PATH | wc -l: os-dev.md 404, SKILL.md 319, review-checklist.md 77, triage-duties.md 103, equal to CEILINGS. The widest non-fence, non-table line in each of the four files is 120 B; the only line the rework widened past the limit is the fenced L313 (exempt as above). No # followed by three digits in the two added lines; #N carries no digit. git grep -c 'Skills-docs:' -- .claude on the head: os-dev.md 1, SKILL.md 2, review-checklist.md 1, nothing else — the body's 两分钟验证 readings hold. The gate verdict agrees: Lint · repo & tooling gates success, Lint & Repo Gates success.

(f) No script keys on the new line — the rework adds no key and no token a parser names (the two readers of the kind line and the record readers are unchanged on this head); right, by reference.

(g) The PR body matches the head. The seat patched it at 2026-10-27T01:47Z. Lines 1–3 unchanged and line-initial: Part of #26184, Clause-②: no, Metadata-protocol: none. What changes item 1 names the restored clause and reads 251 → 634 B; item 4 quotes the new L59 and reads 117 B; the byte table carries 634 B and 117 B; Verification is headed Head 9dd75f01 with the rework named against record 6431523599; Tests says the union was re-run on 9dd75f01; no stale figure survives (no 598, no 106, no 「或收窄」). The six 维护者速读 lines are present with 需要你做的 = 「无,席位落地」. One wording nit for the seat's final six lines (SKILL.md L194): 风险与回滚 still says 「回滚 = revert 本 PR 的一个提交」 while the PR now carries two commits; the rollback is the squash-merge revert either way, so no defect.

(h) Claim surface and report shape. The file list is still the claim's four files, +7/−7 net against main, now two commits; report 6431681340 carries files_changed (the two reworked files), deviations, line_budget, an empty rules_retired, previous_head and rework_of, and lists the body edits for the seat (which the seat applied). Base: base.sha 61c07986 unchanged; the merge-base with origin/main (now 2163e806) is still f02e6443, and the four files are unchanged between f02e6443 and origin/main, so the REST diff and git diff f02e6443 9dd75f01 are identical (7 hunks, index lines aside) and the PR is mergeable: clean. The rework commit carries the model-free trailer pair os-dev.md L283 asks for.

② Semver level

Right, unchanged: .claude/** only, publishes nothing; skip-changeset present; no .changeset/*.md; Check Changeset skipped on this head is the roster's expected skip for a labelled PR, not a missing verdict. Both declaration lines line-initial on the PR body.

③ Boundary flags

Implemented-by: claude/project-thread-1r3slx (the seat's in-session os-dev subagent, mode:subagent)
Reviewed-by: session_01LqKsGyMNFwwnbF5FTAqyPn (independent contract-review subagent)

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

改了什么:pm-dispatch 规则文本多一条 PR 正文声明行 Skills-docs:——元数据协议种类非 none,或 Clause-②: 带 (narrowing) 的 PR,dev 按 diff 写明技能与文档是「已随本 PR 更新(且该包 eval 覆盖)/ 欠后续(列文件)/ 已有后续卡 / 不欠(写原因)」;席位核对该行、代立后续卡并改写成卡号;分诊给会改作者可写面的卡写 skills + docs + eval 三项 done-when。四个 .claude/** 文件各净 0 行;无门禁、无脚本读它。
为什么改:你在席位线程的决策卡上选了「B:种类非 none 或带 (narrowing)」(director 席在 #26369 记的同一字母);此前协议变了没有一行要求技能与文档跟上,字段权限 when 落地后技能一字未提就是本卡起因。
风险与回滚:只改四个规则文件,不发布、不改代码、不加门禁;每个新增一行的文件退掉一行,退掉的每条都在别处有家(复核员逐条核过);回滚 = revert 本 PR(squash 后一个提交)。
先看:① .claude/agents/os-dev.md L279(dev 何时写、拼法在哪)与退掉的 Tier S/H 一行;② .claude/skills/pm-dispatch/references/review-checklist.md L18(缺即 REWORK);③ .claude/skills/pm-dispatch/SKILL.md L313 认领模板——第一轮复核在这里抓到丢了「并带 eval」子句,返工已补回。
两分钟验证:pnpm check:pm-skill-ratchet 预期退出 0 且四个文件各印 headroom 0;git grep -c 'Skills-docs:' -- .claude 预期 os-dev.md 1、SKILL.md 2、review-checklist.md 1,别无命中。
需要你做的:无,席位落地。
席位意见:同意落地。本 PR 走了两轮:首轮复核 FAIL(模板行把你裁定的「已更新 = 教学 + eval」缩成了只有教学,且未报偏差),返工两行后二轮 PASS;两轮都是天花板档独立复核。

席位核对

ACCEPT · domain:skills#2 · session_01LqKsGyMNFwwnbF5FTAqyPn · 2026-10-27T01:53Z — seat review of record for #26184 Part B on head 9dd75f01, against GitHub, not the report's own account. Governed .claude/** PR, Tier S (check-governed-merges --pr 26381: .claude/** ×4, no Tier H path, 14 changed lines): the record that unlocks landing is the independent ## Contract review at comment 6431771737 (Served-tier: CONTRACT_REVIEW_TIER, head 9dd75f01, VERDICT: PASS, superseding the FAIL record 6431523599 on 72b08a34; drafted by a reviewer other than the implementer, the seat's in-session os-dev subagent). This seat adds the landing read, not a second contract read.

  1. Shape. Draft, base main, mergeable: true (clean), two commits; body line 1 Part of #26184 (the card stays open: eight Part A children live), Clause-②: no, Metadata-protocol: none line-initial; ## 维护者速读 with the six labels in order, then What changes / Tests / Acceptance notes / Verification with folds; the seat patched the body at 2026-10-27T01:47Z to the rework head (L313 634 B, L59 117 B, Head 9dd75f01), read back identical. Files: .claude/agents/os-dev.md, .claude/skills/pm-dispatch/SKILL.md, .claude/skills/pm-dispatch/references/review-checklist.md, .claude/skills/pm-dispatch/references/triage-duties.md — +7/−7 net, exactly the claim's surface (claim 6430787650). Labels documentation, size/s, skip-changeset — right, .claude/** publishes nothing. Branch claude/project-thread-1r3slx (the measured platform exception), named by the claim.
  2. Record, measured. Round one (6431523599, FAIL): the reviewer found SKILL.md L313's definition of updated here had lost the draft's 「并带 eval」 clause, budget-free to restore and unreported; and one ambiguous spelling in triage-duties.md L59. Round two (6431771737, PASS): git diff 72b08a34 9dd75f01 is +2/−2 on those two lines and nothing else (os-dev.md and review-checklist.md blobs identical across the heads), the clause restored in meaning, L59 at 117 B, line counts 404/319/77/103 = CEILINGS, every non-fence line ≤120 B, no parser keys on Skills-docs:, the three retirements paid (AGENTS.md PD14 L261–283 + Post-Task step 2; review-checklist.md L75 + check-nul-bytes.mjs header; triage-duties.md L32–34/L80 + SKILL.md L269–276 + filing-gate.md + lanes/director.md), the PR body consistent with the head. The seat re-read git diff 72b08a34 9dd75f01 and the four blobs and reads the same.
  3. Gates, pinned to head 9dd75f01. 45 check-runs, 28 success and 17 skipped, none red or pending (reviewer's three reads 2026-10-27T01:48Z–2026-10-27T01:50Z; the seat read the same after). Among them Lint & Repo Gates, Lint · repo & tooling gates (ratchet + id-lint), Lint · PM dispatch-gates, TypeScript Type Check, Test Core, Dogfood Regression Gate, Governed Surface Queue Guard, Part-of PR must not also close its card, the single-writer and branch-claim guards; Check Changeset skipped is the listed expected skip for skip-changeset.
  4. Accepted deviations. (a) First landing dropped the eval clause unreported — caught by the record, fixed in the rework, named in report 6431681340 under rework_of/deviations. (b) Branch not merged with origin/main (now abb90460): merge-base f02e6443, the four files unchanged between it and main, mergeable_state: clean. (c) The dev wrote the body once; the seat applied the four body edits the rework report listed. (d) The body's 风险与回滚 says 「一个提交」 while the PR carries two; the squash-merge revert is one commit either way.
  5. Carrier. 收班简报, not filed: AGENTS.md Prime Directive 14 L266 「all Tier H」 contradicts its own L277/L280 (.claude/** Tier S) — pre-existing, Tier H file at ceiling, for the maintainer; the ratchet's tighten hint on spec-property-retirement/SKILL.md's table-row pin (326 → 324) rides the next PR touching that file. Decision card [Decision] pm-dispatch: which PRs owe a Skills-docs: line (the #26184 audit Part B rule draft) — protocol-kind only, protocol-kind plus narrowing, or not adopted #26369 (ruled B by the director seat) closes by this seat's hand with this landing.
  6. Landing. Tier S with a PASS record on the current head and every check green ⇒ the owning seat readies it and arms auto-merge through the relay (pr_ready, then automerge_enable), on the maintainer's standing word in the seat thread (2026-10-26: 「你按照 pm-dispatch 技能审核的pr都可以落地」), follows it to MERGED, and confirms on origin/main. 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 stays open as the Part A anchor; the landing record on it will say so.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 01:55
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 27, 2026 01:55
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit b33dd25 Oct 27, 2026
46 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-1r3slx branch October 27, 2026 02:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants