Skip to content

Commit 9dae475

Browse files
pm-dispatch: the claim template spells the ceiling tier by its constant name and cites the --tier MANDATORY path line, never the model id (#21269)
Fixes #21048 Clause-②: no ## What The `Claim:` comment template's `Container & model:` line told every seat to quote this run's `--tier` output into the `model:` slot — and the headline `--tier` prints for a mandated surface is the model id. This repo's `AGENTS.md` (Multi-agent discipline, the 「Commit message」 paragraph) and objectui's `AGENTS.md` (which quotes it verbatim) carry the same rule: no model identifier lands in a comment. So every governed sister-repo claim obeyed one rule by breaking the other — the card's finding. The recogniser half is already on `main` (commit `47849e72`, 2026-09-27): `ceilingTierSpellings()` lists the constant NAME `CONTRACT_REVIEW_TIER` beside the value and the ladder word; `readContainerModelLine` / `containerModelRefusal` read a ceiling spelled by the NAME when the same line carries `MANDATORY` or `reason:`, refuse it bare, and quote no model id back; `post-stamped.mjs` runs that reader before writing a claim. This PR is the **template half only**: two protocol sentences rewritten in place, zero net lines, no code. ### Files (2 lines changed, +2 / −2) | File | What changed | Lines | Bytes on the line | |:--|:--|:--|:--| | `.claude/skills/pm-dispatch/SKILL.md` 〈模板与表〉 | the claim template's `Container & model:` line, rewritten in place: the `model:` placeholder now says — tier word, quoting this run's `--tier` output; the ceiling is spelled `CONTRACT_REVIEW_TIER` and cites, on the same line, the MANDATORY path line `--tier` printed or a `reason:`; never copy the model id | 319 → 319 (ceiling 319) | 118 → 219 — a fenced line, structurally outside the 120-byte cap | | `.claude/skills/pm-dispatch/references/execution-duties.md` 〈认领〉 | the `--tier` sentence, rewritten in place: the tier cites `dispatch-gates --tier --repo REPO` (the sister-repo form included, the same idiom as the file's 门禁清单 sentence), never memory; the ceiling is spelled by its constant name with its citation on the same line; never copy the model id | 183 → 183 (ceiling 183) | 120 → 119 (cap 120) | Not touched: `scripts/pm/dispatch-gates.mjs` (frozen by ruling 208 R6; its half is done and pinned), the 〈升级与决策〉 frame block (`check:skill-frame-sync`), the card's assignee. ### Why one spelling for every repo The triage left it to the claim whether objectstack itself keeps or adopts the model-free spelling. Both `AGENTS.md` files carry the identical comment rule, so there is no repo where the model-id spelling is legal in a claim comment; one spelling keeps the template one line and is exactly what the recogniser already reads. The PM's claim on this card (comment 5942779919) is written in the new shape and passed `post-stamped`'s claim reader before it was posted — a live measurement of the template, not a fixture. ## Verification (tree `30c530e5` = this branch's base; final head `aa492785`) **Premise.** The card's 「Measured」 said no model-free ceiling spelling exists. Falsified on `main`: `ceilingTierSpellings()` returns the constant NAME first (probe below), and the self-test pins it. - `node scripts/pm/dispatch-gates.mjs --self-test` → `✓ dispatch-gates self-test: 1976 cases pass.`, exit 0. The `Container & model` battery (self-test lines ~26007–26020) is green, including: 「the constant NAME and its VALUE are ceiling spellings…」, 「⭐ a ceiling claim quoting the MANDATORY line reads as the ceiling, with its mandate cited, and earns no refusal」, 「⭐ a ceiling claim carrying a per-card `reason:` reads too」, 「⛔ the ceiling by its constant NAME with nothing behind it is refused the same way」, 「the refusal names the ceiling by the constant's NAME and quotes no model identifier back」, 「the default and floor tiers cite nothing and pass」. These are the triage's two pins (model-free spelling passes; no-tier-at-all is still refused) — already landed, none added here. - Direct probe (`node --input-type=module -e` importing `readContainerModelLine` / `containerModelRefusal`): the PM's claim line on this card → `tier: CONTRACT_REVIEW_TIER, ceiling: true, mandateCited: true, refused: false`; the same shape with a sister-repo `--tier --repo objectstack-ai/objectui PATH` citation → ceiling, mandate cited, no refusal; `model: CONTRACT_REVIEW_TIER` with nothing behind it → refused, and the refusal text contains no id-form model name; a default-tier line → no refusal. - `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --tier` on the two paths at `30c530e5`: MANDATORY — `.claude/skills/pm-dispatch/SKILL.md` ⇢ `.claude/skills/pm-dispatch/SKILL.md`, clause ① (the headline of that output carries the model id; the path line is what the template now tells a seat to quote). **Gates.** Derived by `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` (no paths; change set read from the worktree: 2 files, +2/−2) at `30c530e5`: 20 families, identical to the dispatch order's list. Each run in the foreground with its exit code recorded before any pipe; `--ran` reconciliation: `dispatch-gates --ran: 20 derived famil(ies) accounted for — 20 run, 0 NOT-MEASURED (a DERIVED zero — all 20 recorded an exit code and none of them is 3).` — 20 of 20 exit 0. (`pnpm --filter @objectstack/lint run check:doc-formula-expressions` first answered exit 3, PREREQUISITE NOT MET — `@objectstack/formula` and `@objectstack/lint` unbuilt in a fresh worktree; after `turbo run build` for those two packages under the shared verify lock it ran and exited 0.) - `pnpm check:pm-skill-ratchet` exit 0 — `✓ check-skill-line-ratchet: declared cross-file moves: 2, total ceilings down 477 lines.` (SKILL.md 319 at ceiling 319; execution-duties.md 183 at ceiling 183; every non-exempt line ≤ 120 bytes). - `pnpm check:pm-skill-id-lint` exit 0 — `✓ check-skill-id-lint: 34 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 …)`. - `pnpm check:pm-governed-prose` exit 0 — `✓ check-governed-prose: 2 instruction surface(s) name all 6 registered governed surfaces … and claim no others.` - `pnpm check:nul-bytes` exit 0 — `check-nul-bytes: OK (scanned 9923 text file(s) … no raw ASCII control bytes).` - `pnpm check:doc-authoring`, `check:pm-governed-merges`, `check:pm-expected-skips`, `check:gitlink-declared`, `check:refd-timer-probe`, `check:watch-hint-literal`, `check:agent-test-spelling`, `check:cross-package-test-inputs`, `check:driver-memory-census`, `node scripts/check-closing-keyword-parity.mjs` (+ `--self-test`), `node scripts/check-comment-mask-corpus.mjs`, `node scripts/pm/check-governed-queue-guard.mjs --self-test`, `node scripts/pm/check-harness-current.mjs --self-test`: exit 0 each. - Local verification scope: ① none (no workspace package touched); ② none (no package tests or typecheck apply to `.claude/**` markdown); ③ the derived families above. Repo-wide `pnpm lint` is CI's run, not owed here (no `.ts`/`.mjs` touched). - Reverse verification / ablation: not applicable — no code and no test changed; the pins that prove the recogniser live in the frozen file and ran unmodified. ## Acceptance notes - **Boundary, noted not filed.** The default and floor tiers are still spelled by the ladder words `--tier` prints; the recogniser has no model-free equivalent for them and this PR invents none (`dispatch-gates.mjs` is frozen; no new vocabulary). Every sister-repo card under `skills/**` is ceiling by clause ①, so the shape that produced the finding is covered; a default-tier sister-repo claim still carries a ladder word. Carrier: none. - **No third protocol site.** `--tier` is also mentioned in `references/landing-operations.md` (line 9, the suspect-line rule), `references/platform-readings.md` (lines 393–396, quota and sister-tree readings) and `references/lanes/skills.md` (line 18, 「档位从 `--tier` 推导引用」) — none teaches quoting the output into the `model:` slot, so the file surface is the two files named. `post-stamped.mjs`'s `CLAIM_KEY_SPELLINGS` prescription already spells the new shape; `references/contract-review.md` already spells `Served-tier:` by the constant name. - **The `--repo` spelling.** The old sentence hard-coded `--repo objectstack-ai/objectstack`; the new one reads `--repo 仓` (REPO), because the sister-repo route `--tier --repo owner/name PATH…` is the very case the card is about and the file already uses that idiom for `--commands`. - **Changeset.** `.claude/**` publishes nothing → `skip-changeset` (via `label-write`). - **Landing.** Tier S governed surface: this PR stays draft; the owning seat lands it on a `## Contract review` record (`Served-tier: CONTRACT_REVIEW_TIER`, PASS). This dev does not flip ready, queue or arm auto-merge. ## 维护者速读(草稿) ### 改了什么 两句协议文本原地改写:认领评论模板的 `Container & model:` 行(SKILL.md 〈模板与表〉),以及 execution-duties 〈认领〉里「引 `--tier` 输出」那句。天花板档现在写常量名 `CONTRACT_REVIEW_TIER`,同行引 `--tier` 打印的 MANDATORY 路径行或 `reason:`;⛔ 不再把 `--tier` 标题行里的模型 id 抄进评论。行数不变(319/319、183/183),不碰冻结的 `dispatch-gates.mjs`。 ### 为什么改 两条活规则冲突:模板教席位引 `--tier` 输出(含模型 id),而本仓与 objectui 的 AGENTS.md 都禁止评论里出现模型标识,姊妹仓的每条认领都在违反其中一条。识别器半边(接受常量名、要求同行引据、拒收文案不回显 id、`post-stamped` 写前先读)已随早先的 PR 在 main 并有 self-test pin;本 PR 只补模板半边。 ### 风险与代价(含回滚) 纯协议文本,零代码、零发布面,20 个派生门禁本地跑过。已知边界:默认/下限档的档位词仍是 `--tier` 打印的梯度词,识别器无 model-free 等价词,本 PR 不造新词表;姊妹仓 `skills/**` 卡恒为天花板档,实际被覆盖。回滚 = revert 本 commit,无数据、无迁移。 ### 席位意见 (留空,席位定稿) ### 你要做的 无需维护者动作:受管面 Tier S,席位达档复核 PASS 后由席位入队落地。 --- _Generated by [Claude Code](https://claude.ai/code/session_01FNKm1SmPpuJASnbjxWGtsJ)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 4bf4e7e commit 9dae475

2 files changed

Lines changed: 2 additions & 2 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ Worktree: `<repo>-issue-<n>`
312312
Domain: `domain:<x>`
313313
Seat: `domain:<x>#<n>` (the seat number this PM sits on; absent = seat 1)
314314
File surface: `<预期触碰的目录>` (stop on breach; explain in the report)
315-
Container & model: `<S 级机械卡 / M / L>`, `mode:subagent | mode:cloud`, `model: <档位,引当次 --tier 输出>`
315+
Container & model: `<S 级机械卡 / M / L>`, `mode:subagent | mode:cloud`, `model: <档位词,引当次 --tier 输出;天花板拼 CONTRACT_REVIEW_TIER,同行引其 MANDATORY 路径行或 reason:;⛔ 不抄模型 id>`
316316
Clause-②: yes | no
317317
Thread-read: <id of the newest comment on the card at the moment this claim is written, or none>
318318
Serial constraints cleared: `<点名同文件/同包的前驱 PR 与在飞认领,及分诊点名的任意车道在飞兄弟卡中本卡 pin 断言其行为者;无则 none>`

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
- 条款②入队闸门只读认领评论且只读行首键:句中提及与另发评论皆读不到,卡即不可读。
6565
- 谓词保持严格、⛔ 不放宽;session ID 不可省,`mode:subagent` 下 dev 与 PM 同 ID,身份看分支。
6666
- `Clause-②: yes | no` 恰这两种拼写,恒英文机器判据;判据:本卡放宽接受集或扩大公开面吗。
67-
- 引当次 `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --tier <paths>` 输出⛔ 不凭记忆
67+
- 档位引 `dispatch-gates --tier --repo 仓`⛔ 不凭记忆;天花板拼常量名并同行引据,⛔ 不抄模型 id
6868
- 末行 Serial constraints cleared 是落在评论里的读数,同包在飞单不点名等于没查。
6969
- 本卡 pin 断言兄弟卡在改的行为 ⇒ 派发令注明,并在用例内预登记翻转触发词,⛔ 不修绿。
7070
- 家族派发的折叠认领:共享分支按链首卡命名;每张成员卡各留认领评论并点名该分支。

0 commit comments

Comments
 (0)