Skip to content

Commit 1e13012

Browse files
baozhoutaoclaude
andauthored
ci(lint): run the shared prerequisite frame's self-test (#14226)
`scripts/import-prerequisite.mjs` is the shared `PREREQUISITE NOT MET` frame 45 gates import, and its 60-case `--self-test` is the one place the inherited advisory — and, since #13983, the exit-code class those gates return — is pinned. Nothing ran it: `git grep -n "import-prerequisite" -- .github/workflows package.json` was empty, so the pin executed only when someone typed it. Wire it as a fourth leg of lint.yml's existing `scripts/ shared-module self-tests` tolerate-and-collect step, which already runs the same category of module self-test early in the job and reports a verdict per leg. Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV Co-authored-by: Claude <noreply@anthropic.com>
1 parent a35fb43 commit 1e13012

1 file changed

Lines changed: 50 additions & 12 deletions

File tree

.github/workflows/lint.yml

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)