Commit 7337179
feat(pm): H51 + H53 — the two contract-review carrier states no sweep reads, and the FAIL end-state H51 applies (#17138)
* feat(pm): H51 — a contract-review verdict on the current head with no label stroke, and the FAIL end-state it applies
`needs:contract-review` is a dual-carrier gate whose verdict is a HANDOFF, and
the handoff's second act is a LABEL STROKE. Twelve PRs took a verdict in one
shift and no owning seat responded for 2-5 hours: the seats' sweeps read labels,
not PR prose, so a verdict recorded only as a comment reached nobody. H31 is
clean throughout — it compares the two carriers with each other, and both were
correctly on.
Two halves, both from the filing card:
- `references/contract-review.md` 载体纪律 names the FAIL end-state, which the
text never did (the PASS branch was precise, the FAIL branch said only
「转回相应工作态」 into a state model with no rework state). Paid in place by
deleting the vague line it subsumes; ceiling untouched at 60/60.
`lanes/director.md` 职责一 is rewritten in place to point at that single
source rather than carry a second copy; 72/72 untouched.
- H51 files a report-only row for an OPEN gated PR whose thread already holds a
contract-review verdict for the CURRENT head, older than 60 minutes. Verdict-
agnostic on purpose: both branches owe a stroke inside the window, and a row
that parsed the verdict would be issuing one. A verdict naming an OLDER head
is clean — the head moved, so the carrier is genuinely live again.
The anchor is measured rather than quoted: three title dialects were live on the
same day plus a director adoption record carrying the review verbatim, so the
row reads the two things all four share — a `## Contract review` heading line
and the head sha as a code span. Pinning the card's literal title would have
been silent on two dialects while reporting a clean board.
Reuses H48's `prCommentCache`, whose header reserved exactly this reader;
`head.sha` and `labels` ride the open-PR list row, so head identity costs no
request. The H52 self-test's `H51` reservation pin flips to its landed side.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MoTv7pn338AZ71owsp19gQ
* feat(pm): H53 — a contract-review carrier hung on a card with no claim and no PR
The gate rides an increment: 「PR 一存在即挂;报告先于 PR 到达则先挂卡侧」 says
where it is hung, 「⛔ 不前瞻预挂」 says where it is not, and the invariant both
serve is 「开着的载体恒 = 真实待审」. Fourteen open cards across two repos
carried it with no `Claim:` comment and no PR at all — thirteen written the
morning after a ruling restating the discipline merged into the text that seat
reads. All were found by a director summon; no sweep could see them.
H31 needs two carriers to compare, so with no PR it is INAPPLICABLE rather than
clean, and its header deliberately declined the「gate on a card with no PR is
premature」 shape because card-side-first is legal. The CLAIM leg is what lets
this row read the half that premise excluded: a dev executing card-side-first
has been dispatched, so its thread carries a claim. Claim present ⇒ silent.
⛔ Report-only, in H31's own register — the subject is a GATE, the row never
removes a carrier and never asks a script to. Removal is a person's audited act.
It BUYS a complete card thread per gated open card rather than reading a cache:
the measured population is unassigned by construction and H2 buys a thread only
for an ASSIGNED card, so a cache-only reading would report the whole target
shape UNJUDGED while looking healthy. 9 gated of 599 open cards, single-page
walks. H31's live `#10025` reading is pinned unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MoTv7pn338AZ71owsp19gQ
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent fb7d75f commit 7337179
3 files changed
Lines changed: 727 additions & 3 deletions
File tree
- .claude/skills/pm-dispatch/references
- lanes
- scripts/pm
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| 21 | + | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
| |||
44 | 45 | | |
45 | 46 | | |
46 | 47 | | |
47 | | - | |
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
| 36 | + | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| |||
0 commit comments