# Den Configuration Framework: Core Concepts & Guidelines ## Overview This NixOS configuration uses `den`, a declarative pipeline framework that shifts away from static module wiring to a system of **Context Transformation** and **Context-Aware Aspects**. **Important Resource:** The `den` repository is vendored at `_ref/den/` and its official documentation can be found at `_ref/den/docs`. Use these resources (via `read_file`, `grep_search`, or `list_directory`) anytime you need to gain a deeper understanding of den's internal behavior or available features. ## 1. Core Principles * **Aspects (`__functor` pattern):** Configurations are functions of context, not static sets. An aspect (e.g., `{ host, user, ... }: { ... }`) inspects the context it receives and produces configs across domains (`nixos`, `homeManager`, `darwin`) simultaneously. * **Context (`den.ctx`):** Attribute sets containing data (like `host` or `user`). Contexts are *named* (e.g., `ctx.hm-host` vs `ctx.host`) to provide guarantees (e.g., `hm-host` proves Home Manager detection passed). * **The Pipeline (`into`):** Data flows through a defined pipeline. One context transforms `into` others (e.g., a single `ctx.host` fans out into multiple `ctx.user` contexts). * **Providers (`provides`):** Aspects use `provides` to declare sub-aspects or inject configurations across contexts. ## 2. Idiomatic Structure * **Declaration vs. Configuration:** `den.hosts` and `den.homes` declare *what* exists (hosts, architectures, users). `den.aspects` define *how* they are configured. * **Domain Spanning:** A single aspect file handles all relevant domains (e.g., a `git` aspect defines both `nixos.environment.systemPackages` and `homeManager.programs.git`). * **Composition:** High-level aspects `include` lower-level aspect functions. ## 3. The Context Pipeline 1. **`ctx.host` `{ host }`:** Resolves the host's primary aspect (`den.aspects.`). 2. **`ctx.default` `{ host }`:** Activates global defaults for the host. 3. **`ctx.user` `{ host, user }`:** Fans out to create a context for each user on the host. Resolves user aspects (`den.aspects.`). *Crucially, host aspects can configure users here, and user aspects can configure the host.* 4. **`ctx.default` `{ host, user }`:** Activates global defaults for the user. 5. **`ctx.hm-host` `{ host }`:** If the host supports Home Manager and has HM users, this safely imports the HM module. 6. **`ctx.hm-user` `{ host, user }`:** For HM users, their config is forwarded into the host's `home-manager.users.`. ## 4. Configuration Placement * **Host Aspect (`den.aspects.`):** Hardware, networking, system services. Can define default `homeManager` settings for all its users. * **User Aspect (`den.aspects.`):** Dotfiles, user packages, shell preferences. Can define required `nixos` settings for every host the user is on. * **Global Defaults (`den.ctx.default`):** Universal settings (e.g., `stateVersion`, `den._.define-user`). **Note:** Prefer using more specific contexts (like `den.ctx.host` or `den.ctx.user`) over `den.ctx.default` whenever possible. Always write it as `den.ctx.default` rather than `den.default` to make it clear it is a context. * **Feature Aspects:** Granular aspects included conditionally via ` take.exactly` (or `den.lib.take.exactly`). ## 5. Common Pitfalls * **The "Lax Context" Duplicate Config Bug:** A function like `({ host, ... }: { ... })` in `den.default.includes` runs at both the `ctx.host` and `ctx.user` stages, causing duplicate config errors. * **Fix:** Use ` take.exactly ({ host }: ...)` to run only at the host stage. * **Missing `parametric` Wrapper:** Custom aspect trees (not auto-created by Den) that fail to forward context to their includes will throw `error: function 'anonymous lambda' called without required argument`. * **Fix:** Wrap the custom aspect in ` parametric`. * **Home Manager Silent Failures:** If the detection gate fails (wrong OS, missing `"homeManager"` class on user, or missing `inputs.home-manager`), HM configs won't generate. ## 6. Essential Library Functions (`den.lib.*` & Batteries) * `take.exactly`: Executes only if context matches arguments exactly. * `take.atLeast`: Executes if context has at least the requested arguments. * `parametric`: Wrapper to make an aspect forward context to its `includes`. * `_.forward`: Translates config from one domain (e.g., custom class) to another. * **Batteries (`den._.*`):** Built-in parametric aspects (e.g., `define-user`, `user-shell`, `tty-autologin`, `unfree`). ## 7. Useful Commands * **`nix-search-tv`:** Use this command to look up docs for relevant options. * Examples: `nix-search-tv preview "home-manager/ home.packages"`, `nix-search-tv preview "nixos/ environment.systemPackages"`. * Prefix with `nixpkgs/` for nixpkgs docs. * Use `nix-search-tv print` to print all available options and packages (filter output to avoid bloating context).