You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[finding] the three i18n gates pin neither their prerequisite exit code nor their advisory text, while the four sibling gates that answer the same words all do #14857
Found while landing #14008 + #13825 (PR #14856), which moved the PREREQUISITE NOT MET exit code in these three gates from 1 to 3. Out of scope there: that PR's file surface was fixed by triage to the refusal sites and one lane-doc sentence, and adding a pin means extracting a pure text function, which is a shape change rather than a value change.
The reading
Four gates in this repo pin their prerequisite refusal — the exit code AND the advisory text — from their own --self-test, because each first extracted the message into a pure function so the assertion can run without spawning a process or stubbing process.exit:
scripts/import-prerequisite.mjs — prerequisiteNotMetText(), and selfTest asserts EXIT_PREREQUISITE_NOT_MET === 3, that it differs from EXIT_FINDINGS and from 0, and that the rendered advisory contains both numbers.
scripts/check-test-completeness.mjs — invocationVerdict() returns { exit, lines }, and the self-test asserts the refusal's exit is the prerequisite code and has not regressed to the findings code.
scripts/check-release-section-coverage.mjs — same shape.
scripts/check-type-check-coverage.mjs — same shape, plus a case labelled "the refusal code is 3".
The three gates PR #14856 just moved have no such pin, in any of the five refusal paths:
In each, the printer builds its string inline inside console.error(...) and calls process.exit(...) on the next line, so there is no value for a test to read. Measured on fcdbc6d2: grep -n "Exit code" scripts/check-i18n-coverage.mjs scripts/check-i18n-bundles.mjs packages/cli/scripts/check-app-nav-i18n.mjs finds the advisories, and nothing in any selfTest() in those files mentions an exit code at all.
Why it is worth a line
check-i18n-coverage.mjs --self-test does prove its classifiers go red, and says so in its pass line. That reads like coverage of the refusal and is not: the classifiers are pure functions over strings that decide which verdict fires, and they are green whatever number the printer beside them returns.
So the value PR #14856 just moved is unpinned in all three files. A later edit can move it back to 1, or let the printed Exit code N drift away from the process.exit(N) six lines below it, and every gate stays green — which is the exact failure import-prerequisite.mjs's constant docblock argues against ("the self-test pins the value each path actually returns instead of a comment about it").
Not claimed
⛔ No severity claim and no recommendation on ordering. The four sibling gates arrived at the pin one at a time, and whether this is worth the extraction here is triage's call.
The two coverage paths behind the CLI-build probe (COULD NOT MEASURE, POPULATION EMPTY) are unreachable without a build and unpinned, so they are the two that no local run and no test currently observes at all.
Found while landing #14008 + #13825 (PR #14856), which moved the
PREREQUISITE NOT METexit code in these three gates from 1 to 3. Out of scope there: that PR's file surface was fixed by triage to the refusal sites and one lane-doc sentence, and adding a pin means extracting a pure text function, which is a shape change rather than a value change.The reading
Four gates in this repo pin their prerequisite refusal — the exit code AND the advisory text — from their own
--self-test, because each first extracted the message into a pure function so the assertion can run without spawning a process or stubbingprocess.exit:scripts/import-prerequisite.mjs—prerequisiteNotMetText(), andselfTestassertsEXIT_PREREQUISITE_NOT_MET === 3, that it differs fromEXIT_FINDINGSand from 0, and that the rendered advisory contains both numbers.scripts/check-test-completeness.mjs—invocationVerdict()returns{ exit, lines }, and the self-test asserts the refusal'sexitis the prerequisite code and has not regressed to the findings code.scripts/check-release-section-coverage.mjs— same shape.scripts/check-type-check-coverage.mjs— same shape, plus a case labelled "the refusal code is 3".The three gates PR #14856 just moved have no such pin, in any of the five refusal paths:
scripts/check-i18n-coverage.mjs— 3 pathsscripts/check-i18n-bundles.mjs— 1 pathpackages/cli/scripts/check-app-nav-i18n.mjs— 1 pathIn each, the printer builds its string inline inside
console.error(...)and callsprocess.exit(...)on the next line, so there is no value for a test to read. Measured onfcdbc6d2:grep -n "Exit code" scripts/check-i18n-coverage.mjs scripts/check-i18n-bundles.mjs packages/cli/scripts/check-app-nav-i18n.mjsfinds the advisories, and nothing in anyselfTest()in those files mentions an exit code at all.Why it is worth a line
check-i18n-coverage.mjs --self-testdoes prove its classifiers go red, and says so in its pass line. That reads like coverage of the refusal and is not: the classifiers are pure functions over strings that decide which verdict fires, and they are green whatever number the printer beside them returns.So the value PR #14856 just moved is unpinned in all three files. A later edit can move it back to 1, or let the printed
Exit code Ndrift away from theprocess.exit(N)six lines below it, and every gate stays green — which is the exact failureimport-prerequisite.mjs's constant docblock argues against ("the self-test pins the value each path actually returns instead of a comment about it").Not claimed
COULD NOT MEASURE,POPULATION EMPTY) are unreachable without a build and unpinned, so they are the two that no local run and no test currently observes at all.Generated by Claude Code