Files
nixos-config/AGENTS.md
m3tm3re e6cfcc346b docs(agents): expand Beads workflow documentation
- Add 6-step core workflow with examples
- Document slash commands for agent integration
- Add 'Why Beads?' section emphasizing persistence
- Note to avoid bd edit in agent contexts
- Include dependency linking examples
2026-04-26 14:12:30 +02:00

14 KiB

Agent Instructions

This project uses bd (beads) for issue tracking. Run bd prime for full workflow context.

Quick Reference

bd ready              # Find available work
bd show <id>          # View issue details
bd update <id> --claim  # Claim work atomically
bd close <id>         # 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:

# 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 insteadbd update <id> --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

bd ready --json

Lists issues with no blocking dependencies that are ready to work on.

2. Claim Work

bd update <id> --claim

Atomically assigns the issue to you (sets status to "in-progress").

3. Inspect Details

bd show <id>

View full issue details including:

  • Description and acceptance criteria
  • Blocking/blocked-by dependencies
  • Time estimates
  • Status history

4. Create Newly Discovered Work

# Create a new issue
bd create \
  --title "Fix audio on m3-helios" \
  --estimate 2 \
  --priority high \
  --labels nixos,audio

# Link dependencies
bd dep <id> --blocks <blocked-id>      # This issue blocks another
bd dep <id> --after <after-id>         # This issue after another completes
bd dep <id> --requires <requires-id>  # This issue requires another

5. Complete Work

bd close <id> --reason "Added PulseAudio fallback to configuration.nix"

Provide a concise summary of what was done. The --reason is mandatory.

6. Project Snapshot

bd status --json    # Current state of all issues
bd stats            # Metrics: velocity, cycle time, bottlenecks

Example Complete Workflow

# 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:
    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

{ config, lib, pkgs, ... }:
{
  options.myService.enable = lib.mkEnableOption "my service";
  config = lib.mkIf config.myService.enable {
    services.myService.enable = true;
  };
}

Conditionals

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 <nixpkgs> — 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.nixnixosConfigurations
  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

# 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