Repository navigation
feat(integrations): check drift between every activated configuration and the one above it - #103
Merged
Merged
Conversation
clhodapp
force-pushed
the
feat/drift-everywhere
branch
2 times, most recently
from
October 18, 2026 06:38
f6b0616 to
8a36e43
Compare
clhodapp
force-pushed
the
feat/drift-everywhere
branch
from
October 18, 2026 07:54
8a36e43 to
2fb0115
Compare
clhodapp
force-pushed
the
feat/drift-everywhere
branch
from
October 18, 2026 08:25
2fb0115 to
29ab675
Compare
clhodapp
force-pushed
the
feat/drift-everywhere
branch
from
October 18, 2026 08:27
29ab675 to
10c90b2
Compare
clhodapp
force-pushed
the
feat/drift-everywhere
branch
from
October 18, 2026 17:35
10c90b2 to
5d5fbf3
Compare
… and the one above it Drift detection was written for one pair: a home inside a NixOS machine compared `/etc/caisson-home-manager/source.json` with the machine it was built for. It is now a property of the framework. An integration whose configurations are activated passes `activation` to `mkModuleConfiguration`: `identity`, the store path of the childless evaluation, and `marker`, the file its activation writes that identity into. NixOS, darwin and system-manager record the system and `/etc/caisson/marker.json`; a home records its activation package and a file in the state directory of its user; a hjem configuration records its manifest file and a file in its directory. A machine `standsAlone`: it is applied on its own host, so it checks nothing above it. `lib.caisson.integrations` gains `activatingAncestorOf`, `markerOf`, `checksMarkerOf` and `driftCheckOf`. Each activating class writes its marker from its `default` module (`activation-marker` for nixos, darwin, systemManager, homeManager and hjem) when a configuration declared inside it checks it. A home runs `driftCheckOf` against the nearest activating configuration above it from the home-manager module `activation-drift`, so a home inside a darwin or system-manager machine is checked as one inside NixOS is. caisson now registers a `default` home-manager module, which imports `activation-drift` and `activation-marker`, and a `default` hjem module, which imports `activation-marker`. The NixOS module `home-manager-source-marker` and the home-manager module `nixos-source-marker` are removed. The option `caisson.home-manager.machineDrift.warn` becomes `caisson.drift.warn`, and the marker field `baseSystemOutPath` becomes `identity`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rker A drift marker held the store path of the childless evaluation with its string context dropped, which made it a string that looks like a store path but is not tracked as one. The marker and the check now hold the SHA-256 digest of that store path. Computing it evaluates the childless evaluation and builds nothing, and the digest names no store path, so nothing depends on it and nothing can read it as a path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test of the units that activate the homes dropped the string context of the activation package and of the unit script to search one in the other. It now reads the context of the script, which records the store paths the script refers to, and checks that it holds the activation package of the home and not that of the other home. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit b6f1ff3)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
clhodapp
force-pushed
the
feat/drift-everywhere
branch
from
October 18, 2026 18:04
5d5fbf3 to
5c79217
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Drift detection used to cover one pair: a home inside a NixOS machine compared
/etc/caisson-home-manager/source.jsonwith the machine it was built for. This PR moves it into the framework. Every configuration with an activation now checks the nearest configuration above it that also has an activation, whatever the two types are.Stacked on #102.
How it works
The integrations record it. An integration whose configurations are activated passes
activationtomkModuleConfiguration, and the manifest records it.identityis the store path of the childless evaluation, meaning the configuration evaluated without the configurations declared inside it.markeris the file the activation writes into. The marker holds the SHA-256 digest of that store path, not the path itself. Computing the path evaluates the childless evaluation and builds nothing. The digest names no store path, so no string context is dropped, and nothing can read the marker as a path.toplevel/etc/caisson/marker.json$XDG_STATE_HOME/caisson/markers/home-manager-<name>.json.local/state/caisson/markers/hjem-<name>.jsonin the user's directoryA machine's record also sets
standsAlone. A machine is applied on its own host, so a machine declared inside another, such as an image, checks nothing above it.The library computes it.
lib.caisson.integrationsgainsactivatingAncestorOf,markerOf,checksMarkerOfanddriftCheckOf. A child finds the nearest activating configuration among its manifest'sancestors, so it never names that configuration's type.Each class writes its marker. The
defaultmodule of nixos, darwin, systemManager, homeManager and hjem importsactivation-marker. It writes the marker only when a configuration declared inside checks it, because computing the identity costs a second evaluation.A home checks it. The home-manager
defaultmodule importsactivation-drift, which runsdriftCheckOfas an activation step. A home inside a darwin or system-manager machine is checked the same way as one inside NixOS.Breaking changes (pre-1.0)
home-manager-source-markerand the home-manager modulenixos-source-markerare removed. A home that selects its modules itself namescaisson/activation-driftinstead.caisson.home-manager.machineDrift.warnbecomescaisson.drift.warn./etc/caisson/marker.json, and its fieldbaseSystemOutPath, a store path, becomesidentity, a digest.Paired consumer fixes: clhodapp/ch-personal-machines and clhodapp/ch-home-manager, branch
fix/activation-driftin each.Testing
nix flake checkpasses, including the unit tests, the pinned-world suite and the eval-weight gate. The system-manager pinned-world test now checks that the machine writes the marker and that the home's check reads it.drift-warning-vmpasses against this branch onfix/activation-drift. In a NixOS VM it shows five things:/etc/caisson/marker.json;nix flake check --no-buildpasses in all 18 consumers, with both caisson pins pointed at this branch and ch-home-manager and ch-personal-machines on their fix branches.Not covered
A hjem configuration declared inside a machine records a marker for the configurations inside it, but it doesn't check the machine itself. hjem's activation runs no step that a configuration can add. Its one hook is the systemd unit actions it reports after a switch, which would put the warning in the journal rather than on the terminal.
Docs: nix-caisson/nix-caisson.github.io, branch
docs/drift-everywhere.🤖 Generated with Claude Code