⏱️ Measured by the domain:spec execution seat 2 (session session_01UDXER3sdqfeVYpEWZs5mZx) at 2026-09-21T08:3xZ, from a live collision on PR #19533. ⛔ Filed unassigned, ⛔ no priority:*, ⛔ no domain:*, ⛔ no type — routing and grading are triage's. ⛔ Not a proposal for which rule should win.
The collision, with both sides quoted
Side A — the lane's own criterion (.claude/skills/pm-dispatch/references/lanes/spec.md):
契约面 = 「改动前后同一份输入的接受/拒绝结果变了」;判定逐字节不变 ⇒ 辅助面。
辅助面的 changeset 恒 patch …
Side B — the mechanical gate (scripts/check-changeset-no-major.mjs, header, axis 2):
THE LEVEL AXIS (#16055) — a PR that DECLARES clause ② (a new key on a published payload) must grade AT LEAST ONE package whose published source it moves minor or above; and (#16776) a PR that grades none of them that way must not leave the declaration UNREADABLE: where the missing reading is what decides the verdict, this refuses rather than exiting 0 into a check run that concludes success.
It runs in pr-automation.yml as Check Changeset step 15, "Guard against accidental major bumps (launch window)", and it is a required check.
The case that makes them disagree
A PR whose diff is prose only — .describe() strings, docblocks and tests — so the same documents parse to the same values before and after, while the claim declares Clause-②: yes.
- Side A grades it
patch: nothing about the accept set or the public surface moved.
- Side B refuses
patch: the declaration is yes, and no package is graded minor or above.
⚠️ The declaration being conservative is not an escape. references/contract-review.md says the declaration is deliberately provisional — 「Clause-②: yes | no 按设计临时:只定是否必过达档契约复核的保守方向,⛔ 非终审」 and 「声明被复核推翻 ⛔ 不作席位过失」 — so a seat is expected to over-declare and expects the at-tier review to be the real gate. But the LEVEL axis reads the declaration as binding on the version level, and it runs in CI where no review verdict can reach it.
⇒ The very discipline that makes over-declaring safe for the review gate makes it binding for the version gate.
Measured instance
PR #19533 (card #19228). The at-tier contract review ruled ② explicitly: zero accept-set movement, zero export movement, therefore patch, and cited both the lane criterion and the review reference's 「声明⛔ 非终审」 line to overturn the declaration. The dev graded patch. Check Changeset step 15 then failed on the LEVEL axis. Both artefacts are on the board: the review record is the newest long comment on #19228; the failing job is 106263965417.
What the seat did about it, and why it is not a fix: applied 「两条细则冲突 ⇒ 按更严的一条行动并立卡;⛔ 不当场改文本了结」 — restored minor (the stricter direction, and the one that keeps a required check green, since a red required check cannot land whatever a review concluded) and filed this. ⛔ It did not flip the declaration to no to make patch legal: that settles a rule conflict by editing the text the rule reads, which is the move that line forbids.
Why it is worth a card and not a note
The workaround ships a minor bump whose changeset prose has to explain that nothing behavioural changed — a version number that does not mean what a consumer reads it to mean. That is the same defect class the spec lane exists to close, arriving through the release channel instead of through a schema. And it is not one-off: every prose-only repair to a published .describe() on a Clause-②-declaring card hits it, which in this lane is a recurring shape.
⛔ This card takes no position on the answer. Three directions exist and each has a cost the other two do not: make the LEVEL axis read the review's verdict rather than the declaration; make the declaration retractable by a review with a recorded verdict; or accept the floor and say so in the lane rule so 辅助面恒 patch stops being stated unconditionally.
Dedup words
Clause-② level axis · check-changeset-no-major · 辅助面 patch · #16055 · changeset level conflict
Generated by Claude Code
⏱️ Measured by the
domain:specexecution seat 2 (sessionsession_01UDXER3sdqfeVYpEWZs5mZx) at 2026-09-21T08:3xZ, from a live collision on PR #19533. ⛔ Filed unassigned, ⛔ nopriority:*, ⛔ nodomain:*, ⛔ no type — routing and grading are triage's. ⛔ Not a proposal for which rule should win.The collision, with both sides quoted
Side A — the lane's own criterion (
.claude/skills/pm-dispatch/references/lanes/spec.md):Side B — the mechanical gate (
scripts/check-changeset-no-major.mjs, header, axis 2):It runs in
pr-automation.ymlasCheck Changesetstep 15, "Guard against accidental major bumps (launch window)", and it is a required check.The case that makes them disagree
A PR whose diff is prose only —
.describe()strings, docblocks and tests — so the same documents parse to the same values before and after, while the claim declaresClause-②: yes.patch: nothing about the accept set or the public surface moved.patch: the declaration isyes, and no package is gradedminoror above.references/contract-review.mdsays the declaration is deliberately provisional — 「Clause-②: yes | no按设计临时:只定是否必过达档契约复核的保守方向,⛔ 非终审」 and 「声明被复核推翻 ⛔ 不作席位过失」 — so a seat is expected to over-declare and expects the at-tier review to be the real gate. But the LEVEL axis reads the declaration as binding on the version level, and it runs in CI where no review verdict can reach it.⇒ The very discipline that makes over-declaring safe for the review gate makes it binding for the version gate.
Measured instance
PR #19533 (card #19228). The at-tier contract review ruled ② explicitly: zero accept-set movement, zero export movement, therefore
patch, and cited both the lane criterion and the review reference's 「声明⛔ 非终审」 line to overturn the declaration. The dev gradedpatch.Check Changesetstep 15 then failed on the LEVEL axis. Both artefacts are on the board: the review record is the newest long comment on #19228; the failing job is106263965417.What the seat did about it, and why it is not a fix: applied 「两条细则冲突 ⇒ 按更严的一条行动并立卡;⛔ 不当场改文本了结」 — restored
minor(the stricter direction, and the one that keeps a required check green, since a red required check cannot land whatever a review concluded) and filed this. ⛔ It did not flip the declaration tonoto makepatchlegal: that settles a rule conflict by editing the text the rule reads, which is the move that line forbids.Why it is worth a card and not a note
The workaround ships a
minorbump whose changeset prose has to explain that nothing behavioural changed — a version number that does not mean what a consumer reads it to mean. That is the same defect class the spec lane exists to close, arriving through the release channel instead of through a schema. And it is not one-off: every prose-only repair to a published.describe()on a Clause-②-declaring card hits it, which in this lane is a recurring shape.⛔ This card takes no position on the answer. Three directions exist and each has a cost the other two do not: make the LEVEL axis read the review's verdict rather than the declaration; make the declaration retractable by a review with a recorded verdict; or accept the floor and say so in the lane rule so 辅助面恒 patch stops being stated unconditionally.
Dedup words
Clause-② level axis·check-changeset-no-major·辅助面 patch·#16055·changeset level conflictGenerated by Claude Code