@@ -239,8 +239,9 @@ jobs:
239239 - name : Raw control-byte guard
240240 run : pnpm check:nul-bytes
241241
242- # The three shared modules the two `scripts/**` routing gates below
243- # DELEGATE their design arguments to (#10608). Both of those gates are
242+ # The first three of these are the shared modules the two `scripts/**`
243+ # routing gates below DELEGATE their design arguments to (#10608). Both of
244+ # those gates are
244245 # SPELLING gates by deliberate design — `check:entry-guard` enforces that
245246 # only `scripts/invoked-as.mjs` may read `process.argv[1]`, and
246247 # `check:parse-guard` that every TypeScript parse goes through
@@ -261,23 +262,59 @@ jobs:
261262 # own documentation — loud — while a mask that starts OVER-masking makes
262263 # both go quietly green over text they never read.
263264 #
264- # What runs here is the self-tests, not the modules' callers: the callers
265- # are the two gate steps below, which already run on every PR.
265+ # `import-prerequisite.mjs` is the FOURTH module here, from a different
266+ # family and for the same reason (#14007). It is not one of the #10608
267+ # delegates — it is the shared `PREREQUISITE NOT MET` frame that 45 gates
268+ # IMPORT (42 under `scripts/**`, 3 under `packages/lint/scripts/**`), and
269+ # its `--self-test` is the ONE place the inherited advisory is pinned. The
270+ # module says so itself: *"Pinned HERE and nowhere else, because this is
271+ # the one copy 45 importers print."* Since #13983 the same self-test also
272+ # pins the exit-code CLASS those 45 gates return for an unmet prerequisite
273+ # (`EXIT_PREREQUISITE_NOT_MET`, distinct from a gate's own findings exit).
274+ # Nothing ran it: `git grep -n "import-prerequisite" -- .github/workflows
275+ # package.json` was EMPTY, so 60 cases executed only when a human or an
276+ # agent typed the command by hand.
277+ #
278+ # ⛔ NOT a hole in `check:self-test-wired`, whose green is correct by its
279+ # own definition: its population is the scripts CI RUNS, and this file is a
280+ # MODULE no workflow can invoke, so it sat in that gate's remainder by
281+ # construction. The blast radius and the population rule point in opposite
282+ # directions here: the file with the largest inheritance surface in the
283+ # farm is the one shape the wiring gate cannot see. Naming it in this step
284+ # is what moves it INTO that population (161 -> 162 scripts CI runs that
285+ # ship a `--self-test`), and it is the smaller of the two remedies — the
286+ # other being to widen the gate to a transitive closure, which #14007
287+ # explicitly does not ask for. ⛔ It is also not a licence to sweep the
288+ # rest of that remainder from here; that is a separate card.
289+ #
290+ # What runs here is the self-tests, not the modules' callers: for the first
291+ # three the callers are the two gate steps below, which already run on
292+ # every PR; for `import-prerequisite` the callers are the 45 importing
293+ # gates, whose ordinary runs take the branch where the dependency IS
294+ # present and therefore observe none of what the self-test pins.
266295 # Invoked as `node` rather than through `pnpm check:*`: see the GATE
267296 # INVOCATION IDIOM note at the top of this file.
268297 # `ts-parse` spawns ~20 real node children (~10 s measured, and the spawns
269298 # are the point — they pin that a caller's try/catch cannot swallow the
270- # refusal); the other two are in-process fixtures, ~0.5 s combined.
299+ # refusal); the other three are in-process fixtures, ~0.6 s combined.
271300 #
272301 # ⭐ Collected rather than sequenced, for the reason spelled out at the
273302 # `Shallow-history guard self-tests` step below (#10814): under `bash -e` a
274303 # bare sequence stops at the first failure, so a red `ts-parse` would leave
275- # the entry-predicate and comment-mask self-tests UNRUN while the log shows
276- # only the one failure. `ts-parse` is both the slowest of the three and the
277- # one that spawns real children, so it is the likeliest to be red —
278- # precisely the masking direction. The three modules are independent of one
279- # another, so collecting loses nothing.
280- - name : scripts/ shared-module self-tests (parse · entry predicate · comment mask)
304+ # the entry-predicate, comment-mask and prerequisite-frame self-tests UNRUN
305+ # while the log shows only the one failure. `ts-parse` is both the slowest
306+ # of the four and the one that spawns real children, so it is the likeliest
307+ # to be red — precisely the masking direction. The four modules are
308+ # independent of one another, so collecting loses nothing.
309+ #
310+ # ⭐ Collected is also why the fourth leg is HERE rather than in a step of
311+ # its own: Actions skips a job's remaining steps once a step fails, so a
312+ # standalone step further down this job would be masked by every gate above
313+ # it — the same defect one level up, and the split `check-step-collectors`
314+ # explicitly refuses as a remedy. Inside this block the frame's self-test
315+ # prints its own verdict whatever the other three do, and it does so early
316+ # in the job.
317+ - name : scripts/ shared-module self-tests (parse · entry predicate · comment mask · prerequisite frame)
281318 run : |
282319 # Tolerate-and-collect (#10814) — see the note above this step. Each
283320 # self-test runs unconditionally and prints its own verdict; the step
@@ -300,13 +337,14 @@ jobs:
300337 run_self_test node scripts/ts-parse.mjs --self-test
301338 run_self_test node scripts/invoked-as.mjs --self-test
302339 run_self_test node scripts/js-comment-mask.mjs --self-test
340+ run_self_test node scripts/import-prerequisite.mjs --self-test
303341 if [ -n "$failed" ]; then
304342 echo ""
305343 echo "scripts/ shared-module self-tests — the following FAILED:"
306344 printf "%s" "$failed"
307345 exit 1
308346 fi
309- echo "scripts/ shared-module self-tests — all three ran and passed"
347+ echo "scripts/ shared-module self-tests — all four ran and passed"
310348
311349 # Every `scripts/**` entry guard goes through ONE predicate (#10086).
312350 # The hand-typed forms of "did node run me, or did someone import me?"
0 commit comments