Repository navigation
Commit 9dae475
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
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
312 | 312 | | |
313 | 313 | | |
314 | 314 | | |
315 | | - | |
| 315 | + | |
316 | 316 | | |
317 | 317 | | |
318 | 318 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
| 67 | + | |
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| |||
0 commit comments