Commit
This commit is contained in:
70
GEMINI.md
70
GEMINI.md
@@ -1,27 +1,51 @@
|
||||
# Gemini Context & Project Guidelines
|
||||
# Den Configuration Framework: Core Concepts & Guidelines
|
||||
|
||||
This file serves as persistent contextual memory for the Gemini CLI when working on this NixOS configuration project.
|
||||
## 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**.
|
||||
|
||||
## Architecture: The `den` Framework
|
||||
This repository manages NixOS and Home Manager configurations using the `den` framework. The approach here drastically differs from standard NixOS setups.
|
||||
**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.
|
||||
|
||||
### Core Concepts & Rules
|
||||
1. **Freeform Schemas over Custom Options:** Do not use legacy Nix module options (`lib.mkOption`, `lib.mkIf`) to define simple user/host properties (like email addresses, domains, or names). Instead, attach properties directly to the host or user definition objects in `hosts/<name>/default.nix` or `users/<name>.nix`. Den's freeform entity schemas will pass these through the context pipeline automatically.
|
||||
2. **Parametric Aspects:** When a module requires access to host or user variables (like `user.email` or `host.domain`), the aspect MUST be wrapped in `den.lib.parametric`.
|
||||
* *Example:* `lux.myapp = den.lib.parametric { includes = [ ({ user, ... }: { ... }) ]; };`
|
||||
3. **Decentralized Host & User Definitions:** Do not centralize host definitions in a single file. Follow the `quasigod` reference structure:
|
||||
* **Hosts** declare themselves in `modules/hosts/<hostname>/default.nix` (e.g., `den.hosts.x86_64-linux.orion = { ... }`).
|
||||
* **Users** bind themselves to hosts in their own user files in `modules/users/<username>.nix` (e.g., `den.hosts.x86_64-linux.orion.users.kiri = userAccount // { ... }`).
|
||||
4. **App Categories & Naming:**
|
||||
* `/modules/desktop/`: GUI, Wayland, display managers, WMs.
|
||||
* `/modules/dev/`: Developer tools, terminal, neovim.
|
||||
* `/modules/apps/`: User-level software (PIM, Bitwarden, MPV, Email). Note: `pim.nix` stands for Personal Information Management and is an app, not a user definition.
|
||||
* `/modules/services/`: System-level daemons (Caddy, Gitea, Vaultwarden).
|
||||
* `/modules/profiles/`: Aggregations (like workstation/server).
|
||||
## 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.
|
||||
|
||||
### Common Pitfalls & Lessons Learned
|
||||
* **`home-manager` vs `homeManager`:** When defining class configurations inside a parametric function, the key for Home Manager is strictly `homeManager` (camelCase). Writing `home-manager.programs...` will cause evaluation errors because `home-manager` is not the class name used by the schema.
|
||||
* **`user` is an Object:** In context parameters (`{ user, ... }:`), `user` is an attribute set, not a string. Do not interpolate it directly as a string (`"${user}"`); use `${user.name}`.
|
||||
* **Namespace Inclusion:** The project uses the `lux` namespace. When an aspect needs to pull in other aspects, use `with lux; [ ... ]` rather than writing out `den.ful.lux...` repeatedly.
|
||||
* **Abstracting Paths:** Never hardcode `/home/<username>`. Inside `homeManager` modules, use `config.home.homeDirectory`. Inside `nixos` modules (like SOPS), use `/home/${user.name}` where `user` is provided by the parametric context.
|
||||
* **Git Status dependency:** When moving, creating, or renaming files (`mv`, `mkdir`), they must be staged in Git (`git add <file>`) before running `nix flake check`, otherwise the flake evaluator will not see the changes and will throw "undefined variable" or "path does not exist" errors.
|
||||
## 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.<hostname>`).
|
||||
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.<username>`). *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.<name>`.
|
||||
|
||||
## 4. Configuration Placement
|
||||
* **Host Aspect (`den.aspects.<hostname>`):** Hardware, networking, system services. Can define default `homeManager` settings for all its users.
|
||||
* **User Aspect (`den.aspects.<username>`):** 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 `<den/lib> 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 `<den/lib> 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 `<den/lib> 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).
|
||||
|
||||
Reference in New Issue
Block a user