Skip to content

Commit c91a004

Browse files
pm-dispatch(contract-review): a FAIL on the current head, or a head move that changes the reviewed surface, disarms auto-merge at once (#27845)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} --> _Requested by **Elon** · [project thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DQZkczRFmBwr8urZVj1Xj8F)_ Fixes #27809 Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:PR 已挂自动合并时,若当前提交的契约复审判 FAIL,或提交被改动(如合入 main 时改了被审内容),负责席位读到即撤下自动合并;FAIL 记录写明这一步,重新挂上仍须当前提交有 PASS。 - 为什么改:PR #27667 增量复审 FAIL 后 20 分钟,仍凭早先挂上的自动合并被队列合入,主干随即变红(p0 #27806)。原规则只说落地前要有 PASS,没说已挂上的 PR 在 PASS 失效时怎么办。 - 风险与回滚:只改 `.claude/skills/pm-dispatch/` 下三处规则文字,不发布任何包,不加门禁或脚本;三个文件行数都没涨(删两句重复条文付账)。回滚即 revert 这一个提交。 - 先看:`references/contract-review.md` 的 head 后移一条(两行),再看等复核标记一节合并后的第一行。 - 两分钟验证:`pnpm check:pm-skill-ratchet && pnpm check:pm-skill-id-lint`,预期都绿,contract-review.md 仍为 60 行。 - 需要你做的:暂无。contract review owed(契约复审未完成,席位复审后再求批);本 PR 是规则改动,落地为 Tier H,由维护者批准。 ## What changes Rule text only, in `.claude/skills/pm-dispatch/`. No script, no gate, no queue guard (triage: 「新增门禁默认否」). - **`references/contract-review.md`, the one rule site.** The head-move exception bullet under landing check ① now carries both rules: > head 后移:纯重生成或只动散文面则原记录续管,落 `Regen-provenance:` 行;余移或现 head 落 FAIL > 而已挂 auto-merge ⇒ 派发席读到即照 AGENTS.md disarm 句撤挂,FAIL 记录点名撤挂;重挂照 ①。 In English: a pure regeneration or prose-only move keeps the original record (with a `Regen-provenance:` line). Any other move, or a FAIL on the current head, while auto-merge is armed: the dispatching seat disarms on reading it, by the AGENTS.md disarm sentence, and the FAIL record names the disarm. Re-arming follows check ①, so it needs a PASS (or a `Regen-provenance:` line) on the current head. - **The disarm itself is not restated.** It points at the one `disarm` sentence in `AGENTS.md` (governed-surface landing, "Already armed or queued when you read this?"): disable auto-merge AND convert to draft; neither act is measured to dequeue a queued PR, so ask the maintainer to remove it by hand, then confirm it is in neither the queue nor `origin/main`. The relay ops are `automerge_disable` and `pr_draft` (`references/rest-channel.md`). The dequeue facts are in `references/platform-readings.md` § queue membership. - **Pointers, in place:** `references/landing-operations.md:12` (`FAIL ⇒ 撤挂,补丁轮`) and `SKILL.md:200` (`PASS 后 head 移 ⇒ 撤挂回等`). ## Why — measured | Event | Record | Time | |:--|:--|:--| | Seat check after a main merge moved #27667's head to `af33de9c`; "Auto-merge stays armed" | comment 6510205555 | 2026-10-29T22:41Z | | Triage: auto-merge is armed on a head no PASS names; the owning seat disarms until a delta PASS | comment 6510422663 | 22:54Z | | Delta contract review on `af33de9c`: FAIL, two must-fix | comment 6510686343 | 23:11Z | | #27667 merges at `af33de9c` through the still-armed auto-merge | merge `21c4bdd8` | 23:31Z | | main `Dogfood Regression Gate (1/3)` red on the two pins the FAIL named | p0 #27806 | after the merge | `contract-review.md` on `fec60e00b` had no disarm text (`grep -n -i 'disarm\|automerge_disable\|auto-merge'` → 0 hits). Landing check ① said a PASS must name the current head before landing. Nothing said what to do with a PR that was already armed when ① stopped holding, so the seat left it armed. ## Line budget All three files sit at their ceiling with headroom 0 (`scripts/pm/check-skill-line-ratchet.mjs`), and no maintainer ruling orders a raise. The rule costs one line (the exception bullet goes from 1 line to 2). It is paid in the same file by real deletion, not by re-wrap: the marker section's first and last bullets fold into one line, dropping two restatements: - 「卡上副本在规则外、不是要求」: follows from 「单载体 = PR」, which stays. - 「入队只认同形记录,标记有无不改判」: restates landing check ① and 「⛔ 不是闸门」, which stays. Wording compressed in the edited lines only: 「只动上列散文面」 → 「只动散文面」 (the prose faces are defined once, at :9–10), 「继续管」 → 「续管」, `landing-operations.md` 「交棒请审」 → 「交棒」 (SKILL.md ③ is 「请审 = 席位交棒」), `SKILL.md` 「回等复核」 → 「撤挂回等」. | File | Lines (ceiling) | Changed | |:--|:--|:--| | `references/contract-review.md` | 60 (60) | +3 / −3 | | `references/landing-operations.md` | 101 (101) | +1 / −1 | | `SKILL.md` | 319 (319) | +1 / −1, an in-place edit of :200 | Every edited line is at most 120 bytes. ## Deviations from the dispatch order - **The precedent is named here, not in the skills text.** The order asked for one clause naming #27667 → p0 #27806. `check:pm-skill-id-lint` refuses any `#NNN` in the pm-dispatch corpus, and the rules-only ruling moved incident narratives out of it. So the precedent lives in this body and in the commit message. - **The disarm steps are a pointer, not a restatement.** The order's "relay `automerge_disable`, plus `pr_draft` where the repo's reading says disable alone does not dequeue" is already the AGENTS.md disarm sentence, which is stricter (both ops every time, plus the maintainer's hand removal for a queued PR). The rule points there. - **Wanted 3 of the card** (a queue guard that refuses a head whose newest contract record is FAIL) is not built. It is the maintainer's call per the card and triage. - `landing-operations.md:57` and `:72` (the seat's own `origin/main` merge) are not edited. The head-move half reaches every seat through `SKILL.md:200`, which is read in full on every fire. ## Verification <details><summary>dispatch-gates</summary> `node scripts/pm/dispatch-gates.mjs --commands` (no paths, derived from the committed diff against merge base `fec60e00b`) derives 21 families. All 21 were run with exit codes captured before any pipe. `pnpm --filter @objectstack/lint run check:doc-formula-expressions` first exited 3 (`@objectstack/formula` and `@objectstack/lint` not built in a fresh worktree). It was re-run after `pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint`, exit 0. `--ran` reconcile: `21 derived famil(ies) accounted for — 21 run, 0 NOT-MEASURED`. Changed lines 10 (+5 / −5), under the 3000 threshold. `git merge-tree` against `origin/main` `0a4b0fb2` is clean, and no commit since the base touched these three files. Directly relevant: `check:pm-skill-ratchet` (60/60, 101/101, 319/319), `check:pm-skill-id-lint`, `check:pm-governed-prose`, `check:pm-record-recognisers`, `check:skill-frame-sync`. All exit 0. </details> Contract review owed: governed `.claude/**` rules text, at `CONTRACT_REVIEW_TIER`. Landing is Tier H (triage 6512254201: 「A rule change: the maintainer approves」). ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. (not touched) - [x] 2. Every name I added uses the casing for its kind. (no names added) - [x] 3. No formatter ran; `pnpm lint` passes (prose only; the full run is CI's). - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset. `.claude/**` publishes nothing, so `skip-changeset`. - [x] 6. `packages/spec` touched: n/a. - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English (the 维护者速读 and quoted rule text are the sanctioned Chinese channels). - [x] The *Before Submitting* list in CONTRIBUTING.md is done. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_016WV4cwDXbDuhAz7Zn6Dv8i --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent c4cb5ec commit c91a004

3 files changed

Lines changed: 6 additions & 6 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
197197
- 批准后再推亦不过期;席位落地 = 过落地前检、清标、ready、auto-merge,踢出/变基同法。
198198
- ③ 请审 = 席位交棒:ACCEPT 与现 head 同形 PASS 俱在案后,中继 `pr_request_reviewers` 请审批人。
199199
- 作者是审批人 ⇒ `assign` 它、请其余(请它必 422);⛔ 永不派/请席位自身账号;Tier S 不交人。
200-
- `pr_create` 不请不派;`pr_ready` 只补交棒漏;PASS 后 head 移 ⇒ 回等复核;脱中继 PR 自读请/派。
200+
- `pr_create` 不请不派;`pr_ready` 只补交棒漏;非例外 head 移 ⇒ 撤挂回等;脱中继 PR 自读请/派。
201201
- 速读「需要你做的」求批点名 PASS 评论 id+`Head-sha`;无 PASS ⇒ 写 contract review owed 不求批。
202202
- ④ 轮次报告单列 awaiting a human merge。
203203
- skills 车道自有 PR:纯代码面如 `scripts/pm/` 由本席按达档自审(清单不减)后落地。

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@
4646
- ④ 恒由起草者之外的 agent 达档跑,起草已达档不免;喂入同上,⛔ 不喂起草者的结论。
4747
- 轮次报告设复审清单专节,与呈裁清单同为强制审计。
4848
- 请审/求批与落地前检两条,过则 Tier S 入队、Tier H 等人批:① 现 head 同形达档 PASS 在案。
49-
- 例外:纯重生成或只动上列散文面的 head 后移原记录继续管;PR 落 `Regen-provenance:` 行。
49+
- head 后移例外:纯重生成或只动散文面原记录续管,落 `Regen-provenance:` 行;余移或现 head 落 FAIL
50+
而已挂 auto-merge ⇒ 派发席读到即照 AGENTS.md disarm 句撤挂,FAIL 记录点名欠撤挂;重挂照 ①。
5051
- ② PR check 全绿,⛔ 非 required 子集;例外:merge-base 同签名的红不计、按设计而红见 SKILL.md。
5152
- 签名 = 失败步 + 首错行,读 base check runs 的 API ⛔ 不凭口述;主干红止血立单不变。
5253
- 落地时仍欠复核的 PR 在落地 head 复审,车道席或分诊按 (a)(b)(c) 接;FAIL ⛔ 不修已关 PR。
5354
- 每条 must-fix 引该记录立新卡、按发现定级;回退仅限主干红(p0,main-red 约定①)或安全边界。
5455

5556
## 等复核标记 `needs:contract-review`
5657

57-
- 只作等复核标记,⛔ 不是闸门;单载体 = PR,卡上副本在规则外、不是要求。
58+
- 只作等复核标记,⛔ 不是闸门:无 check、workflow 或队列守卫读它与认领/hold 行;单载体 = PR。
5859
- 挂:ACCEPT 时条款②任一肢命中而现 head 无同形 PASS 在案 ⇒ 派发席同笔挂于 PR。
5960
- 摘:现 head 同形 PASS 在案 ⇒ 写记录的席同笔摘;PR 合并或关闭 ⇒ 派发席摘;FAIL 不摘。
60-
- ⛔ 无 check、workflow 或队列守卫读标记与认领/hold 行;入队只认同形记录,标记有无不改判。

‎.claude/skills/pm-dispatch/references/landing-operations.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- 路径肢 = diff 触及契约面 `packages/spec/src/**` 非测试,含 error-code-ledger、`*.zod.ts` 契约 schema。
1010
- 声明肢 = 认领评论声明 `Clause-②: yes`,与路径无关;错误的 `no` 是可审计的假申报。
1111
- 子代理起不来 ⇒ 复核缺席,PR 带 `needs:contract-review` 留 draft 队列外;旁路仅维护者逐次亲审
12-
- PASS ⇒ Tier S ready、auto-merge;Tier H 经 SKILL.md ③ 交棒请审;FAIL ⇒ 补丁轮;⛔ 免复核不放行。
12+
- PASS ⇒ Tier S ready、auto-merge;Tier H 经 SKILL.md ③ 交棒;FAIL ⇒ 撤挂,补丁轮;⛔ 免复核不放行。
1313
- 落地后才见欠复核 ⇒ 按 `contract-review.md` 复审落地 head、发现立新卡,⛔ 不修已关 PR。
1414
- DELIBERATE CORRECTION 红(`check-empty-changeset`)⛔ 不等维护者;确认件皆须点名每个被改 note:
1515
- diff 只改 release 文字或注释者:派发席 ACCEPT 确认,逐句引改前与改后,免第二次同 head 复核。
@@ -61,7 +61,6 @@
6161
- ② enable-auto-merge 调用根本没落地,重发与效果验证序列见 `platform-readings.md`。
6262
- ③ PR 碰 `.github/workflows/**`:令牌常驻 `workflows: write`(裁决评论 6104822731),仍拒即授权漂移。
6363
- 确认 MERGED 同一动作里给 `Part of` 卡收口、`Fixes` 卡代关但标也须摘,⛔ 不拆到下轮巡检。
64-
- `Part of` 卡开着不摘 `pm:dispatched`,无在飞物的卡就永远算进 `label:pm:dispatched is:open`。
6564
- 摘标换回 `pm:queue` 或按剩余物定级,加一条写清交付了什么、剩下归谁的评论。
6665
- 同刻读相关卡 `closed_by_pull_requests`,确认没有卡被正文闭合关键词误关。
6766
- 每次合并后重拉一次车道盘点与预期状态对账,⛔ 不留给下轮巡检。
@@ -70,6 +69,7 @@
7069
- MERGED 不是终点:发版后义务见 `release-aftercare.md`。
7170
- PR 开出至 MERGED,每看一眼(唤醒/巡检/报告前)同读检查与 `mergeable_state`;`unknown` 即重读。
7271
- `dirty` ⇒ 当即合 `origin/main` 推新提交,⛔ 不等冲突通知;未见非 `dirty` ⛔ 不报无需你做。
72+
这一移 head 的撤挂与重挂照 `contract-review.md` head 后移例外条。
7373
- MERGED 或关闭即退订,同刻把 `mode:cloud` 派的会话 `archive_session`。
7474
- 触发条件是卡终局且报告已收复核;⛔ 合并前不归档,误归档可 unarchive 但容器现场已失。
7575
- 暂停或交接时把在挂订阅清点进座位贴,⛔ 不留孤儿订阅。

0 commit comments

Comments
 (0)