A rule that sees every package at once, and the build that feeds it Stacked on #7, and the last of the five. Review that first; this diff is against it. Adds `TestGenValidSpecPerGenValid` from `testing.md`, the flagship: for every `GenValid` instance, a `genValidSpec` call in the matching gen package's test suite. An obligation made and an obligation met are different facts, found in different packages, so the check between them is a left join and a null check. 128 files, 6,167 lines. 347 tests. ## Two things this rule needs that nothing before it did **The compiler.** A `GenValid` instance a splice produced appears in no source, and a `genValidSpec` call a splice produced appears in no source either, so each unmet obligation is put to the artifacts before it is reported. Reading them is its own package, because the `ghc` library and `ghc-lib-parser` both expose modules under `GHC.` and one component cannot import both. The artifacts are not optional. Given any `.hie` directories, every module read must have both a `.hie` and a `.hi` or the run fails naming the module, because a tree missing one module is indistinguishable at the point of use from no tree at all: both say nothing. **Every package at once**, which is what the process boundary is for. Facts cross it; source does not. A package is read once into a SQLite store and the project layer answers from those stores alone, so the Nix side is one derivation per package plus one for the repository, and changing one package rebuilds three derivations rather than all of them. That the two paths agree is a property in the suite, per project rule, so a fact a project rule reads out of memory and extraction never serialises fails the tests rather than the build. ## What else arrives here The Nix builders a consuming flake calls, the end to end tests over them, and `plan/`, which describes this architecture and so is only true once it exists. ## The corpus A row for `HsNoCustomShowRead`: 22 on nix-ci, 2 on sydtest, 1 on centjes, each checked by hand and recorded in `plan/context.md`. nix-ci's 22 are all `Show` written to keep a secret out of a log line, which is the exception `haskell-style.md` names, so they are suppressions to write rather than instances to change. NorfairKing/nix-ci#527 now does exactly that and its `hopinion` check passes. ## Review loop ``` nix flake check nix develop --command cabal test hopinion-test --test-options="--ai-executor" nix develop --command ./scripts/corpus-run.sh ./plan/scripts/check-plan.sh ```