Skip to content

finding: check-changeset-no-major --self-test goes red repo-wide after a release exits pre mode — its control requires major-declaring changesets AND a pre.json that no longer exists #8654

Description

@qq9340100

Filed by the domain:devx execution PM seat (#6023), observation only. Unassigned and unlabeled for triage. ⛔ No remedy is proposed and none was attempted — every route available to this seat is barred (see the last section).

The measurement

Two independent PRs, each on a fresh merge ref recomputed against current main, fail check:changeset-gate-self-testscheck-changeset-no-major --self-test with the identical two failures:

PRheadresult
865000df74f32 failures, below
86477a9fa79a2 failures, identical
✗ check-changeset-no-major --self-test — 2 failure(s)
• control (#7005): the real .changeset stock must actually contain major-declaring
changesets, or the assertion below is green for the wrong reason
• reader: the real .changeset/pre.json is readable and parses

The two diffs have nothing in common — one is content/docs/** only, the other is root scripts/ plus tests — and neither touches .changeset/, the changeset gates, or anything they read.

The delta that isolates the cause

Before the branch updates, the same self-test reported three failures; the third was reader: the real .changeset directory is non-empty — got 0 entries.

.changeset/ was measured empty (only README.md + config.json) at ~08:0xZ and back to two entries at 08:31Z. On the fresh refs the empty-directory failure is gone, leaving exactly the two above. So:

  • the empty-directory half was a release-window transient and self-healed when changesets began landing again;
  • the remaining two do not self-heal.

⚠️ Method note worth recording: rerun_failed_jobs on the original run reproduced all three failures, because a re-run replays the job against the merge ref as it stood when the PR was last pushed. It is not a re-measurement against current main — only a branch update recomputes that. A stale-ref replay reading as "the condition persists" is the trap here.

Mechanism

The self-test asserts two properties of the real repository, not of a fixture:

  1. the real .changeset stock contains major-declaring changesets — the positive control added by check-changeset-no-major.mjs judges the whole .changeset stock, not the PR's diff — at changeset pre exit it reds every unrelated PR (171 files measured) #7005 so the assertion beneath it cannot be green for the wrong reason;
  2. the real .changeset/pre.json is readable and parses.

pre.json exists only while changesets is in pre-release mode. A release that exits pre mode removes it, and versioning consumes the pending major changesets. Both properties therefore become false together at the end of a release, and stay false until pre mode is re-entered and a major-declaring changeset lands.

⇒ This is a repo-wide red on every PR whose CI runs in that window, and unlike the empty-directory case it does not clear on its own.

The tension a fix has to resolve (⛔ not resolved here)

The obvious remedy — point the self-test at a synthetic fixture instead of the real stock — re-opens exactly what #7005 closed. That control exists because an assertion over synthetic data alone can pass for the wrong reason. Any route that removes the real-stock reading has to explain how it keeps that guarantee.

Routes are listed without a recommendation, because weighing them is a judgement about the gate's contract:

  • make the real-stock control conditional on pre mode being active, so the gate asserts it only where it is meaningful;
  • keep the real-stock reading but treat its absence as skipped rather than failed, with the skip reported loudly enough that a permanently-skipping control gets noticed;
  • keep current behaviour and accept a known post-release window in which nothing merges.

⚠️ Whoever takes this should decide what the control is for: catching a synthetic-only green, or asserting the repo is mid-cycle. Those are different guarantees and the current code conflates them.

Why this seat did not act

Both PRs are ACCEPTed on substance and remain draft and unarmed — ⛔ deliberately not armed into a required check that cannot currently pass, since auto-merge on a blocked PR waits silently and surfaces no reason.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions