Repository navigation
Commit a55646b
fix(scripts): render an unread clause-② carrier as NOT MEASURED, and stop routing it to the remedy that clears the carrier (#18577)
Fixes #17229
Clause-②: no
## What was wrong
`declarationFromPullRequest` rendered every non-matching label list the
same way:
```
carrier: `needs:contract-review` is not on this PR (N label(s) read)
```
including `N = 0`. A zero-label read is not an absence. The event
payload is a snapshot taken
when the run fired, so an empty list is equally consistent with *this PR
carries no labels* and
*nothing had been labelled yet*, and nothing inside the payload
separates the two. The file
already owns the right word for that state and uses it verbatim in its
own payload block — "the
`opened` run at 21:40Z would have read NOT MEASURED" — it simply did not
spell it at this call
site. That is `declared ≠ enforced` inside one file.
**The string was not the damage.** `renderLevel`'s `enforce` message
printed the unread carrier
beside the `Clause-②:` line and then offered remedy 2 — *"correct it at
the producer: the
`needs:contract-review` carrier is the review seat's to place and to
clear"*. Pointed at a
carrier the run never looked at, that reads as an instruction to strip a
review requirement in
order to clear a red whose real cause was remedy 1 (a `patch` that owed
`minor`). The file's own
text says the two remedies are "not interchangeable".
## What changed
`scripts/check-changeset-no-major.mjs`, one file, no new inputs.
1. `declarationFromPullRequest` returns a three-valued `carrier` axis —
`present` / `absent` /
`not-measured` — beside `value` and `arm`, and renders an empty or
unreadable label list as
`NOT MEASURED` (still printing the count it read).
2. `judgeLevel` carries the axis through to the renderer on all nine
verdicts.
3. `renderLevel`'s `enforce` branch softens its header and its remedy 2
**only** on a positive
`not-measured`: it names which two things disagree (the clause-②
declaration and the changeset
level), says the carrier is not evidence either way, and withdraws the
carrier half of remedy 2
with an explicit ⛔. Remedy 1 is untouched, and so is the exit code.
⛔ **The payload boundary is untouched**: no API call, no token, no live
label read. The
`labeled` / `unlabeled` triggers remain the documented mitigation, and
the fixed message now
points a reader at them.
## Measured, both directions, end to end
Real CLI, real `--event` payloads, on a throwaway probe commit that
moved `packages/cli/src/**`
under a `patch` changeset (scaffold removed afterwards; the branch
carries only the one file).
Each direction was run against the pre-fix script (extracted from the
merge base) and the fixed
one, on byte-identical input.
| payload | before | after |
|:---|:---|:---|
| 0 labels, body declaring `yes` | *carrier: needs:contract-review is
not on this PR (0 label(s) read)* · "The two declarations disagree" ·
remedy 2 offers clearing the carrier | *carrier: NOT MEASURED — the
payload's label list is EMPTY (0 label(s) read)* · header names the
declaration vs the level · remedy 2's carrier half withdrawn |
| 4 labels, carrier not among them | "The two declarations disagree" +
remedy 2 verbatim | **byte-identical** — `diff` reports 0 differing
lines |
| 5 labels incl. the carrier | *carrier: needs:contract-review IS on
this PR* | **byte-identical** — `diff` reports 0 differing lines |
Exit code 1 in all six runs: the refusal is repaired in its diagnosis,
not spent.
## The check has a positive control
A new self-test battery (`#17229: an UNREAD carrier is NOT MEASURED,
never an absent one`,
25 assertions, roster floor raised 17 → 18) pins both directions from
one harness plus the
fixture control the card asks for — a PR carrying
`needs:contract-review` must make the carrier
line report **present**.
It was proved able to fail, twice, each mutation verified on disk by
occurrence count and blob
hash and restored against `HEAD`:
| mutation | effect | self-test |
|:---|:---|:---|
| `} else if (labels.length === 0) {` → `} else if (false) {` | restores
the pre-fix reader | **8 failures**. One reproduces the filing string
verbatim: *an empty list must be rendered NOT MEASURED — got carrier:
needs:contract-review is not on this PR (0 label(s) read)* |
| `const carrierUnread = result?.carrier === 'not-measured';` → `=
false;` | restores the pre-fix rendering | **3 failures**, incl. the
routing leg |
| restored | — | **299 assertions, exit 0** |
## The trigger types the card left open — measured
The card said the PR "failed identically in two separate workflow runs".
That is true of the
*failure*, and **not** of the carrier line. Measured from the runs API
and the PR timeline:
- `needs:contract-review` was applied at `2026-09-09T19:39:17Z`; the
other four labels at
`19:39:30Z` / `19:39:41Z`.
- Run `34396338801` (job `102616882441`) was created at `19:39:13Z` —
**4 s before** the carrier
was applied. Its payload snapshot could not have carried it, and its log
is the false line.
- Run `34396350963` (job `102616922544`) was created at `19:39:20Z` —
**3 s after**. Its log
reads *carrier: needs:contract-review IS on this PR*.
⇒ There is **no second defect underneath**: the `labeled` run's payload
did carry the carrier and
the documented mitigation held. Only the earlier run printed the false
line. Both runs' event name
is `pull_request` (the runs API exposes the name, not the action type;
the timestamps are what
separate them).
That second log also settles what the original header meant: it printed
"The two declarations
disagree" while carrier and line **agreed**, so "the two declarations"
is the clause-② declaration
versus the changeset level. This PR leaves that path byte-identical and
only disambiguates the one
case where the carrier contributed nothing.
## Acceptance notes
- `skip-changeset`, measured rather than assumed:
`scripts/check-changeset-no-major.mjs` lies
outside every package directory (0 package dirs contain it), no package
manifest's `files[]`
names a `scripts` path, and the touched symbols have 0 hits anywhere
under `packages/`. Firing
controls for both readings: `packages/lint`'s `files[]` does ship
`CHANGELOG.md`, and the same
grep finds `defineStack` under `packages/spec/src`. The root manifest is
`private: true`.
- **noted, not filed**: the card's "Reproducible, not a one-off … the
same PR failed identically in
two separate workflow runs" is inaccurate about the carrier line — only
the first run printed it.
An observation about a card's evidence, not a defect in any file;
corrected above so the next
reader of that thread is not sent looking for a second instance.
Successor: this PR's reader.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---
_Generated by [Claude
Code](https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 497655f commit a55646b
1 file changed
Lines changed: 197 additions & 22 deletions
0 commit comments