Uh oh!
There was an error while loading. Please reload this page.
test(pm): run the dispatch-gates self-test in CI and anchor its convention-gate pins - #8477
Merged
Merged
Conversation
…ntion-gate pins The dispatch-gates tool carried a 61-case --self-test that no CI job ran, and its test-file convention-gate names were pinned by bare substring, so a prefix-preserving rename passed the pin that exists to catch it. - new gate check:pm-dispatch-gates, wired as an unconditional step in lint.yml beside the other two scripts/pm gates; runs the self-test only - the gate lives in its own file so the tool's fixture path literals do not become watch hints and fabricate MATCHED leads across the tree - both halves of the test-file entry's name pin now anchor on the rendered delimiters, matching the i18n entry's pins in the same file Fixes#8162Fixes#8364 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018WuTtyckQa1VcXwgd52JpN
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
hotlong
marked this pull request as ready for review
August 13, 2026 15:38
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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#8162
Fixes#8364
Two halves of one file's problem: the dispatch-gates self-test ran nowhere, and where it did pin the convention-gate names it pinned them by bare substring.
Part 1 — the self-test now runs in CI
Direction 1 (a dedicated
check:pm-dispatch-gates, self-test only), not direction 2 (one job folding everyscripts/pm/**self-test). Why:scripts/pm/gates are each their owncheck:*script with their own named step in the ESLint job (check:pm-skill-ratchet,check:pm-skill-id-lint). Direction 2 would have had to restructure both to fold them in — other jobs' surface, for no gain today.run:body. A folded loop overscripts/pm/*.mjsrenders as one opaque step naming no family, so the very tool being wired could never discover its own gate. A namedpnpm check:pm-dispatch-gatesstep is discovered — measured below.pr-automation.ymland walks the real packages tree), so the derivation's contact with reality is gated too.The step is deliberately unconditional — no
if:, no label read, no paths filter — matching theChangeset-family gate self-testsstep it sits near, for the reason that step's comment gives: an exemption is what a self-test must not have, or the gap just moves.Why the gate is its own file (measured, not stylistic)
The obvious spelling is
"check:pm-dispatch-gates": "node scripts/pm/dispatch-gates.mjs --self-test". That is the one shape this tool cannot have. The derivation resolves a check family to its script file and scans that file for the path literals it operates on — and this tool's tests are made of path strings. Measured on the tree: 49 literals extracted fromdispatch-gates.mjs, of which 2 name inputs it really reads and 43 are self-test fixtures naming other packages (packages/spec/src,packages/objectql,packages/plugins,packages/drivers,.claude/agents,.changeset, ...). Wired directly, the derivation printed, for a card touching spec's filter schema:A fabricated lead in the column the tool's contract reserves for high-signal answers, on most of the tree — exactly what its header rejects ("22 leads is the same as none"). So the gate is
scripts/pm/check-dispatch-gates.mjs, the same shape as the other two pm gates, whose only watch hint is the tool it runs. After the change the same three probes are clean:packages/spec/src/data/filter.zod.tspackages/objectql/src/engine.ts.claude/agents/os-dev.mdscripts/pm/dispatch-gates.mjsA note worth keeping, because the first draft of that file did it: watch-hint extraction reads any quoted span, backticks included, and does not skip comments — so a header written the ordinary way, with each path in backticks, reproduced ten of the false hints from the very file explaining the pollution. That file now names paths unquoted and says why.
Proof the wiring runs
pnpm check:pm-dispatch-gates— green, 61/61 cases, 0.12s.CHANGE_KIND_GATESname mutated, the gate exits 1 and prints1 of 61 case(s) failed. Restored, exit 0. (A gate proven only green is a gate not proven at all.)One honest deviation from the card's suggested probe:
node scripts/pm/dispatch-gates.mjs .github/workflows/lint.ymlshows the new family only in the discovered count (90 to 91), not in the matched list, because the gate does not readlint.yml— it reads the tool. Naming.github/workflowsas a hint would have made that probe print prettier by claiming an input the gate does not have.Part 2 — the convention-gate pins are anchored
Both halves of the test-file entry's name assertion now anchor on the rendered delimiters (
- pnpm x —), the shape the i18n entry's pins in the same file already use. The two conventions in one file no longer disagree.Reverse-verified in the direction predicted before running it — rename both gates in
CHANGE_KIND_GATESto prefix-preserving-v2names, from a committed fix so restoring came out of a real commit:includes(origin/main)STALE, correctly✗ the section names both convention gates, runnablyLeg A is the defect verbatim: the pin stays green through the one rot class the STALE branch exists to report.
Verification
Union of the PM's dispatch list and a re-derivation against the actual diff (
node scripts/pm/dispatch-gates.mjsover the four changed paths). All green:check:pm-dispatch-gates,check:changeset-gate-self-tests,check:filter-alias-parity,check:node-version,check:nul-bytes,check:required-contexts,check:shard-attestation,check:type-check-coverage,check:type-source-resolution,check:workflow-status-functions,node scripts/check-changeset-no-major.mjs,node scripts/check-empty-changeset.mjs, pluseslinton both scripts.The re-derivation added
node scripts/check-empty-changeset.mjs(its consumer block asserts this job's step shape, so a step insertion is its business) andnode scripts/check-shard-attestation.mjsover the PM's list; both green.check:type-check-debtis the one gate not runnable here: its--re-measurehalf refuses to run in a tree whose workspace closure is unbuilt (55 dependencies with no built type entry point) rather than measure a different world, andlint.ymlbuilds that closure in the step immediately before it. Its--self-testand thecheck-type-check-coveragewiring half both ran green; this diff contains no TypeScript, so no ledger input moved.No changeset: PM tooling plus CI config, nothing released —
skip-changeset.Out of scope, filed
#8478 — the general form of the watch-hint pollution measured above: fixture and comment literals become hints in other check scripts too (
check-adr-0087-registration.mjsmatchespackages/runtime,check-empty-changeset.mjsmatchesskills/demo/SKILL.md). This PR sidesteps it for one gate; it does not fix it. #8478 remains open and is not addressed here.Generated by Claude Code