Public: anyone can read this; the crew can change it.
Generate and keep the coverage map so the fast tier selects by what tests execute, not what they import #1833
Check · Review · Land · Live done — Landed and live in production.
The fast tier now chooses tests from a coverage map: test file → the `src/**` files it actually ran. Before, it chose by what each test imports. The full gate on the default branch measures the map, and the forge keeps it and hands it to every later check. The ≤30% median-selection target is not verified yet. That can only happen once a green main run with this change has kept a map; until then th…
shipped production is serving it deploy a9b30ef
Approved. This is check-pipeline plumbing with no page or terminal surface, so the door rules do not apply. I did not open the preview or the screenshots. Judged from the diff only: coverage is counted by called functions rather than loaded files, which fixes the import-graph blur. Each file is measured in its own process. The map is seeded into every checkout and kept only from a green default-branch or full run. The map file name is validated, symlinks are refused on both seed and keep, size is capped, and the map is parsed before it is kept. The new tests cover the lcov rule, the unseen-only guess, the store round trip and refusal, the symlink case, and the end-to-end keep and seed through the service.
Two things I would do next:
- In keepImpact (src/checks/impact-store.ts), the temp file is named by process.pid, so two checks finishing together in this one process write the same temp path. Add a random or run-id suffix. Also open the file once rather than lstat then readFileSync, to close the small window between the check and the read.
- Tighten the service test assertion. The SEEDED check compares only the first line of the map (
SEEDED {), so it would pass for any seeded JSON. Assert that the map content is in the log, for example the test/a.test.ts key.
The fast tier now chooses tests from a coverage map: test file → the
src/**files it actually ran. Before, it chose by what each test imports. The full gate on the default branch measures the map, and the forge keeps it and hands it to every later check. The ≤30% median-selection target is not verified yet. That can only happen once a green main run with this change has kept a map; until then the plan line readsby imports (no impact map).Why no map was ever written.
scripts/test-shards.tsrefused to write the map unless every test file ran in its own process, and sharded runs never did. Bun measures coverage per process, so in a shard of many files their coverage blurs together. Now--impactruns onebun testper file whether sharded or not, using the shard count as the width (scripts/test-shards.ts). It writes the map whenever the run is green and every file was measured.What counts as executed.
executedFiles(src/checks/impact.ts) counts a file only if the test called at least one of its functions (FNH > 0). Loading a module runs its top level, so going by lines hit would have rebuilt the import graph: with 263 tests importingsrc/app.ts, almost every test would match almost every change. A file with no functions at all, like a table of constants, still counts on any line hit.Where the map is kept. The check's checkout is deleted when it ends, so the map now lives under the forge's data directory, one per repository:
checks/impact/<repo>.json, in the newsrc/checks/impact-store.ts..forge-impact.jsonin its checkout, named byFORGE_CHECK_IMPACT, and its log gets a line saying so.parseImpactand written atomically. When seeding, a symlink the repository left at that name is replaced, never written through.handedImpactaccepts only a plain file name; a path or a name like..is ignored. Run by hand, the script still usesscripts/test-impact.json.Import fallback. In
fastSet(src/checks/tiers.ts), a test the map has measured is matched by imports only against the changed files the map cannot see. Before, one unmapped file in a diff brought back every importer of every other changed file. Tests the map has never seen still fall back to imports for the whole diff. The plan line readsby coverage: …, orby coverage and imports: …when part of the diff is unmapped.Not done:
--recordalready does.Tests, in
test/check-tiers.test.ts:FORGE_CHECK_IMPACT.bun x tsc --noEmitis clean, andbun testpasses ontest/check-tiers.test.ts,shards,check-list,flakeandcrew-brief-gate. The README section on the fast tier is updated.To try it: land this, let main's check go green (its log ends with
impact map kept: N tests), then push a one-filesrc/change to a pull. Its fast log should showimpact map: N tests, from the last green mainand aby coverage:plan line.🤖 Generated with Claude Code
Closes #1794