# Agent Instructions This project uses **bd** (beads) for issue tracking. Run `bd prime` for full workflow context. ## Quick Reference ```bash bd ready # Find available work bd show # View issue details bd update --claim # Claim work atomically bd close # Complete work bd dolt push # Push beads data to remote ``` ## Non-Interactive Shell Commands **ALWAYS use non-interactive flags** with file operations to avoid hanging on confirmation prompts. Shell commands like `cp`, `mv`, and `rm` may be aliased to include `-i` (interactive) mode on some systems, causing the agent to hang indefinitely waiting for y/n input. **Use these forms instead:** ```bash # Force overwrite without prompting cp -f source dest # NOT: cp source dest mv -f source dest # NOT: mv source dest rm -f file # NOT: rm file # For recursive operations rm -rf directory # NOT: rm -r directory cp -rf source dest # NOT: cp -r source dest ``` **Other commands that may prompt:** - `scp` - use `-o BatchMode=yes` for non-interactive - `ssh` - use `-o BatchMode=yes` to fail instead of prompting - `apt-get` - use `-y` flag - `brew` - use `HOMEBREW_NO_AUTO_UPDATE=1` env var ## Beads Issue Tracker This project uses **bd (beads)** for persistent task tracking. Run `bd prime` for full workflow context. ### Why Beads? - **Prefer Beads over ad-hoc markdown TODO lists** — Beads provides structured, queryable, shareable issue tracking with dependency management - **Never use `bd edit`** — it opens an interactive editor which blocks agent workflows - **Use flags and stdin instead** — `bd update --claim`, `bd create --title "..." --estimate 2` ### Slash Commands (Agent Workflow) | Command | Purpose | |---------|---------| | `/beads:ready` | Find unblocked issues | | `/beads:create` | Create a new issue | | `/beads:update` | Update an issue (claim, status) | | `/beads:close` | Close completed work | | `/beads:stats` | Project-level snapshot | ### Core Workflow (6 Steps) #### 1. Find Unblocked Work ```bash bd ready --json ``` Lists issues with no blocking dependencies that are ready to work on. #### 2. Claim Work ```bash bd update --claim ``` Atomically assigns the issue to you (sets status to "in-progress"). #### 3. Inspect Details ```bash bd show ``` View full issue details including: - Description and acceptance criteria - Blocking/blocked-by dependencies - Time estimates - Status history #### 4. Create Newly Discovered Work ```bash # Create a new issue bd create \ --title "Fix audio on m3-helios" \ --estimate 2 \ --priority high \ --labels nixos,audio # Link dependencies bd dep --blocks # This issue blocks another bd dep --after # This issue after another completes bd dep --requires # This issue requires another ``` #### 5. Complete Work ```bash bd close --reason "Added PulseAudio fallback to configuration.nix" ``` Provide a concise summary of what was done. The `--reason` is mandatory. #### 6. Project Snapshot ```bash bd status --json # Current state of all issues bd stats # Metrics: velocity, cycle time, bottlenecks ``` ### Example Complete Workflow ```bash # Start session - find work bd ready --json # Claim available issue bd update 42 --claim # Do the work... # Discover something else needed bd create --title "Document hermes-agent setup" --estimate 1 # Link as related bd dep 43 --after 42 # Complete original bd close 42 --reason "Added Hyprland idle timeout config" # Close related bd close 43 --reason "Added setup docs to AGENTS.md" # Push state to remote bd dolt push ``` ### Rules - Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists - Run `bd prime` for detailed command reference and session close protocol - Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files ## Session Completion **When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds. **MANDATORY WORKFLOW:** 1. **File issues for remaining work** - Create issues for anything that needs follow-up 2. **Run quality gates** (if code changed) - Tests, linters, builds 3. **Update issue status** - Close finished work, update in-progress items 4. **PUSH TO REMOTE** - This is MANDATORY: ```bash git pull --rebase bd dolt push git push git status # MUST show "up to date with origin" ``` 5. **Clean up** - Clear stashes, prune remote branches 6. **Verify** - All changes committed AND pushed 7. **Hand off** - Provide context for next session **CRITICAL RULES:** - Work is NOT complete until `git push` succeeds - NEVER stop before pushing - that leaves work stranded locally - NEVER say "ready to push when you are" - YOU must push - If push fails, resolve and retry until it succeeds # Project Agent **Workspace Path:** `/home/m3tam3re/p/NIX/nixos-config` _(Note to Pi: Your file write/edit tools run in a different directory by default. You MUST use absolute paths starting with the Workspace Path above for ALL file operations!)_ **Generated:** 2026-04-26 --- ## Stack | Component | Version/Source | | ---------------- | --------------------------------- | | **Nixpkgs** | nixos-unstable + 25.05 stable | | **Home Manager** | github:nix-community/home-manager | | **Agenix** | github:ryantm/agenix | | **Disko** | github:nix-community/disko | | **NUR** | github:nix-community/NUR | | **Formatter** | alejandra | | **Linters** | statix, deadnix | | **IDE** | nixd | | **Hermes Agent** | NousResearch/hermes-agent | | **LLM Agents** | numtide/llm-agents.nix | --- ## Structure ``` nixos-config/ ├── flake.nix # Entry point: hosts, overlays, dev shells ├── coding-rules.json # Opencode rules configuration │ ├── hosts/ # Per-host NixOS configurations │ ├── common/ # Shared across all hosts │ │ ├── users/ # User definitions │ │ ├── ports.nix # Network ports config │ │ └── extraServices/ # Common service toggles │ ├── m3-ares/ # Main desktop │ ├── m3-atlas/ # Desktop with disko │ ├── m3-helios/ # Desktop with disko │ ├── m3-hermes/ # Desktop with disko + hermes-agent │ └── m3-kratos/ # Server with NUR │ ├── modules/ # Reusable NixOS/home-manager modules │ ├── nixos/ # NixOS-specific modules │ │ └── default.nix # Imports common + service configs │ └── home-manager/ # Home-manager configurations │ ├── home/ # Per-user, per-host home configs │ └── m3tam3re/ │ └── m3-daedalus.nix │ ├── overlays/ # Package overlays │ ├── default.nix # Stable/locked/master branches │ └── mods/ # Package modifications │ ├── pkgs/ # Custom packages │ ├── secrets/ # Encrypted secrets (agenix) │ └── secrets.nix │ ├── .opencode-rules/ # Opencode AI rules │ ├── concerns/ # Coding style rules │ ├── languages/nix.md # Nix conventions │ └── USAGE.md │ └── .pi/ # Agent configuration ``` --- ## Commands | Action | Command | Notes | | -------------------- | ---------------------------------------------------------------------- | ------------------------------------------------- | | **Enter dev shell** | `nix develop` | Includes alejandra, nixd, agenix, statix, deadnix | | **Build host** | `sudo nixos-rebuild switch --flake .#m3-ares` | Replace hostname as needed | | **Dry run build** | `sudo nixos-rebuild dry-run --flake .#m3-ares` | Validate without applying | | **List hosts** | `nix flake show` | Shows all NixOS configurations | | **Update flake** | `sudo nixos-rebuild switch --flake .#m3-ares --update-input nixpkgs` | Update specific input | | **Format code** | `alejandra .` | Run before committing | | **Check lint** | `statix check .` | Run statix for antipatterns | | **Remove dead code** | `deadnix -w .` | Clean up unused let bindings | | **Build ISO** | `nix build .#nixosConfigurations.m3-ares.config.system.build.isoImage` | Generate install ISO | --- ## Conventions ### Formatting & Style - **Formatter:** `alejandra` (mandatory, run before commits) - **Indentation:** 2 spaces (alejandra default) - **Variables:** camelCase (e.g., `maxRetryAttempts`) - **Types/Modules:** PascalCase (e.g., `MyService`) - **Constants:** UPPER_SNAKE_CASE (e.g., `MAX_RETRIES`) - **Files:** hyphen-case (e.g., `my-file.nix`) ### Nix Module Patterns ```nix { config, lib, pkgs, ... }: { options.myService.enable = lib.mkEnableOption "my service"; config = lib.mkIf config.myService.enable { services.myService.enable = true; }; } ``` ### Conditionals ```nix config = lib.mkMerge [ (lib.mkIf cfg.enable { ... }) (lib.mkIf cfg.extraConfig { ... }) ]; ``` ### Anti-Patterns (AVOID) - **Never use `with pkgs;`** — always use explicit package references - **Never use `builtins.fetchTarball`** — use flake inputs instead - **Never use `import `** — always use inputs - **Never use `builtins.getAttr/hasAttr`** — use `lib.attrByPath` or `lib.optionalAttrs` - **Avoid anonymous functions in config** — extract to named lets ### Imports - Use flake inputs for dependencies (e.g., `inputs.home-manager.nixosModules.home-manager`) - Import relative paths with `./` or `../` - Never use absolute paths in imports ### Secrets - Secrets managed via **agenix** in `secrets/` directory - Never commit plaintext secrets - Use `.nix` extension for secret files --- ## Key Files | File | Purpose | | ---------------------------------- | ------------------------------------------------------------------------------------------ | | `flake.nix` | Central entry point defining all hosts, overlays, packages, dev shells, and nixpkgs config | | `hosts/common/default.nix` | Shared Nix settings, nixpkgs overlays, home-manager integration, user defaults | | `hosts/m3-ares/default.nix` | Main desktop host configuration, imports common + service modules | | `hosts/m3-ares/configuration.nix` | Desktop environment config (Hyprland, display, audio, etc.) | | `hosts/m3-ares/programs.nix` | CLI tools, dev tools, shell configs | | `hosts/m3-ares/services/` | Service-specific configs (firewall, printing, etc.) | | `modules/nixos/default.nix` | Orchestrates common + configuration imports | | `overlays/default.nix` | Package version overrides (stable/locked/master branches) | | `.opencode-rules/languages/nix.md` | Nix-specific conventions and patterns | --- ## What to Avoid 1. **Don't modify `flake.lock`** directly — use `nix flake update` 2. **Don't use impure operations** — this is a pure flake-based config 3. **Don't commit without formatting** — always run `alejandra .` first 4. **Don't add packages to hosts directly** — prefer adding to overlays or using NUR 5. **Don't hardcode paths** — use `inputs` and relative imports 6. **Don't create monolithic modules** — keep functions under 20 lines 7. **Don't skip the dry-run** — always test with `--dry-run` before switching 8. **Don't use lib.mkDefault lightly** — understand the precedence implications --- ## Notes ### Adding a New Host 1. Add entry to `flake.nix` → `nixosConfigurations` 2. Create directory in `hosts/` with: - `default.nix` — imports common + specific configs - `configuration.nix` — host-specific system config - `hardware-configuration.nix` — from `nixos-generate-config` - `programs.nix`, `services/`, `secrets.nix` as needed 3. Run `sudo nixos-generate-config --dir ./hosts/new-host` first time ### Adding a New Package 1. For simple packages: add to appropriate overlay in `overlays/default.nix` 2. For complex packages: create in `pkgs/` directory 3. For upstream packages: use NUR or add as flake input ### Development Workflow 1. Edit config files 2. Run `alejandra .` to format 3. Run `statix check .` for linting 4. Run `sudo nixos-rebuild dry-run --flake .#m3-ares` 5. If successful: `sudo nixos-rebuild switch --flake .#m3-ares` ### Remote Building ```bash # Build on remote machine nix copy --to ssh://user@host .#nixosConfigurations.m3-ares.config.system.build.toplevel ssh user@host 'sudo nixos-rebuild switch --flake /nix/store/...-closure' ``` ### Home Manager - Home configs live in `home/m3tam3re/` - Use `home-manager.users.m3tam3re` in host config - Access via `config.home-manager.users.m3tam3re`