Skip to content

Commit 7e0bfce

Browse files
huangyiireneclaude
andauthored
pm(skills): retire the clause-② gate text — label hang/clear, --pair, double carrier, independence requirement (step ②) (#19694)
Part of #19061 Clause-②: no Step ② of the ruled three-step order on the clause-② contract review (ruling 5770886272, letter B; scope narrowed by the maintainer's word of 2026-09-22, 5772289798: 「降档保险丝 不留」). Step ① landed as PR #19660. Step ③ (the `needs:contract-review` label itself and every script that names it) is a later round and is NOT in this PR — #19061 remains open. ## 维护者速读(草稿) **改了什么**:按裁决 B 的第 ② 步,把技能文本里守「条款②契约复核」的三层机器删掉两层半:`needs:contract-review` 标签的挂与清纪律、`--pair` 入队前检、双载体、以及「独立性对」作为硬性要求;`references/contract-review.md` 的〈载体纪律〉与〈降档保险丝〉两节整节删除(您的原话「降档保险丝 不留」),该文件 60 行缩到 24 行;SKILL.md、core-rules.md、platform-readings.md 各删或修剪对应句子(净减 44 行);`packages/spec` 错误码台账源文件顶部注释里那句话去掉标签名(「登记新码是条款②改动」的表述保留),生成的参考页同步重生成,并附一条 `@objectstack/spec` 的 patch changeset(这段注释随 `.d.ts` 与源码一起发布)。`platform-readings.md` 里「强制档不因临缺授权降档」这条原则按复核要求以独立一行恢复(不再提保险丝)。`scripts/pm/dispatch-gates.mjs` 自检里原来钉住〈降档保险丝〉两句话的两条断言,换成一条「这两句话不得回流」的守卫。留下的只有一条 `## Contract review` 记录作为 Tier S(`.claude/**`)的落地记录,队列守卫继续读它。 **为什么改**:您 9-18 说「不需要 AI 不能自审契约改动 这种」,9-22 批准了 B 方案(三层收成一层):标签、`--pair`、记录三层守的是同一件事,多出来的两层是纯成本;席内达档复核就是 Tier S 的落地方式。 **风险与代价(含回滚)**:规则文本删除加一处自检断言改写,不改任何门禁的判定逻辑;自检在本分支最终 head 上实测 1905/1905 通过。回滚 = revert 本 PR(纯文本加一条自检守卫,无迁移)。仍有六处 `.claude/` 散文与 AGENTS.md 一处仍点名旧机器,列在下文,归步骤 ③。 **席位意见**:技能席 1(`session_01Wnstp2kTth7sGXfr8fXypc`)已按 GitHub 与拉取的 head `c7ea483b8` 复核两轮。第 0 轮记录 FAIL 5773967201 只欠两件:`platform-readings.md` 被删的原则行须以不带保险丝名的独立规则补回(≤120 字节),以及 `@objectstack/spec` 的 patch changeset(docblock 会进发布的 `.d.ts`)。补丁轮 1 恰好只做了这两件——PR 路径上两轮之间的 diff = +6(一行 119 字节的补回行、五行 changeset),`origin/main` 的合并未触及 PR 路径,`dispatch-gates.mjs` 与第 0 轮逐字节相同。本席在独立 worktree 复跑 ratchet(SKILL.md 815/819 · contract-review.md 24/60 · platform-readings.md 468/469 · core-rules.md 151/151)、skill-id-lint、frame-sync、governed-prose、doc-authoring、nul-bytes、三个 changeset 门禁、token ratchet 均 exit 0;第 0 轮头上 1905 例 dispatch-gates 自测 exit 0(脚本两轮未变),本头由本席另起后台复跑。`skip-changeset` 已由本席摘掉,`Check Changeset` 随即跑绿,CI 35 项全绿。复核记录 PASS 5774400593(席内 fable),`--pair` 0,ACCEPT 5774446589 在卡上。登记簿读 Tier S,但裁决 B 写的是 Tier H——以您的裁决为准,PR 留 draft 等您的手;若您要本席按 Tier S 入队,一句话即可。步骤 ③(删标签、队列卫士的标签腿、六处散文残留与指针)另开一轮。 **你要做的**:合并这个 draft PR(受管面,按您定的方式落地)。 ## What this PR does - `.claude/skills/pm-dispatch/references/contract-review.md` (60 → 24 lines): the 〈载体纪律(挂与清)〉 and 〈降档保险丝(机读)〉 sections are deleted whole. 〈复核归属与资格(按面)〉 keeps who renders the record, its shape (`Served-tier:` = the constant name, the head sha, `Implemented-by:`/`Reviewed-by:` as record lines, PASS/FAIL) and the landing pre-check, which is now two items (① the at-tier record on file, ② every check green); the pure-regeneration exception line moves under ①. The title and the pointer line are reworded to what remains. No new sentence was added: the current-head binding of the record is stated by AGENTS.md Prime Directive #14 and enforced by the queue guard, so the moved exception line stands on that. - `.claude/skills/pm-dispatch/SKILL.md` (819 → 815): in 〈入队与落地〉 the bullets that hang the label, run `--pair N` on PR open, park the PR behind the label and point at the retired sections go; the Tier S landing sentence keeps 「PASS ⇒ ready、auto-merge;FAIL ⇒ 补丁轮;⛔ 免复核不放行」. Elsewhere only in-line trims: the label example and the gate-label clause in the label-write rules, the self-review-ban half of the PM tooling exception (the authorization-quote condition stays), the machine-read note on the record lines, the triage 「不挂」 clause, and the dangling 「细则见」 pointer on the subagent-verdict rule. - `references/core-rules.md` (151 → 151): the two mirrored clauses trimmed (自审自合; 闸门标签同此). - `references/platform-readings.md` (469 → 468): the `--pair` proxy reading and the fuse-named rule go; the three readings whose subject was the fuse keep their platform fact (get_session semantics, the minute-wall example). The principle the fuse rule carried comes back as a standalone line without the fuse name (patch round 1, the review's ①(b)): 「强制档不因临缺授权降档:临缺非退役,退役唯维护者裁;不达档起隔离达档子代理或等档。」 (119 bytes, at :393 in the served-tier readings block). The `needs:contract-review` mergeable-state reading at :26 stays this round — it is a reading about a label that still exists until step ③. - `packages/spec/src/api/error-code-ledger.zod.ts` docblock :102: 「Registering a code widens this face and is therefore a Clause-② change, door or no door」 — the label name is gone, the Clause-② statement stays. `content/docs/references/api/error-code-ledger.mdx` regenerated by `gen:docs` (the diff is exactly that sentence). `.changeset/19061-error-code-ledger-docblock-label.md` declares a `patch` for `@objectstack/spec` (patch round 1, the review's ①(e)/②): the docblock ships in the `.d.ts` declaration chunks and the `.zod.ts` source is in the package's `files[]`, so the diff publishes bytes from a released package — `AGENTS.md`'s changeset clause is the stricter one over the comment fast lane. `Clause-②: no` stands (no accept / reject behaviour, no public-surface change). - `scripts/pm/dispatch-gates.mjs` (the coordinator's mid-run increment; the file is a self-test, not a gate's logic): its self-test read `references/contract-review.md` and pinned two sentences of the deleted fuse section in two `t(…)` cases — 「…and its fuse keeps the quota exemption pointed at DISPATCH, never at the review」 and 「…and carries the case it never had: a RETIRED tier is not an exhausted one, and it is a maintainer ruling, ⛔ never a seat's reading」. They are replaced by ONE retirement guard in the file's own pattern — 「the rulebook no longer carries the retired 降档保险丝 lines (maintainer 2026-09-22 「降档保险丝 不留」, #19061 comment 5772289798)」 — which asserts the new truth and reds if the text creeps back; the `fuseRules` read and the `CONTRACT_REVIEW_TIER` case stay as they were. A plain removal of the two cases was made and measured first (1904/1904 on the merged head) but committing it was refused by the harness's action policy as a test removal; the guard form is what landed. ## Inventory — every grep hit on the base (`97f4f8c828`), its disposition and where it lands | base hit | what | disposition | after | |---|---|---|---| | SKILL.md:25 | 自审自合 on the PM tooling exception | TRIMMED (independence half goes; authorization-quote clause stays) | 25 | | SKILL.md:155 | gate-label hang/clear example (`needs:contract-review`) | DELETED (+ :154 gate-label clause trimmed) | — | | SKILL.md:239 | record lines `Implemented-by:`/`Reviewed-by:`, 自审机读可见 | TRIMMED (machine-read note goes; record lines stay) | 238 | | SKILL.md:342 | ⛔ 不挂 `needs:contract-review` (triage) | TRIMMED (label clause goes; 裁定写方向 stays) | 341 | | SKILL.md:536 | 条款②自审资格按车道 (at-tier in-seat / isolated subagent) | KEPT (who renders the record) | 535 | | SKILL.md:635 | skills-lane own PR at-tier 自审 | KEPT (who renders) | 634 | | SKILL.md:656 | label hung by the seat on PR/card | DELETED | — | | SKILL.md:657 | `--pair N` on PR open, C5 | DELETED | — | | SKILL.md:659 | pointer naming 载体纪律 / 降档保险丝 | TRIMMED (pointer reworded to what remains) | 655 | | SKILL.md:773 | director duty title names the label | DEFERRED to step ③ (twin lanes/director.md:27 is off this surface) | 769 | | contract-review.md:3 | pointer: 载体纪律、归属资格与降档保险丝 | REWORDED to what remains | 3 | | contract-review.md:5–:22 | 〈载体纪律(挂与清)〉 | DELETED whole; :21 (pure-regen exception) MOVED | 22 | | contract-review.md:30 | record shape lists 独立性对 | KEPT (shape) | 12 | | contract-review.md:31 | `Served-tier:` = constant name | KEPT (shape) | 13 | | contract-review.md:35 | 独立性件 + 保险丝 ⇒ isolated subagent | DELETED (independence requirement + fuse) | — | | contract-review.md:38 | 独立性对(机读) values | TRIMMED (「(机读)」 goes; record-line values stay) | 19 | | contract-review.md:39 | SELF-REVIEW verdict | DELETED | — | | contract-review.md:40 | 清标即落地 / 剥双载体 | DELETED | — | | contract-review.md:43 | ② 双载体已清 via `--pair N` | DELETED (pre-check renumbered 三条 → 两条, ③ → ②) | — | | contract-review.md:44 | 确定性行 / C5 | DELETED | — | | contract-review.md:48–:60 | 〈降档保险丝(机读)〉 | DELETED whole (maintainer 「不留」) | — | | core-rules.md:23 | 自审自合 mirror | TRIMMED (mirror of SKILL.md:25) | 23 | | core-rules.md:40 | 闸门标签同此 (mirror of SKILL.md:155) | TRIMMED | 40 | | platform-readings.md:26 | label is a merge gate (mergeable reading) | KEPT this round — a reading about the label object; goes at step ③ with the label | 26 | | platform-readings.md:106 | 双载体清标 as a rate-limit example | TRIMMED (example goes; reading stays) | 106 | | platform-readings.md:120 | `--pair` proxy reading | DELETED (its general fact stays at :117–:119) | — | | platform-readings.md:385 | ⛔ 不作保险丝输入 | TRIMMED (fuse clause goes; reading stays) | 384 | | platform-readings.md:386 | ⇒ 保险丝无输入 | TRIMMED (fuse clause goes; reading stays) | 385 | | platform-readings.md:394 | 强制档不得因不可用而降档 (fuse rule) | REPLACED — the fuse-named sentence goes; the principle returns as a standalone line without the fuse name (patch round 1) | 393 | | AGENTS.md:278 | PD#14 `--pair N` / `Served-tier:` | OUTSIDE (not edited; step ③, the maintainer's file) | 278 | | error-code-ledger.zod.ts:102 | docblock names the label | REWORDED (Clause-② statement stays) | 102 | Two non-keyword neighbours were trimmed with their hits because they are the same discipline: SKILL.md:154's 「闸门标签被剥不是红灯是放行」 and SKILL.md:76's dangling pointer 「细则见 references/contract-review.md」 (the details it pointed at were the fuse's subagent-adoption lines). ## Line budget (ratchet ceilings untouched; every file at or under) | file | before | after | ceiling | |---|---|---|---| | `.claude/skills/pm-dispatch/SKILL.md` | 819 | 815 | 819 | | `references/contract-review.md` | 60 | 24 | 60 | | `references/core-rules.md` | 151 | 151 | 151 | | `references/platform-readings.md` | 469 | 468 | 469 | | `packages/spec/src/api/error-code-ledger.zod.ts` | 1679 | 1678 | — | | `scripts/pm/dispatch-gates.mjs` | +4 / −4 (comment lines and the one guard) | | — | | `.changeset/19061-error-code-ledger-docblock-label.md` | — | new, 6 lines (`@objectstack/spec`: patch) | — | Diff against `origin/main` (`7e1b048`, merged in at patch round 1; head `c7ea483`): 8 files, +32 / −70. ## File-surface increments beyond the claim (declared) 1. `content/docs/references/api/error-code-ledger.mdx` — the generated reference page carried the sentence; regenerated by `pnpm --filter @objectstack/spec gen:docs`, `check:docs` and `check:generated` (15/15) green. 2. `scripts/pm/dispatch-gates.mjs` — the two fuse-pin cases of its self-test, replaced by one retirement guard (described above). PR #19684 (#19680) landed on `main` and edited the same file in a different region; it is merged in. ## Verification (final head `c7ea483`, patch round 1) - Derivation: `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` (no paths; the changed set read from the merge-base) → 132 families (the changeset gates joined: `check-empty-changeset` `--base` and `--self-test`, `check:objectui-changeset`, `check:pm-changeset-deadline-census`, `release-rehearsal-clone --self-test`). Reconciliation with `--ran`: 132 derived, 129 run, 3 NOT-MEASURED, 0 UNRUN. Every exit captured before any pipe. - The 3 NOT-MEASURED, each a prerequisite refusal (exit 3), none touched by this diff: `pnpm --filter @objectstack/spec run check:skill-examples` (reads `packages/client-react/dist`, not built), `pnpm check:dual-build-cjs-loads` (needs every package's dist), `pnpm check:lean-entry-closure` (needs `packages/objectql/dist`). A whole-repo build is CI's run, not this docblock-only spec change's. - `pnpm check:pm-dispatch-gates` at `c7ea483`, run detached with the exit recorded: exit 0, 「✓ dispatch-gates self-test: 1905 cases pass」, 709.7 s; the retirement guard and the 「spells NO model id」 walk over the 28 rulebook files (which read the restored line) are among them. Without the script change the same gate read 「✗ dispatch-gates self-test: 2 of 1904 case(s) failed」, exit 1 — the expected direction for prose a self-test had pinned. - Changeset gates at this head, all exit 0: `check-changeset-no-major --base origin/main` 「✓ This diff introduces no `major` bump.」; `check-adr-0087-registration --base origin/main` 「this PR adds no declared-breaking changeset (1 non-breaking changeset(s) seen)」; `check-empty-changeset --base origin/main` 「No empty-frontmatter changeset introduced by this diff (1 declaring changeset(s) added)」 and 「No changeset from the merge base modified or deleted」; `check-empty-changeset --self-test` (159 assertions); `check:changeset-gate-self-tests`; `check:pm-changeset-deadline-census`; `check:objectui-changeset`. - Named gates, all exit 0 at this head: `check:pm-skill-ratchet` (SKILL.md 815 / 819, contract-review.md 24 / 60, platform-readings.md 468 / 469, core-rules.md 151 / 151; every line within the 120-byte cap), `check:pm-skill-id-lint` (30 files clean), `check:skill-frame-sync`, `check:pm-governed-prose`, `check:doc-authoring`, `check:nul-bytes` (plus a direct grep of the seven changed files for the wider control-byte class: no match), `check-skills-token-ratchet` (34 files within ceilings), `check-skill-frame-freshness`, `check:pm-clause2-carriers` (1140), `check-governed-queue-guard --self-test` (312), `check:pm-half-states` (5160), `check:pm-expected-skips`, `check-published-list-mirrors`, `check-self-test-wired`, `check-scripts-symbol-anchors`, `check-declaration-mirrors`. - `packages/spec`: `build` exit 0 (four times — base and after each of the three `origin/main` merges); `gen:docs`; `check:docs`; `check:generated` 「All 15 generated artifacts are up to date」 (at `c7ea483` too); `typecheck` exit 0 and `vitest run src/api/error-code-ledger.test.ts` 20/20 at `c7ea483` (declared narrowing: the diff in this package is a comment plus a changeset; the whole suite is CI's). - eslint narrowing: `pnpm exec eslint --no-inline-config --format json` over the two lintable changed files (`error-code-ledger.zod.ts`, `dispatch-gates.mjs`): exit 0, 2 judged, 0 errors, 0 warnings. Population: `eslint.config.mjs:971` (`**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}`); invariance: `eslint.config.mjs:327–:329` — type-aware linting is never enabled, so no untouched file's verdict can move because of this diff. - `node scripts/pm/check-governed-merges.mjs --pr 19694`: GOVERNED — Tier S (4 of 6 paths hit the register, all under `.claude/**`; no Tier H path), 88 changed lines at that reading, under the human-merge threshold. ## Changeset — measured, not assumed The dispatch's assumption 「the docblock sentence changes no emitted dist byte」 is FALSIFIED on the dist half: the file-level docblock of `error-code-ledger.zod.ts` IS emitted into the declaration bundle. Base build vs post-edit build of `packages/spec/dist` (216 files each): 12 differ — the two `.d.ts`/`.d.mts` chunks that carry the docblock (`automation-api.zod-*`, renamed by content hash), the four entry `.d.ts` files that import them, four sourcemaps (line shift) and the two build-input stamps. Runtime `.js`/`.mjs`/`.cjs`: 0 differ. `needs:contract-review` in dist after: 0 hits (base: 2). `files[]` of `@objectstack/spec` also ships `src/**/*.zod.ts`, so the source comment ships too. So the diff publishes bytes from a released package and takes a `patch` changeset for `@objectstack/spec` (added in patch round 1 on the review's word; `AGENTS.md`'s clause is the stricter one over the comment fast lane). The `skip-changeset` label applied at round 0 is the wrong carrier and the seat removes it at the landing act; this dev did not touch it. ## Acceptance notes — riders off this surface (not filed; prose drift is outside the fileable classes) - Six `.claude/` prose sites still name the retired machinery and are off this step's claimed surface: `.claude/agents/os-dev.md:303` (the label + `--pair PR-NUMBER` reading), `references/dispatch-runbook.md:161` (独立性件), `references/lanes/director.md:27` (duty title names the label) and `:35` (pointer to 载体纪律), `references/lanes/ui.md:38` (独立性件与降档保险丝), `references/state-machine.md:10` (the label's card-side hang). Carrier: step ③ of #19061 (the label), or a sub-issue of it. - `references/lanes/director.md:33` points at 「`../contract-review.md` 落地前检③」; after the renumbering here that item is ②. Same carrier. - `scripts/pm/dispatch-gates.mjs` docblock line 「Rule text: `references/contract-review.md` 「降档保险丝」」 (near the `CONTRACT_REVIEW_TIER` constant) names a section that no longer exists; outside the two cases this PR was allowed to touch — step ③'s territory. - `AGENTS.md:278` (Prime Directive #14) still names `check-clause2-carriers.mjs --pair N` and the label — Tier H, the maintainer's own edit at step ③. - The `--template` pointers kept in `contract-review.md` :13 and :19 point at `check-clause2-carriers.mjs --template`; step ③ decides that file's fate. - The derivation did not list `check:pm-dispatch-gates` for a diff touching only `references/contract-review.md`, although that gate reads the file at runtime; it appeared once `dispatch-gates.mjs` itself was in the diff. --- _Generated by [Claude Code](https://claude.ai/code/session_01Wnstp2kTth7sGXfr8fXypc)_ --- _Generated by [Claude Code](https://claude.ai/code)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent fb7b746 commit 7e0bfce

8 files changed

Lines changed: 32 additions & 70 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
The error-code ledger's file docblock (`src/api/error-code-ledger.zod.ts`, shipped in the `.d.ts` declaration bundle and in the package's `src/**/*.zod.ts`) no longer names a retired PM-process label. The sentence now reads: registering a code widens the published contract face and is therefore a Clause-② change, door or no door; a code present in `dist` and absent from the ledger is a protocol gap, not a tier question. Documentation only — no code, type, value or export moves, and the generated reference page follows the source (#19061).

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

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
2222
## 红线
2323

2424
- ⛔ PM 永不写代码、不写文件;唯一例外是维护者逐 PR 明示授权的 `.claude/` 内部工具 PR。
25-
- ⛔ 该例外的 PR 不得自审自合:授权原话引在正文,复核由另一座位或维护者做。
25+
- 该例外的 PR 授权原话引在正文。
2626
- ⛔ 永不以任一账号对受管面 PR 提交批准 review,永不合并受管面 PR。
2727
- ⛔ 受管面 PR 无授权批准时永不翻 ready、入队或挂 auto-merge;批准在案后席位落地。
2828
- ⛔ 永不合自己的 PR,永不合红的或未复核的 PR,永不绕过合并队列。
@@ -73,7 +73,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
7373
- 探针先行:fire 的第一动作是一次最便宜的车道盘点查询,⛔ 在它之前不读任何长文本。
7474
- 队列空 + 无在飞 + 无待复核 + 决策箱无新答复 ⇒ 自退。
7575
- 分诊席跑普通直连会话、默认判断档;裁决不在本席,归维护者召唤的总监席。
76-
- 子代理裁决逐份过转录核验采信,细则见 `references/contract-review.md`。
76+
- 子代理裁决逐份过转录核验采信。
7777
- 开轮互斥:fire 开始、首个写动作之前读四个读数,未收班活动任一未满一轮 ⇒ 自退。
7878
- 读数一、二:最近的收班简报,与晚于它的最新开轮标记。
7979
- 开轮标记是轮中会话在座位贴上的唯一痕迹;标记可漏写,认领不可省。
@@ -151,8 +151,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
151151
- P0 嫌疑的等待走紧急直接分诊通道,是义务不是选项。
152152
- 代执行他人指令的关闭、摘标、回收认领,评论带出处三件:谁的指令、原话、在哪说。
153153
- 标签写恒四步:取现集 → 只增删目标 → 写合并集 → 回读 diff 对 union(现集, 增删)。
154-
- union 有而回读缺 = 被并发剥掉,重挂并报告;闸门标签被剥不是红灯是放行。
155-
- 承载闸门语义的标签(如 `needs:contract-review`)挂与清两向同此四步。
154+
- union 有而回读缺 = 被并发剥掉,重挂并报告。
156155
- 多席可写面恒读回;API 200 不等于落地正确。
157156
- PM 写进 GitHub 的文本 ⛔ 不用尖括号路径占位符,改写成后跟显式路径的说法。
158157
- 携带易损片段的评论(派发令与裁决)post 后读回;写侧形状见 `references/platform-readings.md`。
@@ -236,7 +235,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
236235
- 代扫在分诊座位有主时立即停止。
237236
- 规则 5:一块板不设第二跟踪器:pm 标签就是状态机,org Project 只是维护者的聚合视图。
238237
- 认领即跟到 MERGED:派发后发现的跨车道面(含 spec)不移卡,认领席借契约复审档隔离复核。
239-
- 复核记录带 `Implemented-by:`/`Reviewed-by:`,自审机读可见;`pm:retriage` 改路由只对未派发卡。
238+
- 复核记录带 `Implemented-by:`/`Reviewed-by:`;`pm:retriage` 改路由只对未派发卡。
240239
- 转移落对方队列:目标仓立单带 `pm:queue`、出处行与一行可执行判据,依赖用 `Blocked-by:`。
241240
- 跨座位请求骑在它所关的既有卡上:请求席在自卡写 `Blocked-by:`,并在目标卡留一条评论。
242241
- 该评论点名席位与步骤;无既有卡承载且请求自身即立卡门 ①②④ 时才立新卡。
@@ -339,7 +338,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
339338
- 见新 tag 族发布 ⇒ 在 cloud 立 `.objectstack-sha` bump 单。
340339
- bump 单单张封顶:先查同题 open 单,已有就追评刷新;工具链新形态只提请不扩面。
341340
- 分类动作每张三选一,外加一个修复通道。
342-
- ⛔ 不挂 `needs:contract-review`:随 draft PR 或 `Clause-②: yes` 认领;裁定写方向、给六态之一。
341+
- 裁定写方向、给六态之一。
343342
- 方向在 ADR/本卡裁决/不可重裁规则:贴 `check-prior-rulings.mjs` 的 `Prior rulings read:` 行,或不点。
344343
- `pm:queue` = 有具名落点或复现的具体缺陷,无可问之事;⛔ 工具/门禁修复不由此进。
345344
- `tooling` 入 `pm:queue` 仅当首行带 `Unblocks: #N`(open 产品卡)或点名所护的已发布面。
@@ -650,13 +649,10 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
650649
- 声明肢 = 认领评论声明 `Clause-②: yes`,与路径无关;错误的 `no` 是可审计的假申报。
651650
- 交付后复核按面欠 ⛔ 不按车道(五面见 `references/contract-review.md`);双肢命中即 spec 车道。
652651
- 子代理起不来 ⇒ 复核缺席,PR 留 draft 队列外等档;唯一旁路是维护者亲审,逐次为准。
653-
- PASS ⇒ 同席剥标并引记录、ready、auto-merge;FAIL ⇒ 补丁轮;⛔ 免复核不放行。
652+
- PASS ⇒ ready、auto-merge;FAIL ⇒ 补丁轮;⛔ 免复核不放行。
654653
- 真正设计分叉照旧进决策箱,席内复核 ⛔ 不替代维护者裁定。
655654
- 外部评审链降为可选事后审计,非放行前提。
656-
- `needs:contract-review`(恒英文)由席位同笔挂:PR 一现即挂 PR;报告先到则先挂卡。
657-
- `Clause-②: yes` 认领同笔卡上挂标;开 PR 跑 `--pair N`:只确定性行红才挡请审,C5 只印读数。
658-
- 挂标后复核完成前短暂停靠;⛔ 不前瞻预挂。
659-
- 契约复核的适用面、载体纪律、资格与归属、降档保险丝见 `references/contract-review.md`。
655+
- 契约复核的适用面、资格与归属见 `references/contract-review.md`。
660656
- 碰生成物的 PR 入队前先同步 + 整体重生成:四步序 `bash scripts/pm/os-regen-merge.sh`。
661657
- 跟到 MERGED 为止,入队后的看护归车道 PM 的落地窗口:每轮同时读队列分支与 `origin/main`。
662658
- 默认分支 push 即触发对外部署的仓,只在验证层存在时才合并;无验证层 ⛔ 不合并。
Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
1-
# 契约复核细则(按车道)
1+
# 契约复核细则(按面)
22

3-
见 SKILL.md 〈入队与落地〉的条款②闸门;本文只放载体纪律、归属资格与降档保险丝。
4-
5-
## 载体纪律(挂与清)
6-
7-
- 内容肢及于 published `skills/**`:作可证伪的算子或契约语义主张的改动挂标走本复核。
8-
- ⛔ 判据不是提到契约:纯算子清单、拼写、格式不触发。
9-
- `Clause-②: yes | no` 按设计临时:只定是否必过达档契约复核的保守方向,⛔ 非终审。
10-
- 删误拒的 `Clause-②: no` 附 `Contract-text:` 引已发布契约文本,双载体同载;缺引即缺申报。
11-
- 真闸门在 PR 或报告时点的达档复核;声明被复核推翻 ⛔ 不作席位过失。
12-
- 机械地板 claim 时可查树:新导出符号或已发布载荷上的新键恒 `yes`,锁达档契约复核。
13-
- conformance 类 ⛔ 不机械化:填充已声明字段、在两个已发布码之间重选输入类都需判断。
14-
- claim 拿不准 ⇒ 按 `yes` 挂标走达档契约复核;⛔ 不建全量分类学与 claim 时决策程序。
15-
- 同笔在卡上记一行条款②认定,PR 侧 ACCEPT 补齐;停靠只防误入队,⛔ 无无限期等外席态。
16-
- 前瞻的条款②事实住卡上裁决与分诊评论、`Clause-②` 申报和 `--tier` 输出。
17-
- 开着的载体恒 = 真实待审;载体不迁移:⛔ 不迁 PR review 或 Request Changes,⛔ 不为迁移留门。
18-
- FAIL 同 PASS 剥双载体:同笔留卡上交接评论(引复审、独立性对、欠改);卡态与 assignee 不动。
19-
- 重挂前先查裁决:闸门标签缺失 ⇒ 先 grep 卡评论找复审结论;`get_reviews` 读空 ≠ 未复审。
20-
- PASS + 无标 + head 未动 = 已清标不是被剥;head 后移或无结论才重挂;清标缺引记录即半态。
21-
- 例外:纯重生成 head 后移原记录继续管;判据机读已提交树;PR 落 `Regen-provenance:` 行。
3+
见 SKILL.md 〈入队与落地〉的条款②闸门;本文只放复核归属与资格。
224

235
## 复核归属与资格(按面)
246

@@ -32,29 +14,11 @@
3214
- ① derived judgments 逐项:diff 引出的接受集与公开面变化逐条点名判对错。
3315
- ② semver 定级与 changeset 声明一致;③ 边界旗:dev 挂旗与 `open_questions` 逐旗答复或升级。
3416
- 复核形状:只读 diff 与卡片,check 结论取 head 的 check-runs,⛔ 永不本地重跑派生门禁族。
35-
- 独立性件(契约真分叉、dev 挂旗)与保险丝只免席内审,不免复核:起隔离达档子代理。
3617
- 只喂卡片、既有裁决与 PR 本体,⛔ 不喂派发令与派发席自己的结论;简报写成对抗性。
3718
- 隔离复核子代理暂存全写按所审 PR 命名的 `<scratchpad>/pr-<n>/`,⛔ 不读非本轮自写的暂存。
38-
- 独立性对(机读):`Implemented-by:`/`Reviewed-by:` 取值见 `--template`;子代理记采纳它的席位。
39-
- 两者同 session ⇒ 报 SELF-REVIEW;只 `mode:remote` 可达,`mode:subagent` 席内审是设计;值紧跟冒号。
40-
- 清标即落地:PASS ⇒ 同席同笔剥双载体;清标同笔落 PR provenance 评论,引记录 id 与所判 head。
19+
- 独立性对:`Implemented-by:`/`Reviewed-by:` 取值见 `--template`;子代理记采纳它的席位。
4120
- 轮次报告设复审清单专节,形状与代裁清单同为强制审计。
42-
- 落地前检三条,过则 Tier S 入队、Tier H 等人批:① 达档条款②复核 PASS 在案(同形记录)。
43-
- ② 双载体已清,逐对机读 `PM_SWEEP_REPO=仓 node scripts/pm/check-clause2-carriers.mjs --pair N`。
44-
- 确定性行 = 记录在案、`Served-tier:`、双载体一致、认领形;C5 放宽 tell 只报告,归复核裁。
45-
- ③ PR check 全绿,⛔ 非 required 子集;例外:merge-base 同签名的红不计、按设计而红见 SKILL.md。
21+
- 落地前检两条,过则 Tier S 入队、Tier H 等人批:① 达档条款②复核 PASS 在案(同形记录)。
22+
- 例外:纯重生成 head 后移原记录继续管;判据机读已提交树;PR 落 `Regen-provenance:` 行。
23+
- ② PR check 全绿,⛔ 非 required 子集;例外:merge-base 同签名的红不计、按设计而红见 SKILL.md。
4624
- 签名 = 失败步 + 首错行,读 base check runs 的 API ⛔ 不凭口述;主干红止血立单不变。
47-
48-
## 降档保险丝(机读)
49-
50-
- 保险丝只管 spec 与 skills 席的条款②复核:每场前必读服役档(`platform-readings.md`)。
51-
- 总监席裁决非达档裁决,⛔ 不受本丝;总监席档位由维护者逐场定。
52-
- ⛔ 自述档位与传参皆非读数;条款②的 `mode:subagent` 派发恒保留标至达档复核完成。
53-
- 读数不达档 ⇒ 改走转录核验达档复核子代理;起不来即无复核,标签原样、队列外等档。
54-
- 子代理档只取其转录 harness 逐请求 `model` 盖章;`get_session` 量的是派发会话,⛔ 不作互证。
55-
- 清标前 `--pair`:`Served-tier:` ≠ 常量名 ⇒ exit 4,点名 PR、评论、读数;型号串按 `AGENTS.md` 拒。
56-
- 施工档只取 harness `model` 盖章或认领 Container & model 行;`Co-Authored-By` = 署名常量 ⛔ 非证据。
57-
- 产出裁决的每轮都须读到契约复审档位,见回退证据 ⇒ 裁决整体作废。
58-
- 父会话只可逐字采纳或整体作废(核验失败、越范围、格式不完整),⛔ 永不改写润色。
59-
- PASS、FAIL 与作废都落 PR 或卡;同 head 再起子代理须引前次作废因,⛔ 不重起求 PASS。
60-
- 额度耗尽豁免只及派发 ⛔ 不及复核;档位退役 ≠ 耗尽,恒维护者裁决 ⛔ 非席位读数。

‎.claude/skills/pm-dispatch/references/core-rules.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
## 全体座位的不变量
2121
- 状态住 GitHub 标签、assignee、正文行与座位贴;⛔ 本地零状态;循环须能从新会话恢复。
2222
- PM ⛔ 不写文件也不写代码,唯一例外是维护者逐 PR 明示授权的 `.claude/` 内部工具 PR。
23-
- 该例外须把授权原话引在 PR 正文并由另一座位或维护者复核,⛔ 不得自审自合。
23+
- 该例外须把授权原话引在 PR 正文。
2424
- 用户账号仅三用:assignee、授权批准、维护者亲手;写只走 REST 代理,署名随令牌非席位。
2525
- GitHub 新内容一律英文,中文只留轮次报告、派发令裁决引文与四维分析;引文照抄不译。
2626
- 存量中文 ⛔ 不追溯改写;一 PM 一车道、一车道多席、一席一贴;与 AGENTS.md 冲突以之为准。
@@ -37,7 +37,7 @@
3737
- 五个 pm 状态标签加 `needs-user-decision` 共六态互斥,转换恒一笔 replace,队列卡逾三天欠转换。
3838
- 关闭即在同一笔摘掉 pm 状态标;状态变更不过夜,半状态在结束会话前补齐或回滚。
3939
- 等待别的座位也是状态、写在卡上才存在;代他人指令的关闭须带指令、原话与出处三件。
40-
- 标签写恒为读现值、增删目标、写合并集、回读比对四步,缺项即重挂,闸门标签同此。
40+
- 标签写恒为读现值、增删目标、写合并集、回读比对四步,缺项即重挂。
4141
## 平台读数纪律
4242
- 判据取命令输出,⛔ 不取 API 字段字面值、不取本地工作树、不取看着相邻的日志。
4343
- 核验 main 用 fetch 后的 `origin/main`,⛔ 不用共享检出树;仓不可达 ⛔ 不当查过且干净。

‎.claude/skills/pm-dispatch/references/platform-readings.md‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
- 只要 `totalCount` 的健康指标取 perPage=1;只要最近 N 张就取 N。
104104
- 小时池之外还有分钟级二级限流:GraphQL 端点 2,000 点/分、并发 ≤100。
105105
- 官方指引:变更类请求间停 ~1 秒,mutation 按 5 倍计;批量写因此 ~1 秒一发。
106-
- 双载体清标、批量重分诊这类把写挤在同一秒的扫动,会在小时池仍绿时撞上分钟墙。
106+
- 批量重分诊这类把写挤在同一秒的扫动,会在小时池仍绿时撞上分钟墙。
107107
- REST 可达性是会话属性(GitHub App 会话门),⛔ 不是端点或席位类型的属性。
108108
- 开轮探一次、按班存档;探针必须是一条真 repo-scoped 读。
109109
- 门关着时 repo-scoped 路径整类回 403 `GitHub access is not enabled for this session`。
@@ -117,7 +117,6 @@
117117
- CCR 容器的 GitHub 出口是代理加凭据的:无 header 的 REST 读回 200 带会话身份,core 上限 15000。
118118
- 调用方自带的 `Authorization` 头被代理覆盖;`HTTPS_PROXY` 端口打死也不切断网络。
119119
- ⇒ 容器内得出的 token 作用域结论 ⛔ 不迁移到出口未经代理的会话。
120-
- 同因:`check-clause2-carriers.mjs --pair` 带与不带 token 都不再 403 退 3;真缺声明照常退 4。
121120
- REST 写侧经出口代理必带 `Content-Type: application/json`,否则代理回 415 且一个字节都没写。
122121
- 判别式:该 415 的 `documentation_url` 指 Claude Code 不指 GitHub ⇒ 代理拒,不是 GitHub;四端点实测。
123122
- 两通道的信封在配额、权限、传输三样上都不同 ⇒ 任一侧的拒绝只是那一侧的读数。
@@ -382,16 +381,16 @@
382381
- ⛔ 不据 `ls-remote | grep issue-` 正命中回避该卡:失效方向是活卡被读成已认领,无红信号。
383382
- 会话从上下文检测不到自己的静默降档:横幅只在 UI 侧渲染,上下文零信号。
384383
- 服役档的权威读数是 `get_session`(claude-code-remote MCP,无参)的 `external_metadata.last_served_model`。
385-
- 它是最近一轮服役者,降档链中途照真;`session_context.model` 是配置档,⛔ 不作保险丝输入。
386-
- 该读数按宿主分叉:有的宿主的 `get_session` 按契约排除当前会话 ⇒ 保险丝无输入。
384+
- 它是最近一轮服役者,降档链中途照真;`session_context.model` 是配置档。
385+
- 该读数按宿主分叉:有的宿主的 `get_session` 按契约排除当前会话。
387386
- ⛔ 不据一台宿主推全体;替代读数用时在卡上申报。
388387
- 无它时的合法替代 = grep 本会话 transcript 里 harness 写的 `"model":`,逐请求写入、非自述。
389388
- 档位额度终止是第三种死法:子代理死在编辑中途、宿主报本账户档位额度到顶。
390389
- 有宿主信号故非普通子代理死亡,亦非维护者中止 ⇒ 派发已死、前提完好、卡在资源。
391390
- 处置 = 死认领回收加 worktree 抢救,⛔ 不重核前提、不升级。
392391
- 无前置探针,只在 dev 死在里面时可观测;缓解只在 dev 侧的早 WIP 提交。
393392
- 档位不可用时 ⛔ 不凭记忆宣告车道阻塞,逐文件面现推 mandate。
394-
- 强制档不得因不可用而降档 —— 那正是降档保险丝要拒的替换。
393+
- 强制档不因临缺授权降档:临缺非退役,退役唯维护者裁;不达档起隔离达档子代理或等档。
395394
- 本车道强制多是过宽的回忆:`dispatch-gates.mjs --tier PATH` 逐路径现推,路径线是下限非放行。
396395
- 该脚本只答自己那棵树:姊妹仓路径回 absent from this tree,姊妹仓的档位与条款②只能手推。
397396
- `os-verify-lock.sh` 只住 objectstack:objectui 无它,跑本仓副本读的是容器级锁,非该仓深度。

‎content/docs/references/api/error-code-ledger.mdx‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,8 @@ package's `dist` is registered here whether or not an HTTP door can ever
103103
answer with it — a thrown value's `code` is what a consumer's
104104
`catch (e) { switch (e.code) }` pins, and once shipped it cannot be renamed
105105
without breaking that consumer. Registering a code widens this face and is
106-
therefore a Clause-② change (`needs:contract-review`), door or no door; a
107-
code present in `dist` and absent here is a protocol gap, not a tier
108-
question.
106+
therefore a Clause-② change, door or no door; a code present in `dist` and
107+
absent here is a protocol gap, not a tier question.
109108

110109
ONE shape, no second list: a `door: 'none'` code is a row like any other —
111110
the string under the package that stamps it, and a comment that states its

‎packages/spec/src/api/error-code-ledger.zod.ts‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,8 @@
9999
* answer with it — a thrown value's `code` is what a consumer's
100100
* `catch (e) { switch (e.code) }` pins, and once shipped it cannot be renamed
101101
* without breaking that consumer. Registering a code widens this face and is
102-
* therefore a Clause-② change (`needs:contract-review`), door or no door; a
103-
* code present in `dist` and absent here is a protocol gap, not a tier
104-
* question.
102+
* therefore a Clause-② change, door or no door; a code present in `dist` and
103+
* absent here is a protocol gap, not a tier question.
105104
*
106105
* ONE shape, no second list: a `door: 'none'` code is a row like any other —
107106
* the string under the package that stamps it, and a comment that states its

‎scripts/pm/dispatch-gates.mjs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25541,12 +25541,12 @@ function selfTest() {
2554125541
});
2554225542
}
2554325543
t(`${SKILL_RULEBOOK_ROOT} spells NO model id at all — ${skillRulebookFiles.length} file(s) read, and a RETIRED id left there is caught HERE, where a current-value pin cannot see it (found: ${skillIdSpellings.join(', ') || 'none'})`, skillRulebookFiles.length > 0 && skillIdSpellings.length === 0);
25544-
// The rulebook half of the same coupling: the skill names the constant, and
25545-
// its downgrade fuse carries the case the quota exemption never had.
25544+
// The rulebook half of the same coupling: the skill names the constant. Its
25545+
// downgrade-fuse section is retired (maintainer 2026-09-22 「降档保险丝 不留」,
25546+
// #19061 comment 5772289798), so the guard below reds if that text creeps back.
2554625547
const fuseRules = readFileSync(nodePath.join(ROOT, '.claude/skills/pm-dispatch/references/contract-review.md'), 'utf8');
2554725548
t('the rulebook names the contract-review tier by its CONSTANT, so a retirement moves the value and the prose follows', fuseRules.includes('`CONTRACT_REVIEW_TIER`'));
25548-
t('…and its fuse keeps the quota exemption pointed at DISPATCH, never at the review', /额度耗尽豁免[^\n]*⛔[^\n]*不及复核/.test(fuseRules));
25549-
t('…and carries the case it never had: a RETIRED tier is not an exhausted one, and it is a maintainer ruling, ⛔ never a seat\'s reading', /档位退役[^\n]*≠[^\n]*耗尽[^\n]*维护者裁决[^\n]*⛔[^\n]*非席位读数/.test(fuseRules));
25549+
t('the rulebook no longer carries the retired 降档保险丝 lines (maintainer 2026-09-22 「降档保险丝 不留」, #19061 comment 5772289798)', !/额度耗尽豁免[^\n]*不及复核/.test(fuseRules) && !/档位退役[^\n]*≠[^\n]*耗尽/.test(fuseRules));
2555025550

2555125551
// ── Clause-② suspicion (the enqueue-gate card): hit / no hit / wording ────
2555225552
//

0 commit comments

Comments
 (0)