2026-04-26 14:10:54 +02:00
# Agent Instructions
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
This project uses **bd ** (beads) for issue tracking. Run `bd prime` for full workflow context.
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
## Quick Reference
2025-12-29 18:55:52 +01:00
2026-04-26 14:10:54 +02:00
```bash
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
2025-12-28 11:28:19 +01:00
```
2026-04-26 14:10:54 +02:00
## Non-Interactive Shell Commands
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
**ALWAYS use non-interactive flags** with file operations to avoid hanging on confirmation prompts.
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
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.
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
**Use these forms instead:**
2026-01-02 15:12:26 +01:00
2026-04-26 14:10:54 +02:00
```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
2026-01-02 15:12:26 +01:00
2026-04-26 14:10:54 +02:00
# For recursive operations
rm -rf directory # NOT: rm -r directory
cp -rf source dest # NOT: cp -r source dest
```
2026-01-02 15:12:26 +01:00
2026-04-26 14:10:54 +02:00
**Other commands that may prompt:**
2026-01-02 15:12:26 +01:00
2026-04-26 14:10:54 +02:00
- `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
2026-01-02 15:12:26 +01:00
2026-04-26 14:10:54 +02:00
<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:ca08a54f -->
2026-04-22 17:59:23 +02:00
2026-04-26 14:10:54 +02:00
## Beads Issue Tracker
2026-04-22 17:59:23 +02:00
2026-04-26 14:12:30 +02:00
This project uses **bd (beads) ** for persistent task tracking. Run `bd prime` for full workflow context.
2026-04-22 17:59:23 +02:00
2026-04-26 14:12:30 +02:00
### 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 <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
```bash
bd ready --json
```
Lists issues with no blocking dependencies that are ready to work on.
#### 2. Claim Work
```bash
bd update <id> --claim
```
Atomically assigns the issue to you (sets status to "in-progress").
#### 3. Inspect Details
```bash
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
```bash
# 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
```bash
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
```bash
bd status --json # Current state of all issues
bd stats # Metrics: velocity, cycle time, bottlenecks
```
### Example Complete Workflow
2026-04-22 17:59:23 +02:00
2026-04-26 14:10:54 +02:00
```bash
2026-04-26 14:12:30 +02:00
# 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
2026-04-26 14:10:54 +02:00
```
2026-04-22 17:59:23 +02:00
2026-04-26 14:10:54 +02:00
### 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
<!-- END BEADS INTEGRATION -->
# 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
2026-04-22 17:59:23 +02:00
```
nixos-config/
2026-04-26 14:10:54 +02:00
├── 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
2026-04-22 17:59:23 +02:00
```
2026-04-26 14:10:54 +02:00
---
2026-04-22 17:59:23 +02:00
2026-04-26 14:10:54 +02:00
## Commands
2026-04-22 17:59:23 +02:00
2026-04-26 14:10:54 +02:00
| 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
2026-04-22 17:59:23 +02:00
```nix
{ config, lib, pkgs, ... }:
2026-04-26 14:10:54 +02:00
{
options.myService.enable = lib.mkEnableOption "my service";
config = lib.mkIf config.myService.enable {
services.myService.enable = true;
2026-04-22 17:59:23 +02:00
};
}
```
2026-04-26 14:10:54 +02:00
### Conditionals
2026-04-22 17:59:23 +02:00
2025-12-28 11:28:19 +01:00
```nix
2026-04-26 14:10:54 +02:00
config = lib.mkMerge [
(lib.mkIf cfg.enable { ... })
(lib.mkIf cfg.extraConfig { ... })
];
2025-12-28 11:28:19 +01:00
```
2026-04-26 14:10:54 +02:00
### Anti-Patterns (AVOID)
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
- **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
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
### Imports
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
- Use flake inputs for dependencies (e.g., `inputs.home-manager.nixosModules.home-manager` )
- Import relative paths with `./` or `../`
- Never use absolute paths in imports
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
### Secrets
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
- Secrets managed via **agenix ** in `secrets/` directory
- Never commit plaintext secrets
- Use `.nix` extension for secret files
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
---
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
## Key Files
2025-12-28 11:28:19 +01:00
2026-04-26 14:10:54 +02:00
| 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`