fix(pm): stop dispatch-gates requiring a .changeset/*.md population it cannot own - #15277
Merged
Merged
Conversation
… it cannot own The self-test's live-specimen block asserted `changesetPop.length >= 100` against the real working tree. That population is owned by the release cycle, not by this tool: a changesets version pass consumes all of it, so the control reds on the Version Packages PR — a required context, on the one PR whose merge IS the release — and then on `main` for the days it takes 100 fresh changesets to accumulate. The control was guarding something real: the two assertions under it pass vacuously over an empty population (`every` on nothing, `0 === 0`). That vacuity is now closed by construction instead of by a size claim — the corpus assertions run only where there is a corpus, and where there is not, the run says NOT MEASURED out loud, names why, and carries the tally on its verdict line. A silent skip would let the specimen rot, which is what the `>= 100` was reaching for. What a gate can require is the specimen's HOME: `.changeset/config.json`. While it is tracked, an empty population is this repo mid-cycle; when it goes, the specimen is rotted and somebody must pick a new one. That is the distinction the count could not draw. The second live-population site — the residue block's `hintReachesTree` — takes the same exit, so the red does not survive the repair at the site that was measured. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…angeset-population-control
os-zhuang
marked this pull request as ready for review
September 4, 2026 08:27
os-zhuang
enabled auto-merge
September 4, 2026 08:27
os-zhuang
deleted the
claude/issue-15255-changeset-population-control
branch
September 4, 2026 09:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #15255
dispatch-gates.mjs's self-test assertedchangesetPop.length >= 100against the liveworking tree. That population belongs to the release cycle, not to this tool: a changesets
version pass consumes all of it. So the control reds on the Version Packages PR — a
required context,
Lint & Repo Gates, on the one PR whose merge is the releasetrigger — and then on
mainfor as long as it takes 100 fresh changesets to accumulate.⛔ This PR does not merge, queue or auto-merge the Version Packages PR #11336, and pushes
nothing to
changeset-release/main. It lands the gate repair onmainas an ordinary PR.A correction to the card's premise, and why it changes the fix
The card reads the population on the release PR as
0. Measured instead: it is 1..changeset/README.mdsurvives a version pass, sob8573e843carries exactlyREADME.md+config.json(read via the contents API on that ref). That is why CIreported
1 of 1353 case(s) failedand not three — the other two corpus assertions aresatisfied by a one-file population.
This matters for the shape: a guard written as "skip when the population is
0" wouldstill have been red on the very tree it was written for. The size claim has to go, not
just be gated.
What replaces it
1, at 3 and at 865. The vacuity the
>= 100was guarding (everyover nothing,0 === 0) is closed by construction: they no longer run over an empty set at all.⊘line, a reason areader can check (
git ls-files '.changeset/'), and a tally repeated on the verdictline. It is never pushed into
cases, where it would be one more✓..changeset/config.json. While itis tracked, an empty population is this repo mid-cycle and the specimen is resting; when
it goes, the specimen has rotted and somebody must pick a new one. That is the
distinction "large" could not draw, and it is what stops a silent skip from letting the
specimen decay unnoticed.
hintReachesTree— takes thesame exit. Left unguarded it would have kept producing the release-blocking red after the
measured site stopped.
Measured readings
Each is a real run of
node scripts/pm/dispatch-gates.mjs --self-test, populations mutatedin an isolated scratch worktree (own index; this branch's tree was never mutated).
✓ 1363 cases pass.3c4728cb5)✓ 1363 cases pass.mainfor days after a release)✓ 1363 cases pass.— 0 skipped, corpus assertions ran✗ 1 of 1353 case(s) failed.— reproduces the CI red exactly✓ 1363 cases pass.— 0 skipped✓ 1359 cases pass. ⊘ 2 subject(s) NOT MEASURED …The pre-fix leg is the reverse verification: same tree, same command, only the script
swapped, and it fails on exactly the case the card names.
Gates
Derived on the final commit
3c4728cb5withnode scripts/pm/dispatch-gates.mjs(no pathspassed — the tool reads its own change set). All green:
check:pm-dispatch-gates(the self-test, 1363) ·check:nul-bytes·check:declared-population-live·check:ratchet-remedy-authority·check:watch-hint-literal·check:parse-guard·check:entry-guard·check:agent-test-spelling·check:cli-command-ids·check:cross-package-test-inputs·check:pm-half-states·check-self-test-wired·check-whole-set-label-write·check-closing-keyword-parity·check-comment-mask-corpus·measure-self-test-floorESLint was run over the whole repo, not narrowed:
eslint . --no-inline-config --format json→ 5877 files, 0 errors, 0 warnings.
Two readings that are not verdicts on this change:
check:bash32-floorfails 8 of 153 cases here — and fails identically on pristinemainin a separate checkout. A host-bash artifact of this macOS seat, not this diff.check-closing-keyword-parityandcheck-comment-mask-corpusfirst exited on their ownstated prerequisite (no
node_modules; the former exits 3 and says so explicitly). Thatis NOT MEASURED, not a finding. Both were re-run green after
pnpm install.Seat declaration
scripts/pm/os-verify-lock.shprinted, verbatim, on every heavy run of this card:So the wall-clock figures above are shared-box readings, not quiet-machine promises.
scripts/pm/**releases nothing from any package, so this carries theskip-changesetlabel rather than a
.changeset/*.mdentry — which would have been a small irony here.Generated by Claude Code