Resolution Pipeline
Pipeline overview
Section titled “Pipeline overview”When Den evaluates a host, it runs a resolution pipeline driven by policies and entities. Policies are directed edges that fan context out to downstream entity kinds; each entity kind binds behavior for its resolved context.
flowchart TD
start["den.hosts.x86_64-linux.laptop"] --> host["host {host}"]
host -->|"host-to-users"| user["user {host, user} (per user)"]
host -->|"host-to-default"| hdef["default {host}"]
user -->|"user-to-default"| udef["default {host, user}"]
host -->|"host-to-hm-host"| hmhost["hm-host {host}"]
hmhost -->|"hm-host-to-hm-user"| hmuser["hm-user {host, user}"]
hmuser --> fwd["forward into home-manager.users.alice"]
-
Host resolution
For each entry in
den.hosts.<system>.<name>, the pipeline creates ahostscope. The host’s own aspect is resolved viaden.schema.host.includes, binding owned configs for the host’s class. -
Core policies fan out
Core policies (
modules/policies/core.nix) define the fundamental traversal edges:Policy From To Resolve host-to-usershostuserOne edge per host.usersentryhost-to-defaulthostdefaultIdentity (passes context through) user-to-defaultuserdefaultIdentity Each policy’s
resolvefunction receives the current context and returns a list of downstream contexts.host-to-usersfans out: one{ host, user }pair per user declared on the host. -
Battery policies create derived entity kinds
Batteries register additional policies that create derived entity kinds when their conditions are met. Each battery uses
makeHomeEnvto produce policies for the new entity kinds:Policy Condition Target entity kind host-to-hm-hostHM enabled, host has homeManager-class usershm-hosthm-host-to-hm-userPer homeManager-class userhm-userhost-to-hjem-hosthjem enabled, host has hjem-class usershjem-hosthjem-host-to-hjem-userPer hjem-class userhjem-userhost-to-maid-hostnix-maid enabled, host has maid-class usersmaid-hostmaid-host-to-maid-userPer maid-class usermaid-userhost-to-wsl-hostNixOS host with wsl.enablewsl-hostThe
-hostentity kind imports the battery’s OS module (e.g.,home-manager.nixosModules.home-manager). The-userentity kind forwards the resolved user aspect into the appropriate namespace (e.g.,home-manager.users.<name>). -
Deduplication
The pipeline tracks a
seenset keyed by context identity. When a scope is entered for the first time with a given context, the full aspect (owned configs + statics + parametric matches) is included. Subsequent visits with the same context key skip already-applied includes, preventingden.defaultconfigs from being applied twice when the same aspect appears at multiple entity kinds.Each policy transition creates an independent scope with its own dedup state, so entity kinds reached through different policies are isolated.
-
Home configurations
Standalone
den.homesentries follow a separate path with their own core policy:flowchart TD home["den.homes.x86_64-linux.alice"] --> homestage["home {home}"] homestage -->|"home-to-default"| hdef["default {home}"] homestage --> hmc["homeConfigurations.alice"]Home scopes have no
hostin context, so policies and provides requiring{ host }are not activated. Thehome-to-defaultpolicy still applies shared defaults. -
Output
Flake-level policies (
modules/policies/flake.nix) drive the final assembly.to-os-outputsresolves all hosts for a system;to-hm-outputsresolves all homes. Each resolved entity is instantiated (lib.nixosSystem,darwinSystem, orhomeManagerConfigurationdepending on class) and placed intoflake.nixosConfigurations,flake.darwinConfigurations, orflake.homeConfigurations.
See also
Section titled “See also”- Entities and Schema — what entities are and how they feed the pipeline
- Policies — how entities relate
- Quirks & Pipes — structured data flow between aspects
- Fleets & Multi-Host — cross-host resolution and data flow
- Aspects — how entities resolve