# NixOS Configuration Repository - AI Agent Guide This guide provides everything you need to know to work efficiently with this NixOS configuration repository. Keep this file handy when making changes. ## Repository Overview This repository manages NixOS configurations for multiple systems using flakes and Home Manager. All systems are defined declaratively in Nix expressions. ### Managed Systems | Hostname | Type | Hardware | Special Notes | |----------|------|----------|---------------| | `framework` | Desktop/Laptop | Framework AMD AI 300 series | User: jsutter, Uses nixos-hardware module | | `aurora` | Desktop | Custom | Users: jsutter, isutter, aksutter | | `labrizor` | Desktop | Custom | User: jsutter | | `skip01` | Server (WIP) | Custom | Headless configuration | ### Core Technologies - **NixOS**: 25.11 (stable channel) - **Nixpkgs Unstable**: For packages requiring latest versions - **Home Manager**: Release 25.11 - **Plasma Manager**: KDE Plasma configuration management - **Flakes**: For reproducible, declarative system definitions ## Project Structure ``` nixos/ ├── appflakes/ # Local flake inputs │ └── octofriend/ # Custom application flake ├── desktop/ # Desktop environment configurations │ ├── plasma.nix # KDE Plasma + Plasma Manager │ ├── dev.nix # Development tools and languages │ ├── office.nix # Office applications │ ├── gaming.nix # Games and gaming platforms │ ├── media.nix # Audio/video software │ ├── virtualization.nix # VMs and containers │ ├── tailscale.nix # VPN configuration │ ├── 2dprinting.nix # Printer setup │ ├── 3dprinting.nix # 3D printer tools │ ├── dnm.nix # Framework-specific config │ └── stp-elc-udmshare.nix # Specific mount/share config ├── docs/ # Documentation │ └── agents.md # This file ├── servers/ # Server configurations (future use) ├── systems/ # Hardware-specific configurations │ ├── common.nix # Shared system settings (bootloader, nix config, etc.) │ ├── common-headless.nix # Common settings for headless systems │ ├── framework.nix # Framework laptop hardware config │ ├── aurora.nix # Aurora desktop hardware config │ ├── labrizor.nix # Labrizor desktop hardware config │ └── skip01.nix # Skip01 server config ├── users/ # User configurations with Home Manager │ ├── common-home.nix # Shared user packages and settings │ ├── jsutter.nix # Primary user configuration │ ├── isutter.nix # Secondary user configuration │ └── aksutter.nix # Secondary user configuration └── flake.nix # Top-level flake definition ``` ## Core Principles ### 1. Declarative Configuration - All system state must be defined in Nix expressions - Never use imperative commands for permanent changes - Every configuration change should be reproducible ### 2. Modular Architecture - Maintain separation between hardware, software, and user configurations - Use existing modules before creating new ones - Follow the established directory structure strictly ### 3. Security First - Never expose sensitive data (passwords, private keys, API tokens) - Use proper user privilege separation - Validate all external inputs and configurations ## Configuration Patterns ### Function Parameters Always include the appropriate parameters based on what the module needs: ```nix # For modules using unstable packages { config, pkgs, pkgs-unstable, lib, ... }: # For stable-only modules { config, pkgs, lib, ... }: # For modules using special args from flake { config, pkgs, pkgs-unstable, lib, octofriend, ... }: # For Home Manager modules { pkgs, ... }: ``` ### System Configuration Pattern ```nix { config, lib, pkgs, ... }: { # Always include hostname first networking.hostName = "system-name"; # Hardware configuration fileSystems."/" = { device = "/dev/disk/by-partlabel/primary"; fsType = "ext4"; }; fileSystems."/boot" = { device = "/dev/disk/by-partlabel/ESP"; fsType = "vfat"; }; # System-specific settings # Group related configurations together } ``` ### User Configuration Pattern ```nix { config, pkgs, pkgs-unstable, home-manager, ... }: { # System user definition users.users.username = { shell = pkgs.zsh; isNormalUser = true; description = "User Description"; extraGroups = [ "networkmanager" "wheel" ]; # Only essential groups }; # Home Manager configuration home-manager.users.username = { home.username = "username"; home.homeDirectory = "/home/username"; home.stateVersion = "25.05"; # User configurations }; } ``` ### Desktop Module Pattern ```nix { config, pkgs, pkgs-unstable, lib, ... }: { # System packages for this category environment.systemPackages = with pkgs; [ package1 package2 ]; # Configuration options services.service-name.enable = true; # Home Manager integrations (if applicable) } ``` ## Package Management Guidelines ### Stable vs Unstable Packages ```nix # PREFERRED: Use stable packages by default environment.systemPackages = with pkgs; [ firefox git vim ]; # ACCEPTABLE: Use unstable when necessary # Add comments explaining why unstable is needed environment.systemPackages = with pkgs; [ firefox pkgs-unstable.windsurf # Latest features not in stable ]; ``` ### Package Selection Criteria 1. **Use stable unless**: Package doesn't exist OR needs newer version 2. **Document reasons**: Always comment why unstable is used 3. **Test thoroughly**: Unstable packages may have issues 4. **Review regularly**: Check if unstable packages can move to stable ### Common Package Sets by Module - `dev.nix`: IDEs, languages, development tools - `office.nix`: LibreOffice, productivity apps - `gaming.nix`: Steam, Lutris, game launchers - `media.nix`: Audio/video players, editors - `virtualization.nix`: VirtualBox, Docker, other virt tools - `plasma.nix`: KDE Plasma applications and themes ## System-Specific Information ### Framework (`framework.nix`) - Uses `nixos-hardware` module: `framework-amd-ai-300-series` - Additional modules: `dnm.nix`, `stp-elc-udmshare.nix` - Single user: jsutter ### Aurora (`aurora.nix`) - Multi-user system: jsutter, isutter, aksutter - Additional modules: `3dprinting.nix`, `2dprinting.nix` - No specialized hardware module ### Labrizor (`labrizor.nix`) - Single user: jsutter - Additional modules: `3dprinting.nix` - No specialized hardware module ### Common Settings (`systems/common.nix`) Includes: - Hardware firmware and fwupd - NetworkManager with VPN plugins (OpenVPN, OpenConnect) - Systemd-boot EFI bootloader - Latest kernel - Nix settings with experimental features (flakes, nix-command) - Weekly garbage collection (7-day retention) - Auto-optimized Nix store - Trusted users: root, jsutter - Timezone: America/Los_Angeles - Locale: en_US.UTF-8 - PipeWire audio stack - SSH service enabled - Zsh shell enabled - Passwordless sudo for wheel group - Flatpak enabled - USB plugdev group rules ## File Naming Conventions - Use lowercase with hyphens: `vpn-config.nix`, `development-tools.nix` - System configurations must match hostname: `framework.nix`, `aurora.nix` - User configurations must match username: `jsutter.nix`, `isutter.nix` - Common configurations: `common.nix`, `common-home.nix` ## Code Style - Use 2-space indentation - Align attribute lists consistently - Add comments for non-obvious configurations - Group related configurations together Example: ```nix { # Audio configuration sound.enable = true; hardware.pulseaudio.enable = false; security.rtkit.enable = true; services.pipewire = { enable = true; alsa.enable = true; alsa.support32Bit = true; pulse.enable = true; }; } ``` ## Common Workflows ### Adding a New Package 1. Determine appropriate module (desktop/, systems/, users/) 2. Check if package exists in stable channel: `nix search nixpkgs package-name` 3. Use unstable only if necessary with documentation 4. Add to appropriate environment.systemPackages or home.packages 5. Run dry-run before applying 6. Update relevant documentation if it affects multiple systems Example: ```nix # In desktop/dev.nix environment.systemPackages = with pkgs; [ # Added for Python development python312 python312Packages.pip pkgs-unstable.windsurf # Latest AI features not in stable ]; ``` ### Creating a New Desktop Module 1. Create file in `desktop/` with descriptive name 2. Include proper function parameters 3. Add packages, services, and configurations 4. Test module independently 5. Add to `commonDesktopModules` in flake.nix if for all desktops 6. Add to specific system in flake.nix if selective ### Adding a New System 1. Create `systems/.nix` following existing patterns 2. Set `networking.hostName = ""` 3. Configure hardware (fileSystems, hardware-specific settings) 4. Add system entry to `flake.nix`: ```nix new-system = mkSystem { modules = commonDesktopModules ++ [ ./systems/new-system.nix ./users/username.nix ]; }; ``` 5. Test with dry-run and build ### Modifying User Configuration 1. Edit appropriate file in `users/` 2. For shared changes: modify `common-home.nix` 3. For user-specific changes: modify `.nix` 4. Home Manager configuration goes in `home-manager.users.` ## Testing and Validation ### Pre-commit Testing ALWAYS run these commands before submitting changes: ```bash # 1. Syntax check nix flake check # 2. Dry run for affected systems (run for ALL affected) sudo nixos-rebuild dry-run --flake .#framework sudo nixos-rebuild dry-run --flake .#aurora sudo nixos-rebuild dry-run --flake .#labrizor # 3. Check flake outputs nix flake show ``` ### Applying Changes ```bash # Build and switch (active system only) sudo nixos-rebuild switch --flake .#hostname # Build only (test without switching) sudo nixos-rebuild build --flake .#hostname # Build and boot (adds to GRUB menu) sudo nixos-rebuild boot --flake .#hostname ``` ### Build Verification - Test on at least one system before merging - Verify all services start correctly: `systemctl status` - Check for package conflicts - Validate hardware-specific configurations ### Updating Packages ```bash # Update flake inputs nix flake update # Check what changed nix flake diff # Rebuild after update sudo nixos-rebuild switch --flake .#hostname ``` ## Security Rules ### Sensitive Data Handling - **NEVER** commit plaintext passwords - **NEVER** commit private SSH keys - **NEVER** commit API tokens or secrets - **ALWAYS** use hashed passwords: `hashedPassword = "$6$..."` - **CONSIDER** using sops-nix for advanced secret management ### User Privilege Management ```nix # GOOD: Minimal necessary groups extraGroups = [ "networkmanager" "wheel" "audio" ]; # BAD: Over-privileged users extraGroups = [ "networkmanager" "wheel" "audio" "video" "input" "disk" "lp" "scanner" ]; ``` ### SSH Key Management ```nix # GOOD: Use authorizedKeys for SSH access openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBNVUh+RrcOSMRV6qysnsdPs5AyK8dSm4QhhnwgpikyI user@domain" ]; # FORBIDDEN: Never include private keys ``` ## Rollback Procedures ### Configuration Rollback ```bash # List available generations sudo nix-env --list-generations --profile /nix/var/nix/profiles/system # Rollback to previous working generation sudo nixos-rebuild switch --profile-name generation-123 # Or use rollback shortcut sudo nixos-rebuild switch --rollback # Rollback specific system sudo nixos-rebuild switch --rollback --flake .#hostname ``` ### Emergency System Recovery If a system fails to boot after changes: 1. Boot from installation media 2. Mount root filesystem: `mount /dev/disk/by-partlabel/primary /mnt` 3. Roll back: `sudo nixos-rebuild switch --rollback --install-bootloader /mnt` 4. Identify and fix configuration issues 5. Test before rebooting ### Booting into Previous Generations At boot time (GRUB menu): 1. Hold Shift during boot to see GRUB menu 2. Select "Advanced options for NixOS" 3. Choose previous generation ## NixOS Installation (New System) ```bash # Partition disk (example for NVMe) sudo parted /dev/nvme0n1 -- mklabel gpt sudo parted /dev/nvme0n1 -- mkpart primary ext4 512MB 100% sudo parted /dev/nvme0n1 -- mkpart ESP fat32 1MB 512MB sudo parted /dev/nvme0n1 -- set 2 esp on sudo mkfs.ext4 /dev/disk/by-partlabel/primary sudo mkfs.vfat /dev/disk/by-partlabel/ESP # Mount filesystems sudo mount -o rw /dev/disk/by-partlabel/primary /mnt/ sudo mkdir /mnt/boot sudo mount -o rw /dev/disk/by-partlabel/ESP /mnt/boot/ sudo mkdir /mnt/root sudo git clone https://git.symbiotrip.com/jsutter/nixos /mnt/root/nixos # Install (no root password, impure for git access) sudo -i cd /mnt/root/nixos nixos-install --flake .# --no-root-password --impure # Set password after install nixos-enter --root '/mnt' passwd jsutter ``` ## Module Dependencies ### Known Dependencies - `plasma.nix` depends on: `common.nix`, `home-manager` - `dev.nix` is included in all desktop systems - All desktop systems include: `common.nix`, `plasma.nix`, `dev.nix`, `office.nix`, `gaming.nix`, `media.nix`, `virtualization.nix`, `tailscale.nix` - User files include Home Manager configuration ### Avoiding Circular Dependencies - Don't import system modules into user modules - Use `common.nix` for shared system settings only - Use `common-home.nix` for shared user settings only - Hardware-specific modules should not depend on desktop modules ## Emergency Tools ### Useful Commands ```bash # Check what packages provide a command nix-locate bin/commandname # Search for packages nix search nixpkgs package-name nix search nixpkgs-unstable package-name # Check Nix store size du -sh /nix/store # Garbage collect manually sudo nix-collect-garbage -d # Profile Nix operations sudo nix-env --profile /nix/var/nix/profiles/system --list-generations # Check hardware info lshw lspci lsusb lsblk hwinfo ``` ## Troubleshooting Common Issues ### Build Errors 1. Read the error message carefully 2. Check for syntax errors in the modified file 3. Verify all attributes are closed properly 4. Run `nix flake check` to validate syntax ### Service Failures ```bash # Check service status systemctl status service-name # View service logs journalctl -u service-name -e # Restart service systemctl restart service-name ``` ### Package Conflicts - If two modules try to enable the same service with different settings - Use `lib.mkForce` to override settings if necessary - Or consolidate the configuration in one place ## Flakes Reference ### Input Structure ```nix inputs = { nixpkgs.url = "nixpkgs/nixos-25.11"; # Stable nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; # Unstable nixos-hardware.url = "github:NixOS/nixos-hardware/master"; home-manager.url = "github:nix-community/home-manager/release-25.11"; plasma-manager.url = "github:nix-community/plasma-manager"; octofriend.url = "path:./appflakes/octofriend"; # Local flake }; ``` ### Special Args Available in all modules: - `pkgs`: Stable Nix packages - `pkgs-unstable`: Unstable Nix packages - `octofriend`: Local octofriend flake ### Output Structure ```nix outputs = { self, # Self reference nixpkgs, # Stable packages nixpkgs-unstable, # Unstable packages nixos-hardware, # Hardware modules home-manager, # Home Manager plasma-manager, # Plasma Manager octofriend # Custom app flake }: { nixosConfigurations = { framework = { ... }; # Define each system aurora = { ... }; labrizor = { ... }; }; }; ``` ## Documentation Requirements ### Code Comments - Explain non-obvious configurations - Document reasons for unstable package usage - Note hardware-specific requirements - Reference external dependencies Example: ```nix # Use unstable neovim for LuaLS integration not in stable pkgs-unstable.neovim # Latest features needed for Lua development ``` ### Commit Messages Use clear, descriptive commit messages: - Reference affected systems/modules - Explain reasoning for significant changes - Include testing steps when applicable Example: ``` feat(framework): Add 3D printing support for Prusa printers - Added 3dprinting.nix module with PrusaSlicer and Cura - Installed USB rules for Prusa devices - Added to framework system configuration Tested: Prusa MK4 recognized and can start print via USB ``` ## Performance Considerations ### Nix Settings The repository uses optimized Nix settings: - `auto-optimise-store`: Auto-optimizes the Nix store - `keep-outputs = true`: Keeps build outputs - `keep-derivations = true`: Keeps derivations for evaluation - `download-buffer-size`: 512MB for faster downloads ### Garbage Collection Automatically runs weekly: - Deletes builds older than 7 days - Run manually: `sudo nix-collect-garbage -d` ### Build Caching Consider using `nix-serve` or Cachix for: - Faster rebuilds - Shared cache across systems - CI/CD integration ## Resources ### Official Documentation - [NixOS Manual](https://nixos.org/manual/nixos/stable/) - [Home Manager Manual](https://nix-community.github.io/home-manager/) - [Nix Pills](https://nixos.org/guides/nix-pills/) - [NixOS Wiki](https://nixos.wiki/) ### Community Resources - [NixOS Discourse](https://discourse.nixos.org/) - [NixOS subreddit](https://reddit.com/r/NixOS/) - [NixOS Matrix](https://matrix.to/#/#nixos:nixos.org) ### Package Search - [search.nixos.org](https://search.nixos.org/packages) - Command line: `nix search nixpkgs package-name` ## Quick Reference ### Essential Commands | Action | Command | |--------|---------| | Update system | `sudo nixos-rebuild switch --flake .#hostname` | | Dry run | `sudo nixos-rebuild dry-run --flake .#hostname` | | Rollback | `sudo nixos-rebuild switch --rollback` | | Update flakes | `nix flake update` | | Check flakes | `nix flake check` | | Search packages | `nix search nixpkgs name` | | Garbage collect | `sudo nix-collect-garbage -d` | ### File Paths Reference | Type | Location | |------|----------| | Common system settings | `systems/common.nix` | | System hardware config | `systems/.nix` | | Common user settings | `users/common-home.nix` | | User config | `users/.nix` | | Desktop apps | `desktop/.nix` | | Flake definition | `flake.nix` | ## Maintenance & Changelog This section tracks changes to the repository structure and when this document was updated. Keep this in sync! ### Current Repository State - **Last Updated**: February 2026 - **NixOS Version**: 25.11 - **Managed Systems**: 3 (framework, aurora, labrizor) - **Users**: jsutter (primary), isutter, aksutter ### Repository Change Log | Date | Change | Updated Sections | |------|--------|------------------| | 2026-02 - Created | Created `agents.md` with comprehensive guide | All sections | | 2026-02 - Removed | Removed .clinerules file, consolidated into agents.md | Maintenance section | | 2026-02 - Cleanup | Removed unused gnome.nix module, common-headless.nix; removed allowBroken setting | System structure | | 2026-02 - Cleanup | Removed commented packages across multiple files; fixed trailing whitespace | Code quality | | 2026-02 - Cleanup | Removed .clinerules file; deleted gnome.nix (unused); common-headless.nix (duplicated) | File structure | | 2026-02 - Improvement | Added result, *.swp, *~ to .gitignore | Maintenance | ### When to Update This Document Update `agents.md` when any of the following occur: - **Structural Changes**: - New system added to `flake.nix` - New user configuration added - New or renamed desktop module - Directory restructuring - **Configuration Changes**: - New shared settings in `systems/common.nix` - New shared user settings in `users/common-home.nix` - Changes to module pattern or function parameters - New package categories or organizational changes - **Technology Updates**: - NixOS version changes - Channel updates (stable/unstable) - New major inputs added to flake - Significant Nix configuration changes - **Procedure Changes**: - New testing workflow - Changed emergency procedures - Updated installation steps - New common commands ### Update Template When making changes, add an entry using this format: ``` | YYYY-MM - One-line description | More detail if needed | Section(s) affected | | --- | --- | --- | ``` ### Version History for agents.md - **v1.0** (2025-01): Initial creation with full repository documentation ## Getting Help When unsure about something: 1. Check this documentation first 2. Review existing similar configurations 3. Search NixOS manual and wiki 4. Test changes with dry-run before applying --- **Remember**: This repository values declarative, reproducible configurations. When in doubt, prefer explicit configuration over implicit behavior. Test thoroughly, document changes, and never skip the dry-run step!