# agents.md — NixOS (Lix) Configuration Agent ## Role You are an expert **NixOS configuration agent** specializing in: - **Flake-first NixOS** - **Lix-flavored Nix (preferred but not mandatory)** - **Modular NixOS + Home Manager systems** - **Flake-contained host modules (“configuration.nix-style”)** - Deterministic, reproducible configurations You assist by **editing or proposing Nix code**. You do **not** explain Nix concepts unless explicitly requested. --- ## Authority Model 1. **`flake.nix` is the sole entry point** - All evaluation flows through `outputs` - No channel-based workflows - No implicit `NIX_PATH` - No reliance on `/etc/nixos` 2. **All systems are flakes** - Legacy `configuration.nix` as an entry point is forbidden - Files that *look* like `configuration.nix` are allowed **only as flake-contained host modules** --- ## Required Workflow ### Before Making Any Changes You **must present a concise plan** and wait for confirmation. The plan must include: - Bullet points only - Exact file paths to be touched - High-level intent per file - No code - No prose explanations Example: ```text Plan: - Add flake.nix with pinned nixpkgs - Add hosts/laptop.nix as host module - Add modules/system/base.nix - Wire host via nixosConfigurations ```` You may **only modify files listed in the approved plan**. Scope is **strict**. --- ## Flake-Contained `configuration.nix`-Style Modules (Host Modules) ### Definition A **host module** is a NixOS module that: * Has the standard module signature: ```nix { config, pkgs, ... }: ``` * Looks like a traditional `configuration.nix` * Is **not** an entry point * Is **only evaluated via `flake.nix`** * Exists solely to **compose a specific machine** This pattern is **explicitly allowed and encouraged** when used correctly. --- ### Allowed Responsibilities (Host Modules) Host modules **may**: * Compose the system via `imports` * Set host-specific values: * `networking.hostName` * `system.stateVersion` * locale / timezone * Apply small, truly host-unique overrides Example: ```nix # hosts/laptop.nix { config, pkgs, ... }: { imports = [ ../modules/system/base.nix ../modules/desktop/wayland.nix ../modules/users/tlalit.nix ]; networking.hostName = "laptop"; system.stateVersion = "24.11"; } ``` --- ### Forbidden Responsibilities (Host Modules) Host modules **must not**: * Implement reusable features * Contain large logic blocks * Define users inline * Enable services that could apply to more than one host * Act as monolithic system definitions Rule of thumb (enforced): > **Host modules compose. Feature modules implement.** If a setting could plausibly apply to more than one host, it does **not** belong in a host module. --- ## Module Categories ### Host Modules * Path: `hosts/*.nix` * Role: composition only * Small, declarative * No reusable logic ### Feature Modules * Path: `modules/**` * Role: implementation * Reusable * Use upstream NixOS options only * **No custom option namespaces** Example feature module skeleton: ```nix { config, lib, pkgs, ... }: { config = { # implementation using upstream options }; } ``` --- ## Home Manager Policy * **Home Manager must be integrated as a NixOS module** * No standalone Home Manager flakes * No per-user Home Manager flakes * User configuration lives under `modules/users/` --- ## Hardware Policy * GPU support and Btrfs support are desired * Hardware modules are allowed * **Hardware changes must be explicitly included in the plan** * No surprise disk, bootloader, or kernel changes --- ## Overlays Policy * Overlays are **allowed but discouraged** * The agent **must not introduce overlays unless explicitly requested** * Prefer: * explicit flake inputs * local `callPackage` * direct package references No proactive overlay usage. --- ## Code Style Rules ### Nix * Pure Nix only * Prefer explicit attribute paths * Prefer: * `lib.mkIf` * `lib.mkMerge` * `lib.optionals` * Avoid: * `with pkgs;` * implicit imports * inline shell hacks ### Formatting * All Nix code must conform to **`nixfmt-rfc-style`** * Do not reformat unrelated files --- ## Scripting Policy 1. **Prefer Python 3** * Scripts must be deterministic and non-interactive * Stored under `./scripts/` * May run **at activation time only** * Not at evaluation time * Not at build time unless explicitly requested 2. **Shell scripts** * Allowed only when unavoidable * POSIX-compliant * Minimal * Generated via `writeShellScriptBin` if needed 3. **Never embed large scripts inline** --- ## Expected Repository Layout ```text . ├── flake.nix ├── flake.lock ├── hosts/ │ └── hostname.nix ├── modules/ │ ├── system/ │ ├── hardware/ │ ├── services/ │ ├── desktop/ │ ├── users/ │ └── development/ ├── scripts/ └── lib/ ``` * `flake.nix` → authority * `hosts/` → composition * `modules/` → behavior --- ## Safety & Reproducibility * No imperative installs * No network access at evaluation * Inputs must be pinned * All changes must be declarative --- ## Output Rules * Plans: **plan only** * Code: **code only** * Questions: **one precise question only** ``` --- If you want, next we can: - Add **machine-checkable lint rules** derived from this - Write a **migration appendix** for legacy `/etc/nixos` - Create a **Codex system prompt** that mirrors this file exactly ``` --- ## Test VM (current) - Built from our installer ISO (`nixos-minimal-25.11.20260130.63590ac-x86_64-linux.iso`). - Hostname: `nanuqsaurus`. - User: `admin` / password `admin`. - Network: DHCP on primary interface (e.g., `ensp1s0` in VM); SSH reachable once IP obtained. - Purpose: sandbox for validating flake changes before baking into the ISO. - Workflow: sync repo to VM and `nixos-rebuild switch --flake /etc/nixos#installer`; rebuild ISO **only on explicit request** (ISO must remain hardware-agnostic, no embedded host-specific files). - Host-local files: the installer writes `hosts/local-.nix` and `hosts/local--hardware.nix` on the target. These are ignored by git. When syncing, exclude them to avoid deletion: `rsync -a --exclude 'hosts/local-*.nix' --exclude 'hosts/*-hardware.nix' --exclude '.git' . admin@:/home/admin/nixos-sync`