Skip to content

Commit b33dd25

Browse files
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)
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. <details><summary>Ratchet, id-lint and frame gates — exit 0 each</summary> ```text 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) ``` </details> <details><summary>Derived union — 25 families, each exit captured before any pipe, reconciled with --ran</summary> ```text 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). ``` </details> <details><summary>The one build (prerequisite of check:doc-formula-expressions), under the shared verify lock</summary> ```text 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. ``` </details> <details><summary>Byte table of every added or respelled line (limit 120; fence lines exempt)</summary> ```text 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) ``` </details> <details><summary>Nothing parses the new key</summary> ```text 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 ``` </details> --- _Generated by [Claude Code](https://claude.ai/code/session_01LqKsGyMNFwwnbF5FTAqyPn)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 13136f7 commit b33dd25

4 files changed

Lines changed: 7 additions & 7 deletions

File tree

‎.claude/agents/os-dev.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,13 @@ model: opus
276276
- 红 = 本改动的后果(陈旧 fixture)同 PR 修,余照报;⛔ 永不跳过或收窄;计数记 `dogfood_battery`。
277277
- 认领的 `Clause-②:`、`Metadata-protocol:` 两行照抄进 PR 正文行首;无则零写,⛔ 不自造。
278278
- 两行同抄进 changeset 正文行首;`Check Changeset` 读 PR 正文:kind 即 `minor`,`none` 即 `patch`。
279+
- 种类非 `none` 或带 `(narrowing)` ⇒ 按 diff 加写 `Skills-docs:` 行;拼法与分工住认领模板。
279280
- ⛔ 永不 `Fixes` 一张还在决策箱的卡:合并会静默关掉它,而收件箱过滤只读 open。
280281
- ⛔ 不写否定式的关单句,它照样关掉点名的卡:解析器无视否定,只匹配关键词 + `#<n>`。
281282
- 关键词是 `fix/fixes/fixed/close/closes/closed` 与 `resolve/resolves/resolved`;让它们远离其它卡号。
282283
- 卡片关系只在 PR 正文声明一次:commit ⛔ 不带卡片 trailer,其 trailer pair 一律 model-free。
283284
- harness 归属提醒凭其优先级句让位本文件;harness 自写含模型名 trailer 只报,⛔ 不仿不改史。
284-
- 受管路径全在 `.claude/**` 者 Tier S,达档复核 PASS 在案即由席位入队落地;余皆 Tier H 等人批。
285-
- 两声明行后 `## 维护者速读` 六行,受管与否都带,中文、业务角度,不写席位意见。
285+
- 声明行后 `## 维护者速读` 六行,受管与否都带,中文、业务角度,不写席位意见。
286286
- 六行固定:改了什么/为什么改/风险与回滚/先看/两分钟验证/需要你做的。
287287
- 先看 ≤3 文件按风险排,点名风险 hunk;两分钟验证 = 一条命令或一次点击,写预期所见。
288288
- 需要你做的恰一个动作,非受管面写「无,席位落地」;席位定稿成评论。

‎.claude/skills/pm-dispatch/SKILL.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
188188
- ① 席位记录落 PR 先于 `pr_ready`/入队且钉 head:速读六行+席位意见,其下 `## 席位核对`。
189189
- ② PR 悬着等人批,同笔挂 `needs-user-decision`;人工直合即审核记录,授权批准 ⇒ 席位落地。
190190
- 指针 `ACCEPT → PR #n comment <id>`;技能面 hunk 复核随面定档:席未达档起隔离达档复核。
191-
- 核对六项(席位读此):形态/前提实测/门禁 check-runs/接受的偏差/范围外去向/落地条款。
191+
- 核对六项:形态/前提实测/门禁 check-runs/接受的偏差/范围外去向+`Skills-docs:`/落地条款。
192192
- 速读六行固定:改了什么/为什么改/风险与回滚/先看/两分钟验证/需要你做的。
193193
- 草稿归 dev:每个 PR 正文带 `## 维护者速读` 六行,中文、业务角度,不写席位意见。
194194
- 终稿 = 席位对照自己读的 diff 校正六行、加席位意见行,置顶席位记录;维护者只读评论。
@@ -310,7 +310,7 @@ Seat: `domain:<x>#<n>` (the seat number this PM sits on; absent = seat 1)
310310
File surface: `<预期触碰的目录>` (stop on breach; explain in the report)
311311
Container & model: `<S 级机械卡 / M / L>`, `mode:subagent | mode:cloud | mode:thread`, `model: <档位词,引当次 --tier 输出;天花板拼 CONTRACT_REVIEW_TIER,同行引其 MANDATORY 路径行或 reason:;⛔ 不抄模型 id>`, `effort: <medium | high | xhigh | max,按卡难度定>`
312312
Clause-②: yes | no
313-
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)
313+
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`; `updated here` = this diff teaches it in `skills/**` or the docs and the package's evals exercise it; the seat files the owed card and rewrites `owed — FILES` to `#N` before ACCEPT)
314314
Responsibility: `<whose code produces the risk | the platform path that already covers it, or none | who reaches it, and whether anyone uses it today>` (defect cards only, else `n/a — not a defect card`; the dispatch prompt's ruling section repeats the three answers)
315315
Thread-read: <id of the newest comment on the card at the moment this claim is written, or none>
316316
Premise: holds | corrected <comment id> | inbox (the pre-dispatch premise reading, dispatch-runbook.md 派发前置)

‎.claude/skills/pm-dispatch/references/review-checklist.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
## 范围与 changeset
1616

1717
- 三条判据:无 `content/docs/releases/` 改动、用户可见改动有 changeset、无与卡无关的文件。
18+
- 种类非 `none` 或带 `(narrowing)`:`Skills-docs:` 行在且属实;`follow-up owed` 立卡改 `#N`;缺 ⇒ REWORK。
1819
- changeset/CHANGELOG、`content/docs/**`、`apps/docs/**`:逐句核 diff,ACCEPT 点名所核句,⛔ 不起子代理。
1920
- Tests/docs-only 按仓库分流:本仓库走 `skip-changeset` 标签,⛔ 不走空 changeset。
2021
- 空 changeset 在本仓库滞留发布;含读者可见生成产物时 dev 改选 changeset 亦对。
@@ -71,7 +72,6 @@
7172
- 判据是它报的证据面(搜了什么、找到什么)加 PM 自己在 `origin/main` 上的复核。
7273
- 验收判据本身也可被证伪:dev 用测量推翻字面判据、换上更强的不变量门禁照 ACCEPT。
7374
- 但推翻过程必须写在 PR 正文并附 main 语料上的实测信噪比,否则按 REWORK 要证据。
74-
- `+0/-0` 不是空文件的证明:NUL 字节让 git 当二进制渲染,还让文件对 grep 隐身。
75-
- 先疑 NUL,以 blob 定论 `git show <sha>:<path> | wc -l`,要求源侧写转义序列。
75+
- `+0/-0` 先疑 NUL,以 blob 定论 `git show <sha>:<path> | wc -l`,要求源侧写转义序列。
7676
- 以死代码或不可达为由的删除,PM 先在 `origin/main` 用带引号精确名核引用面,再 ACCEPT。
7777
- 卡的交付物含系统性 sweep 时,ACCEPT 评论把范围外产出成组列出并写明 sweep 判据。

‎.claude/skills/pm-dispatch/references/triage-duties.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
- 父单已有子结构的:父单队列标签即可,分诊逐个展开路由、补 `Blocked-by:` 排序。
5757
- 跨层功能点(≥2 层)立父单带 `area:*`+`pm:epic`+清单项级,逐层子单按 `Blocked-by:` 排。
5858
- 每张留一条英文审计评论(`Triage: lands in …; rationale: …`),可选带 `Size/model suggestion:` 行。
59+
- 改作者可写面(种类非 `none` 或带 `(narrowing)`)的卡,首触 done-when 写 skills + docs + eval 三项。
5960
- 查重/shadow 检查先按文件/机制查本仓与姊妹仓 open 卡(含 `pm:dispatched`),再跟引用与关键词。
6061
- 同文件同机制 = 同一发现,不分车道,首触定级即并:证据搬先卡,后卡关 `duplicate_of`。
6162
- 同族发现并入收口卡,不开单点卡;在飞(assignee/open PR)永不并,`Blocked-by:` 不派;完工查过期。
@@ -93,7 +94,6 @@
9394
- ①只翻 report-only,不删门不跳测;②同笔送待决策汇总入下批,附两红 run;③不同意即翻回。
9495
- 条件:席位验收评论逐条核实、去重计数(候选/落地/已有/拒收)、一事一行、不计重排。
9596
- 机械边界测试(条款②判据):改动扩大接受集或公开面 ⇒ 是;拉回已声明契约 ⇒ 否。
96-
- 决策形状的卡一律入 `needs-user-decision`,带四棱块与推荐;总监席认领见 `lanes/director.md`。
9797
- 轮次报告设呈裁清单专节(卡、推荐、所引权威),⛔ 无代裁清单、无追认表。
9898
- 回翻条款:实施中发现契约终究要动 ⇒ dev 停手,卡回决策箱,⛔ 永不静默重裁。
9999
- 请示纪律:方向性授权覆盖整条执行链一并做完,⛔ 不逐项回问。

0 commit comments

Comments
 (0)