Trust
Every gen library’s test suite runs on each push under upstream Nix, Determinate Nix and Lix, each pinned to its latest release. This page lists the other guarantees gen makes and the check behind each one, so you can decide whether to build on it.
What gen guarantees
Section titled “What gen guarantees”| Guarantee | Checked by |
|---|---|
| Every library works under upstream Nix, Determinate Nix and Lix | Each library’s CI runs its checks under all three on every push and pull request |
No library imports nixpkgs.lib | A source scan in every library’s test suite |
gen’s module system agrees with nixpkgs’ lib.evalModules on the grammar they share | A differential test suite in gen-merge |
| Every merged value records which file set it, and at what priority | gen-merge’s test suite |
| An incremental rebuild gives the same output as a full one | Byte-identity checks in gen-memo’s suite and in the benchmark harness |
| A faster change cannot ship with a wrong result | Every benchmark checks byte-identical output before it compares cost |
Three evaluators
Section titled “Three evaluators”The shared CI workflow lives in gen-harness. Each library calls
it, and it runs the library’s nix flake check once per evaluator. Determinate Nix runs with lazy
trees enabled, and the workflow checks that it is. A failure under one evaluator does not stop the
other two, so a red run shows every evaluator that failed.
No nixpkgs.lib
Section titled “No nixpkgs.lib”gen’s libraries use no part of nixpkgs. gen-merge is a module system of its own, with its own
mkOption, mkMerge and types. Each library’s suite has a purity test that reads the library’s
source with comments removed, and fails if it finds a nixpkgs call such as lib.evalModules or
lib.mkOption. gen-types also tests that the scan catches a planted violation.
nixpkgs enters only where your configuration is handed to a terminal you supply, such as a NixOS system builder.
Compatibility with the nixpkgs module system
Section titled “Compatibility with the nixpkgs module system”gen-merge’s ci/tests/differential.nix evaluates the same modules with gen-merge and with nixpkgs’
lib.evalModules, and fails when the two disagree on the grammar they share: options,
priorities, mkIf, mkMerge, freeform types and submodules. The hub’s rehost-den-parity check runs a real host
registry through gen’s stack and through the nixpkgs stack it replaced, and requires byte-identical
output for every instance and field. The one field outside that comparison is id_hash, whose
encoding differs between the two stacks. gen-schema’s own suite checks it.
No check yet compares the aspect grammar against a reference.
Knowing where a value came from
Section titled “Knowing where a value came from”evalModuleTree returns a provenance record beside the merged config. For each option it lists
the file that won, its priority, and every definition that took part. A test checks that reading
provenance never forces the values it describes.
Incremental rebuilds
Section titled “Incremental rebuilds”A warm run reuses results from an earlier run after an edit. gen-memo’s suite requires the warm output to be byte-identical to a cold run of the same input, and the warm trace says whether anything was reused. Benchmarks shows how much work reuse saves.
Running the checks yourself
Section titled “Running the checks yourself”Clone any library and run its suite from the repository root:
nix develop ./ci --command ciFrom the hub’s root, nix flake check ./ci runs the hub’s own checks, including
rehost-den-parity, and nix run ./ci#perf-bench runs the benchmark gates.
Palettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).