Repository navigation
Commit c91a004
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
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
200 | | - | |
| 200 | + | |
201 | 201 | | |
202 | 202 | | |
203 | 203 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
| 49 | + | |
| 50 | + | |
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
53 | 54 | | |
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
57 | | - | |
| 58 | + | |
58 | 59 | | |
59 | 60 | | |
60 | | - | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
65 | 64 | | |
66 | 65 | | |
67 | 66 | | |
| |||
70 | 69 | | |
71 | 70 | | |
72 | 71 | | |
| 72 | + | |
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| |||
0 commit comments