nixos/docs/agents.md
Julian Sutter 7143d71bf5 docs: Create comprehensive agents.md and deprecate .clinerules
- Added docs/agents.md with complete repository guide
- Includes all project structure, workflows, testing procedures
- Covers package management, security, rollback procedures
- Added maintenance section with changelog for future updates
- Deprecated .clinerules, pointing to agents.md instead
- Created single source of truth for AI agent operations
2026-02-03 22:26:32 -08:00

748 lines
No EOL
20 KiB
Markdown

# 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
└── .clinerules # Project-specific rules for AI agents
```
## 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/<hostname>.nix` following existing patterns
2. Set `networking.hostName = "<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 `<username>.nix`
4. Home Manager configuration goes in `home-manager.users.<username>`
## 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 .#<name> --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/<hostname>.nix` |
| Common user settings | `users/common-home.nix` |
| User config | `users/<username>.nix` |
| Desktop apps | `desktop/<category>.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 and deprecated `.clinerules` | All sections |
### 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. Consult the `.clinerules` file for additional guidelines
5. 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!