The check suite consumes source files through two entirely separate channels,
and Phase 0 only hardened one of them.
`withSourceResolution` wraps `ssrLoadModule`, which covers the 159 module loads.
It does not and cannot see the other 30 sites, which read source as TEXT through
`readFileSync` to assert structural facts - "the panel imports no local
suggestion ranker", "no runtime path writes a definition". Renaming
`base44Client.js` to `.ts` is what surfaced the difference: ENOENT in the middle
of a suite that had been passing, from a line no grep for `ssrLoadModule` would
ever have found.
`resolveSourcePath()` in `ssr-resolve.mjs` reuses the existing `candidatesFor()`
ordering - the written path first, then `.ts`, then `.tsx` - and returns a path
relative to the root, so every call site keeps its `join(ROOT, ...)` as it was.
An unresolvable path comes back unchanged, which keeps the two absence
assertions honest: a check proving `store.js` is GONE still asks about the path
it means, and now also notices if the file returns under another extension.
Thirty-seven lines change, each a one-for-one replacement. No assertion text, no
record() message, no ordering, no logic.
The audit found the reads in four shapes, and two of them a path grep cannot
see:
- direct readFileSync(join(ROOT, 'src/x.jsx'), 'utf8')
- via a const const P = join(ROOT, 'src/x.jsx')
- dir + name ['node.js', 'patch.js'].map((f) => readFileSync(join(ROOT, 'src/lib/ui', f)))
- path array for (const f of files) readFileSync(join(ROOT, f))
The third and fourth hide thirteen filenames in adjacent arrays, which is why
the first estimate of this work was twenty-two files and the real number is
thirty-five.
One directory scan also filtered `/\.jsx?$/` over `src/pages/admin` and
`src/components/agents`. That one does not crash - it quietly matches nothing
once those directories are TypeScript, and the check passes having inspected an
empty set. Widened to `/\.[jt]sx?$/`. A silent shrink is worse than a failure,
and CI's FLOOR of 900 would not have caught it.
Deliberately NOT touched, because they are correctly extension-specific: the
`dist/assets` filter reads built bundles, which are `.js` whatever the source
was; `scripts/stubs/react-hot-toast.js` and `scripts/browser-flows.js` are
scripts, not migrated source; and every comment that mentions a `.js` filename
says something true about a file that still has that name.
Proven rather than assumed. `npm test` reports 1684/1691 before and after, the
same seven failures. Then `src/api/base44Client.js` - the exact file whose
rename broke the suite - was renamed to `.ts`, the suite re-run, and the check
that reads it as text passed: "the app does not import the seed fixture". The
rename was reverted and the file verified byte-identical.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBG1wnuRfJKCstGB8Fekr8