Appearance
import-graph-check.mjs
Proves that the live client cannot reach the design world, by walking the import graph rather than trusting a grep.
Contributor tooling › import-graph-check.mjs
What it does
Walks the import graph outward from the live entry app/src/game/main.jsx, following static imports and any dynamic import() edges it can resolve. It then asks which design-world modules that walk reached, and compares that set against a recorded baseline. A design-world module reachable from the live entry and absent from the baseline fails the run; so does a baseline entry the walk no longer reaches.
The design-world modules are named in the tool's own STRIP_LIST: the mock data source, the world populator, fleet motion, the highscore mock, and the simulation overrides. ADR-0010 abolishes the practice of filling live state with invented values. This check holds that line while the strip lands. The baseline is the list of crossings that still exist, and it is meant to shrink to nothing.
Usage
Run through its npm run alias:
bash
npm run imports:checkOr directly:
bash
node tools/import-graph-check.mjsOptions
| Flag | Value | What it does | Default |
|---|---|---|---|
--baseline | path | Reads the recorded crossings from this file instead of the default, resolved against the current working directory. The file must hold a JSON array of repository-relative module paths. | tools/import-graph-baseline.json. |
Inputs and outputs
Reads app/src/game/main.jsx and every module reachable from it with an .mjs, .jsx, .js, .ts or .tsx extension, staying inside app/src. Reads the baseline JSON. Writes nothing.
On success it exits 0 and prints one line naming how many design-world modules are recorded and confirming they all match the baseline. When the walk followed dynamic import() edges it lists each one first, as those are the edges a reader is least likely to have predicted.
On failure it exits 1. For a module that is reachable but unrecorded it prints the module and a witness: the chain of imports from the live entry that reaches it. The crossing is then found without re-deriving the path by hand. For a baseline entry that is no longer reachable it prints the module alone; that case means the strip has advanced and the baseline should lose a line. A closing line counts both kinds.
Examples
Run the check as the gate runs it, before a commit that touches client data plumbing:
bash
npm run imports:checkCheck a proposed baseline without moving the tracked one, which is how you confirm a strip slice removed exactly the crossings you meant it to:
bash
node tools/import-graph-check.mjs --baseline /tmp/proposed-baseline.jsonNotes
The walk blanks comments before scanning for import statements, so a JSDoc type reference such as import('./mock.mjs').GameData is not mistaken for a real edge. That matters here more than it would elsewhere: this codebase writes type casts inline, mid-statement, and a naive scan would report a crossing that does not exist at runtime.
A dynamic import() whose specifier is not a literal cannot be resolved and is not walked. The check is therefore a lower bound on reachability — it proves a crossing exists, never that none does. A computed import into the design world would pass, which is a reason to keep specifiers literal in client code.
The baseline records crossings that are known and tolerated, not crossings that are approved. Adding a line to it to make a red run green reverses the tool's purpose; the fix is to sever the import, and ADR-0010 is the record that says so.
Source
tools/import-graph-check.mjs — part of Contributor tooling