⏱️ Measured by the domain:spec execution seat 2 (session session_01UDXER3sdqfeVYpEWZs5mZx) at 2026-09-21T08:5xZ, from a live instance on PR #19533. ⛔ Filed unassigned, ⛔ no priority:*, ⛔ no domain:*, ⛔ no type — routing and grading are triage's.
The reading, taken first-hand
$ node scripts/check-changeset-no-major.mjs --base origin/main
✓ This diff introduces no `major` bump.
ℹ️ LEVEL AXIS: NOT APPLICABLE — this run has no `pull_request` to read a declaration from, so the
clause-② axis has no input by construction rather than by omission. …
EXIT=0
⭐ The gate is not lying, and that matters for how this is fixed. It says exactly why the axis produced nothing, it distinguishes 「by construction」 from 「by omission」, and it names which callers legitimately reach that path. This is a well-behaved refusal to report on an input it does not have.
The consequence is nonetheless real: the script has two axes, and the second one — 「a PR that DECLARES clause ② must grade at least one package minor or above」 — is the one that actually reds in CI. A seat or dev running the gate locally before pushing gets EXIT 0 that says nothing about it.
Measured instance, and the remedy proven in two legs
PR #19533 pushed a changeset level change, ran the repo's fast checks, and went red on Check Changeset step 15 anyway. The implementer then drove the same script offline through its own --event flag against the real pull_request payload:
--event + the patch commit → EXIT 1, reproducing the CI red
--event + the minor commit → EXIT 0, with ✓ LEVEL AXIS
Two legs, so the flag is a measurement rather than a hope. ⇒ The capability exists; nothing tells a seat to use it.
Why it is a finding rather than a note
The dispatch protocol's pre-push discipline says to run the repo's own fast checks before pushing, and a PM dispatch order repeats it. For this gate that instruction is incomplete in a way the runner cannot detect: the local green and the CI red are the same script, the same tree and the same commit, differing only in an input the local invocation has no reason to supply. A check whose local form is reliably green on the axis most likely to fail trains seats to trust a signal that cannot fail — which is the same shape as a dead instrument reading as a clean result, and that shape cost this shift two red pushes.
⚠️ It also interacts with #19548 (the lane's 辅助面-⇒-patch rule versus this same LEVEL axis), but it is a separate defect: #19548 asks which rule wins; this card asks why a seat cannot find out before pushing.
Candidate remedies, ⛔ none chosen here
- A runbook line: where the pre-push discipline is written, name
--event "$GITHUB_EVENT_PATH" (or the offline equivalent) for this gate specifically.
- Or make the local run say what it cannot say more loudly than an
ℹ️ beside a ✓ — the information is already in the output; what is missing is that a reader skimming for a non-zero exit will not see it.
- Or have the gate derive the declaration from the claim comment / PR body when no payload is present, which is a behaviour change and the most expensive of the three.
Dedup words
check-changeset-no-major · LEVEL AXIS NOT APPLICABLE · --event payload · vacuous local green · pre-push gate discipline
Generated by Claude Code
⏱️ Measured by the
domain:specexecution seat 2 (sessionsession_01UDXER3sdqfeVYpEWZs5mZx) at 2026-09-21T08:5xZ, from a live instance on PR #19533. ⛔ Filed unassigned, ⛔ nopriority:*, ⛔ nodomain:*, ⛔ no type — routing and grading are triage's.The reading, taken first-hand
⭐ The gate is not lying, and that matters for how this is fixed. It says exactly why the axis produced nothing, it distinguishes 「by construction」 from 「by omission」, and it names which callers legitimately reach that path. This is a well-behaved refusal to report on an input it does not have.
The consequence is nonetheless real: the script has two axes, and the second one — 「a PR that DECLARES clause ② must grade at least one package
minoror above」 — is the one that actually reds in CI. A seat or dev running the gate locally before pushing getsEXIT 0that says nothing about it.Measured instance, and the remedy proven in two legs
PR #19533 pushed a changeset level change, ran the repo's fast checks, and went red on
Check Changesetstep 15 anyway. The implementer then drove the same script offline through its own--eventflag against the realpull_requestpayload:--event+ thepatchcommit → EXIT 1, reproducing the CI red--event+ theminorcommit → EXIT 0, with✓ LEVEL AXISTwo legs, so the flag is a measurement rather than a hope. ⇒ The capability exists; nothing tells a seat to use it.
Why it is a finding rather than a note
The dispatch protocol's pre-push discipline says to run the repo's own fast checks before pushing, and a PM dispatch order repeats it. For this gate that instruction is incomplete in a way the runner cannot detect: the local green and the CI red are the same script, the same tree and the same commit, differing only in an input the local invocation has no reason to supply. A check whose local form is reliably green on the axis most likely to fail trains seats to trust a signal that cannot fail — which is the same shape as a dead instrument reading as a clean result, and that shape cost this shift two red pushes.
patchrule versus this same LEVEL axis), but it is a separate defect: #19548 asks which rule wins; this card asks why a seat cannot find out before pushing.Candidate remedies, ⛔ none chosen here
--event "$GITHUB_EVENT_PATH"(or the offline equivalent) for this gate specifically.ℹ️beside a✓— the information is already in the output; what is missing is that a reader skimming for a non-zero exit will not see it.Dedup words
check-changeset-no-major·LEVEL AXIS NOT APPLICABLE·--event payload·vacuous local green·pre-push gate disciplineGenerated by Claude Code