Filed out-of-scope from work on #16147 (the resolver's region-level page:header route). Not touched there; filed unassigned.
The defect
scripts/check-i18n-walk-parity.mjs refuses correctly when its inputs are not built, prints the right words, and then returns the wrong number:
/** A hard prerequisite failure: says what it did NOT measure, and exits. */
function reportPrerequisiteNotMet(headline, lines) {
console.error(` check:i18n-walk-parity — PREREQUISITE NOT MET: ${headline}\n`);
...
process.exit(1);
}
Exit 1 is the finding code. This repo already has one answer to that, with a name and a self-test: EXIT_PREREQUISITE_NOT_MET === 3 in scripts/import-prerequisite.mjs, whose own header states the reason in as many words:
Exit 1 from an unmet prerequisite and exit 1 from a real finding are the same reading — which is why the guarded refusal below does NOT keep that number.
Its siblings import it. Two of them are in this very family: check-i18n-bundles.mjs and check-i18n-coverage.mjs, plus check-dts-closure.mjs and check-doc-frontmatter.mjs. check-i18n-walk-parity.mjs is the one that spells the same headline by hand and keeps exit 1.
Measured, on a fresh per-task worktree
A gate sweep over the derived family list on a worktree where the dependency closure was built but packages/cli itself was not, exit codes captured before any pipe:
50 exit=3 pnpm check:dual-build-cjs-loads <- PREREQUISITE NOT MET, reads as NOT MEASURED
52 exit=1 pnpm check:i18n-walk-parity <- PREREQUISITE NOT MET, reads as a FINDING
67 exit=3 pnpm check:type-check-debt <- PREREQUISITE NOT MET, reads as NOT MEASURED
All three refused for the same reason. Two are legible as NOT MEASURED from the number alone; the middle one is not. Its stderr does say so — but the number is what a sweep, a runner script, or a CI step condition reads, and it is the reading a seat writes into a report. The failure direction is a false RED reported against whatever landed most recently, which is exactly the near-miss import-prerequisite.mjs records as its reason for existing.
Repro
git worktree add --no-track ../objectstack-probe -b probe origin/main
cd ../objectstack-probe && pnpm install # closure NOT built
pnpm check:i18n-walk-parity > /tmp/out.log 2>&1; echo "EXIT=$?"
# EXIT=1, with "PREREQUISITE NOT MET: the workspace CLI is not built" in the log
Suggested direction, for whoever takes it
Route the refusal through the shared helper rather than re-spelling it: import EXIT_PREREQUISITE_NOT_MET (and EXIT_FINDINGS) from scripts/import-prerequisite.mjs and return that code, the way check-dts-closure.mjs does — which also gets the shared "capture the code BEFORE any pipe" frame in the output for free. A self-test case asserting the refusal's code is 3 and is not the findings code would pin it; check-doc-frontmatter.mjs already carries a case in that exact shape.
Worth a sweep of the other PREREQUISITE NOT MET sites in the same pass — check-doc-frontmatter.mjs also has a hand-written exit(1) near its refusal text, unverified here as to whether it is on the refusal path or a different branch. That is a reading this card does not make.
Filed out-of-scope from work on #16147 (the resolver's region-level
page:headerroute). Not touched there; filed unassigned.The defect
scripts/check-i18n-walk-parity.mjsrefuses correctly when its inputs are not built, prints the right words, and then returns the wrong number:Exit 1 is the finding code. This repo already has one answer to that, with a name and a self-test:
EXIT_PREREQUISITE_NOT_MET === 3inscripts/import-prerequisite.mjs, whose own header states the reason in as many words:Its siblings import it. Two of them are in this very family:
check-i18n-bundles.mjsandcheck-i18n-coverage.mjs, pluscheck-dts-closure.mjsandcheck-doc-frontmatter.mjs.check-i18n-walk-parity.mjsis the one that spells the same headline by hand and keeps exit 1.Measured, on a fresh per-task worktree
A gate sweep over the derived family list on a worktree where the dependency closure was built but
packages/cliitself was not, exit codes captured before any pipe:All three refused for the same reason. Two are legible as NOT MEASURED from the number alone; the middle one is not. Its stderr does say so — but the number is what a sweep, a runner script, or a CI step condition reads, and it is the reading a seat writes into a report. The failure direction is a false RED reported against whatever landed most recently, which is exactly the near-miss
import-prerequisite.mjsrecords as its reason for existing.Repro
Suggested direction, for whoever takes it
Route the refusal through the shared helper rather than re-spelling it: import
EXIT_PREREQUISITE_NOT_MET(andEXIT_FINDINGS) fromscripts/import-prerequisite.mjsand return that code, the waycheck-dts-closure.mjsdoes — which also gets the shared "capture the code BEFORE any pipe" frame in the output for free. A self-test case asserting the refusal's code is 3 and is not the findings code would pin it;check-doc-frontmatter.mjsalready carries a case in that exact shape.Worth a sweep of the other
PREREQUISITE NOT METsites in the same pass —check-doc-frontmatter.mjsalso has a hand-writtenexit(1)near its refusal text, unverified here as to whether it is on the refusal path or a different branch. That is a reading this card does not make.