Skip to content

Record what each evaluator received as declaration events - #126

Merged
clhodapp merged 2 commits into
mainfrom
feat/declaration-events
Oct 20, 2026
Merged

clhodapp merged 2 commits into
mainfrom
feat/declaration-events

Conversation

@clhodapp

@clhodapp clhodapp commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Builds on nix-caisson/caisson-core#51, merged, which gives every configuration manifest a history. This branch pins caisson-core to main, which has it.

caisson fills each configuration's history with a declaration event for each module its evaluator received, in that order. For the NixOS configuration of the pinned-world machine, the events are:

Key Origin
nixos nixpkgs: nixos/modules/module-list.nix (NixOS' module list, a single event)
caisson.nixos caisson: modules/nixos/core
modules.nixos.caisson/core project caisson
modules.nixos.caisson/default project caisson
inline/4 the configuration's module
caisson.nixos.pkgSet caisson's module that hands NixOS the package set

Keys. lib.caisson.modules now hands out each registered module inside a module keyed modules.<class>.<name>@<project>, so an evaluation knows which registry entry each module is. The module system imports modules that share a key once, so a registry entry an evaluation selects twice is imported once. Before, it was imported twice, which either failed or doubled its list definitions. The project is part of the key because the same name can be registered by different projects in the registries an evaluation reads. The tree has a local home-manager-activation in a unit test, and caisson's integrations add their own through caisson's closure. Without the project in the key, the module system would drop one of them silently.

Integrations. Each integration's evaluate returns modules, the list it handed its evaluator, with ecosystemUnit { key; project; file; } where the ecosystem's module list goes: NixOS, nix-darwin, home-manager, nvf, nixidy, system-manager, terranix, flake-parts and treefmt-nix. inEcosystem makes those units for hjem, nixvim and nix-topology, whose lists name the ecosystem's modules by their files. The other integrations evaluate only caisson's modules and the configuration's.

Files. A file inside a source in the Nix store is written relative to that source, such as modules/nixos/core. A module registered through projects has no file yet, because registration doesn't record one. caisson-core's own registry events have no file for modules either.

Tests.

  • The pinned-world test aMachineRecordsWhatItsEvaluatorReceived checks the sequence above, its origins and indices, and that a home-manager configuration inside the machine has the machine's childless history as its prefix and adds events after it.
  • Two unit tests that read lib.caisson.modules directly now look inside the keying module.

nix flake check passes locally, including the VM tests and the evaluation-cost gate.

The docs are in nix-caisson/nix-caisson.github.io#81.

🤖 Generated with Claude Code

… events

Every configuration manifest now has a `history` (caisson-core), and
caisson fills it with a `declaration` event for each module the
evaluator of the configuration received, in that order:

- the module list of the ecosystem, as a single event, such as `nixos`
  from `nixpkgs: nixos/modules/module-list.nix`;
- caisson's framework module, `caisson.<class>`, and the other modules
  caisson adds, such as `caisson.nixos.pkgSet`;
- each module selected from the registry, by its registry key, such as
  `modules.nixos.default`, with the project that registered it;
- a module given as a path, by its path, and any other module as
  `inline/<index>`, with the file it names.

To know which registry entry a selected module is, `lib.caisson.modules`
now hands out each registered module inside a module keyed
`modules.<class>.<name>@<project>`. The module system imports the
modules that share a key once, so a registry entry an evaluation
selects twice is imported once. The project is part of the key so that
entries of the same name in different registries stay apart, such as
a local `default` of the tree and caisson's own, which the
integrations read from caisson's closure.

Each integration's `evaluate` returns `modules`, the list it handed
its evaluator, with an `ecosystemUnit` where the ecosystem's module
list goes. `inEcosystem` makes those units for the integrations that
name the ecosystem's modules by their files (hjem, nixvim, topology).
caisson is pinned to the caisson-core branch that adds `history`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clhodapp
clhodapp merged commit c9d69d5 into main Oct 20, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant