98b0d082

By: Tom Sydney Kerckhove <syd@cs-syd.eu>

A rule that sees every package at once, and the build that feeds it

Stacked on the package PR. Adds TestGenValidSpecPerGenValid from testing.md,
which is 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.

That rule needs two things nothing before it did.

It needs 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.

It needs to see 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.

With it come the Nix builders a consuming flake calls, the end to end tests
over them, and the plan documents, which describe this architecture and so are
only true once it exists.

The corpus gains 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 hide a secret, which is the exception haskell-style.md
names, so they are suppressions to write rather than instances to change.

Suite timing

Time to Start Worker time Duration Time to finish Idle
Config 3m24s 1s 1s 3m25s 3m24s
Eval 3m47s 18s 18s 4m05s 21s
Build 3m56s 47s 3m53s 7m50s 3m11s
Suite 3m24s 1m06s 4m25s 7m50s 6m57s

Timeline

0s3m50s4m5m30s7m30s7m40s7m50s