A rule that sees a whole package Replaces #7, which GitHub will not let me reopen: I merged it by mistake and then took it back off master. Stacked on #10. Review that first; this diff is against it. Adds `HsGenValidInGenPackage` from `haskell-style.md`, the first rule that cannot answer from one module, and with it the fact store that lets a rule see further. 39 files, 1,220 lines. 257 tests. ## Why a database What a rule above the module level does with facts is join them. One table per fact, owned by the rule that writes it, so a rule brings its own schema the way it brings its own check. The envelope never learns what is in that table, which is why adding a rule adds no case to it: a package rule is a migration, what it writes out of one module, and the query it answers with. A fact is a row rather than a keyed entry. Two instances in one module are two facts, and there is nothing to key them on that is not invented. Where the store lives is a two-constructor type rather than a string, because `:memory:` is not a file name: it is SQLite's word for having no file at all. ## The level A rule's constructor is also its level, so nothing can disagree with it. Each level judges exactly the suppressions naming its own rules, which is what keeps unused-suppression detection sound without a global pass over the repository. ## Still not here One process, so the store has nowhere to go and nothing crosses a process boundary. Nothing reads what the compiler wrote down: the package check's signature does not take the compiler's answers, because this rule has no use for them. weeder removed seven store queries on the way in that only a project rule would want. ## What #9 handed over The store is what needs a fact written down, so the serialisation arrives with it: - The `PersistField`/`PersistFieldSql` instances on the name and place types, and with them the `persistent` dependency. #9 had them with no database, which is what dragged `persistent`, `path-pieces` and `http-api-data` into a tool that never opened a connection. - `parseSpan` and `parseModuleRef`, which exist so a column can be read back. - The `HasCodec` instances on `InstanceFact`, `InstanceOrigin`, `ParseOutcome`, `ComponentKind`, `TypeHead` and `PackageName`. Nothing serialised a fact before this. - `packageModelDataPaths`, `componentModelDeclaredModules` and `componentModelSourceDirs`, which were assigned and never read in #9. ## Review loop ``` nix flake check nix develop --command cabal test hopinion-test --test-options="--ai-executor" ```