Found while reverse-verifying #8352 (PR #8363), measured rather than reasoned.
CHANGE_KIND_GATES entries carry a STALE branch: a gate name that no workflow run discovers is printed as ⚠ NAME: STALE — … fix CHANGE_KIND_GATES in this script, so a hand-written table reports its own rot instead of quietly aging. The self-test is supposed to pin that branch.
The gap
scripts/pm/dispatch-gates.mjs:392 pins the test-file entry's gate names by substring:
t('the section names both convention gates, runnably',kindHit.some((l)=>l.includes('pnpm check:query-options-erasure'))&&…);includes is satisfied by every name that merely starts with the expected one. Rename the gate to check:query-options-erasure-v2 and the rendered line becomes - pnpm check:query-options-erasure-v2 — …, which still contains the searched substring — the pin stays green through exactly the rename class the STALE branch exists to report.
This is measured, not hypothetical: the identical shape was written for the i18n entry in PR #8363, and renaming that gate to check:i18n-renamed-probe left the self-test green at 47/47 while the live run correctly printed STALE. Anchoring on the rendered delimiters (- pnpm x —) made the same break fail 2 cases.
Scope
scripts/pm/dispatch-gates.mjs only — one assertion on line 392 (the check:type-check-coverage half of the same line has the same shape). PR #8363 tightened the i18n entry's two pins and deliberately did not touch this pre-existing one, to keep that PR inside its card's scope; the two conventions now sit side by side in one file, which is its own small reason to reconcile them.
Note the STALE mechanism itself is fine — this is about the test that guards it. Severity is low: it only misleads when someone renames a gate to a longer name sharing the old prefix.
Generated by Claude Code
Found while reverse-verifying #8352 (PR #8363), measured rather than reasoned.
CHANGE_KIND_GATESentries carry a STALE branch: a gate name that no workflow run discovers is printed as⚠ NAME: STALE — … fix CHANGE_KIND_GATES in this script, so a hand-written table reports its own rot instead of quietly aging. The self-test is supposed to pin that branch.The gap
scripts/pm/dispatch-gates.mjs:392pins the test-file entry's gate names by substring:includesis satisfied by every name that merely starts with the expected one. Rename the gate tocheck:query-options-erasure-v2and the rendered line becomes- pnpm check:query-options-erasure-v2 — …, which still contains the searched substring — the pin stays green through exactly the rename class the STALE branch exists to report.This is measured, not hypothetical: the identical shape was written for the i18n entry in PR #8363, and renaming that gate to
check:i18n-renamed-probeleft the self-test green at 47/47 while the live run correctly printed STALE. Anchoring on the rendered delimiters (- pnpm x —) made the same break fail 2 cases.Scope
scripts/pm/dispatch-gates.mjsonly — one assertion on line 392 (thecheck:type-check-coveragehalf of the same line has the same shape). PR #8363 tightened the i18n entry's two pins and deliberately did not touch this pre-existing one, to keep that PR inside its card's scope; the two conventions now sit side by side in one file, which is its own small reason to reconcile them.Note the STALE mechanism itself is fine — this is about the test that guards it. Severity is low: it only misleads when someone renames a gate to a longer name sharing the old prefix.
Generated by Claude Code