Skip to content

Observation: check-changeset-no-major.mjs has no --self-test, and its enforcing half is unexecuted on every run today (pre-mode) #6923

Description

@os-project-manager

Measured while implementing #6509 (PR #6917). Not fixed there — out of that PR's file surface, filed separately per Prime Directive #10. Unclaimed.

Observation

#6509 names three scripts as one family. Two of them have --self-test and PR #6917 wires those halves into lint.yml. The third, scripts/check-changeset-no-major.mjs, has no --self-test at all — measured on origin/main @ 6968885ef:

$ grep -n "self-test\|selfTest" scripts/check-changeset-no-major.mjs
  (no output)

It is therefore not a candidate for that wiring, and PR #6917's new pin says so explicitly in its assertion message so the omission does not read as an oversight. But the absence itself is worth recording, because of what the script contains and when it runs.

Why it is not merely "a small script"

Two decision surfaces, neither with a fixture:

  1. A hand-written frontmatter parser (majorPackagesIn, :60-71) with a regex covering three quoting dialects — "name": bump, 'name': bump, name: bump — and a case-insensitive major comparison. check-empty-changeset.mjs has a parser of the same shape and pins it with six dedicated parser: assertions; this one has none.
  2. The RC exemption branch (:93-113): it reads .changeset/pre.json, and on mode === 'pre' it prints notices and process.exit(0) instead of failing. An unreadable pre.json falls through to the guard.

The part that makes it observation-class rather than cosmetic

.changeset/pre.json currently says "mode": "pre", so every CI run today takes the exemption branch and exits 0. The enforcing half — the offenders report and the process.exit(1) at :127 — is unexecuted on every run, and has never had a fixture to execute it either.

It re-arms by itself at changeset pre exit. That is precisely the day whole-stack majors are under discussion and the guard's verdict matters most — and it will re-arm having never been exercised in either direction.

Same family as #4690 / #6509: a checker whose red direction is pinned nowhere. Distinct fix face from #6509 (which is about where the two existing self-tests run), so filed separately rather than as a sub-issue.

Impact, stated honestly

  • No known instance. Nothing is mis-judged today; the guard is standing aside by design.
  • The gap is potential, not active: if the parser or the exemption branch drifted, no fixture and no CI run would notice until changeset pre exit.
  • Observation class. Recording it so the pre-exit window does not arrive with this unmeasured.

Candidate dispositions (no conclusion presumed)

  1. Add --self-test fixtures (both directions: a major in each quoting dialect is caught; pre-mode stands aside and says so; an unreadable pre.json enforces) and fold it into check:changeset-gate-self-tests, which PR fix(ci): run the changeset family's --self-test in lint.yml, out of reach of skip-changeset (#6509) #6917 introduces — one extra script name in an existing step, no new lint step.
  2. Do it as part of the changeset pre exit checklist instead, when the guard actually re-arms.
  3. Rule the script small enough to stand without fixtures and write that down.

Leaning 1 — the wiring it would attach to already exists after #6917, so the marginal cost is one line — but the RC-window timing makes 2 defensible. Left to triage.


Generated by Claude Code

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions