Uh oh!
There was an error while loading. Please reload this page.
ci(lint): run the shared prerequisite frame's self-test - #14226
Merged
baozhoutao merged 1 commit intoSep 1, 2026
Conversation
`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. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
This was referenced Sep 1, 2026
baozhoutao
marked this pull request as ready for review
September 1, 2026 15:14
Uh oh!
There was an error while loading. Please reload this page.
baozhoutao
deleted the
claude/issue-14007-import-prerequisite-selftest-ci
branch
September 1, 2026 15:39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#14007
scripts/import-prerequisite.mjsis the sharedPREREQUISITE NOT METframe that 45 gates import (42 underscripts/**, 3 underpackages/lint/scripts/**). Its--self-testis the one place the inherited advisory is pinned — the module says so itself: "Pinned HERE and nowhere else, because this is the one copy 45 importers print." Since PR #14009 it also pins the exit-code CLASS those same 45 gates return for an unmet prerequisite. Nothing ran it.This wires it. One line of CI, plus the prose that keeps the line explicable.
The reading, re-verified on this branch before any edit
The card was filed against a 49-case self-test; the count is 60 now (PR #14009 and PR #14217, both merged). Sixty cases that executed only when a human or an agent typed the command by hand.
Why the wiring gate did not catch it, and why that is not a bug in the wiring gate
Quoting the card's load-bearing sentence verbatim, because it is the whole value of the finding:
check-self-test-wired's population is the scripts CI runs, and this file is a MODULE gates import, never a script a workflow invokes — so it sat in that gate's remainder by construction, with the gate correctly green. ⛔ Nothing here changes that gate's population rule, and ⛔ nothing here audits the rest of that remainder (a separate sweep card).Naming the module in a workflow step is the other, smaller remedy — and it is what moves the file INTO the population. Measured on this branch, same gate, same tree, before and after the step:
The 176-file
--self-testcorpus and the 220-filescripts/sweep are unchanged; only the "run by CI" count moves, which is exactly the claim being fixed. Full verdict lines under Gates below.Placement, and why
Chosen: a fourth leg of lint.yml's existing
scripts/ shared-module self-teststolerate-and-collect step, rather than a standalone step or thepackages/lintjob — that step is already the home forscripts/**shared modules whose behaviour is pinned only by their own self-test, it sits early in thelintjob, and its collector shape gives the new leg a verdict of its own whichever way the other three go. A standalone step further down would be masked by every gate above it (Actions skips a job's remaining steps once one fails) — the same defect one level up, and the splitcheck-step-collectorsexplicitly refuses as a remedy.No root
package.jsonalias: lint.yml's GATE INVOCATION IDIOM note makes the directnode scripts/X.mjs --self-testform the local convention, anddispatch-gates.mjsderives families from either spelling, so nothing is lost.Ablation — the wiring is load-bearing
The real
run:block was extracted out of lint.yml and driven under a realbash -e, exactly as Actions runs it. Mutation:EXIT_PREREQUISITE_NOT_MET = 3->1in the module — the very exit-code class PR #14009 established. Mutation confirmed on disk (anchor count 1 -> 0, injected marker present) before any reading was taken; restore pinned toHEADand verified byte-identical (git diff HEADempty, bloba7ccff1fon both sides).Before this PR that same mutation produced no CI signal at all.
A first mutation attempt is recorded rather than dropped: prefixing a string onto a local variable inside the self-test's own harness landed on disk and the self-test still passed. A mutation that is not load-bearing is not an ablation, so it was replaced with the one above rather than reported as a result.
Gates
Family derived from the real diff with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(23 families; no path list hand-fed to it — the script takes the change set from the merge base itself). All of them run, exit codes captured before any pipe, on496a99c2with a cleangit status --porcelain:The wiring gates' arithmetic did not break. The module moved from the remainder into the population and is wired inside it;
check-self-test-workflow-commands, which imports its membership fromcheck-self-test-wiredrather than re-deriving it, picked the new member up (162) and scanned real output; andcheck-step-collectors --self-testnow drives the four-command block under a realbash -e, asserting in every red position that each leg still runs and is named.Also green (exit 0):
check-aggregator-roster,check-position-name-fold-loaders,check-required-contexts,check-shard-attestation,check-whole-set-label-write,docs-audit/check-drift-comment,pm/ci-failure --self-test,check:agent-test-spelling,check:declared-population-live,check:node-version,check:pm-dispatch-gates,check:pnpm-acquisition,check:pnpm-filter-targets,check:required-contexts,check:shard-attestation,check:stall-guard-budget,check:stall-guard-headroom,check:type-check-coverage,check:workflow-status-functions,check:nul-bytes, plus both wiring gates' own--self-testlegs.Declared narrowing, one gate:
check:type-check-debtis NOT MEASURED here — it exited 3 (PREREQUISITE NOT MET, this very frame), refusing to--re-measurebecause 56 workspace dependencies have no built type entry point in this worktree. That is not a pass and not a finding. Its lint.yml-facing assertion — the--max-old-space-size=4096CI heap ceiling this file pins — is covered bycheck:type-check-coverage, which ran here and printedOK; and this diff edits no TypeScript, so it cannot move a DEBT or TEST_DEBT number in either direction. CI builds the closure before that step and runs it for real.skip-changeset: the diff is one workflow file, publishing nothing from any package.Card #14007 is fixed by this PR; no other card is addressed here.
Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
Generated by Claude Code