Skip to content

Commit a55646b

Browse files
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

File tree

0 commit comments

Comments
 (0)