# Agent Guidelines for NixOS Configuration ## Project Overview This repository contains a NixOS configuration managed with Nix Flakes. It defines system configurations for one or more hosts (currently `cryodev-main` and `cryodev-pi`), custom packages, modules, overlays, and templates. ## Environment & Build Commands ### Prerequisites - **Nix** with Flakes enabled. - **Git** ### Core Commands - **Build Host Configuration**: ```bash nix build .#nixosConfigurations..config.system.build.toplevel # Examples: nix build .#nixosConfigurations.cryodev-main.config.system.build.toplevel nix build .#nixosConfigurations.cryodev-pi.config.system.build.toplevel ``` - **Format Code**: ```bash nix fmt ``` This uses the formatter defined in `flake.nix` (typically `nixfmt` via `pre-commit-hooks`). - **Run Checks (Lint/Test)**: ```bash nix flake check ``` This validates the flake outputs and runs configured checks (including formatting checks and deploy-rs checks). - **Update Flake Inputs**: ```bash nix flake update ``` ### Development Shell You can enter a development shell with necessary tools (if configured in `devShells`): ```bash nix develop ``` ## Code Style & Conventions ### General Nix Style - **Formatting**: Strictly adhere to `nixfmt` style. Run `nix fmt` before committing. - **Indentation**: Use 2 spaces for indentation. - **Lines**: Limit lines to 80-100 characters where possible, but follow the formatter's lead. - **Comments**: Use `#` for single-line comments. Avoid block comments `/* ... */` unless necessary for large blocks of text. ### Module Structure - **Function Header**: Always use the standard module arguments pattern: ```nix { config, lib, pkgs, inputs, outputs, constants, ... }: ``` - Include `inputs`, `outputs`, and `constants` if you need access to flake inputs, the flake's own outputs, or the central constants. - **Option Definitions**: - Define options in `options = { ... };`. - Implement configuration in `config = { ... };`. - Use `mkEnableOption` for boolean flags. - Use `mkOption` with types (e.g., `types.str`, `types.bool`) and descriptions. - **Imports**: - Use relative paths for local modules: `imports = [ ./module.nix ];`. - Use `inputs` or `outputs` for external/shared modules: `imports = [ outputs.nixosModules.common ];`. ### Naming Conventions - **Files**: `kebab-case.nix` (e.g., `hardware-configuration.nix`). - **Options**: `camelCase` (e.g., `services.myService.enable`). - **Variables**: `camelCase` in `let ... in` blocks. ### Flake Specifics - **Inputs**: Defined in `flake.nix`. - `nixpkgs`: Main package set (typically following a stable release). - `nixpkgs-unstable`: Unstable channel for latest packages. - **Outputs**: - `nixosConfigurations`: Host definitions. - `nixosModules`: Reusable modules exported by this flake. - `packages`: Custom packages exported by this flake. - `overlays`: Overlays to modify `nixpkgs`. - `templates`: Project templates for creating new hosts. ### Error Handling - Use `assert` for critical configuration invariants. - Use `warnings` or `trace` for deprecation or non-critical issues during evaluation. - Example: ```nix config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.port > 1024; message = "Port must be non-privileged"; } ]; }; ``` ## Directory Structure - `flake.nix`: Entry point, defines inputs and outputs. - `hosts/`: Specific host configurations. - `/default.nix`: Host entry point. - `modules/`: Reusable NixOS modules. - `nixos/`: Modules specific to NixOS (e.g. `nixvim`, `comin`, `forgejo`). - `pkgs/`: Custom package definitions. - `overlays/`: Nixpkgs overlays. - `templates/`: Templates for bootstrapping new hosts (`raspberry-pi`, `generic-server`). - `scripts/`: Helper scripts (e.g., `install.sh` for bootstrapping). - `constants.nix`: Central configuration for domains, IPs, and ports. - `INSTRUCTIONS.md`: Setup and deployment instructions (DNS, SOPS, bootstrap). - `README.md`: General project documentation and architecture overview. ## Deployment Workflows - **cryodev-main**: Push-based deployment via Forgejo Actions using `deploy-rs`. - **cryodev-pi**: Pull-based deployment using `comin` (polling the repository). ## Working with Agents - **Context**: When asking for changes, specify if it's for a specific host (`hosts/cryodev-main`) or a shared module (`modules/`). - **Verification**: Always run `nix flake check` after changes to ensure validity. - **Refactoring**: When moving code, update `imports` carefully. - **Constants**: Use `constants.nix` for values like domains, IPs, and ports instead of hardcoding them in modules.