# AGENTS.md Repository guidelines for AI coding agents. ## Issue Tracking (Beads) **Session start**: Run `bd ready` to see available work. **Commands:** - `bd ready` - Issues with no blockers - `bd show ` - Issue details - `bd update --status=in_progress` - Claim work - `bd close ` - Complete work - `bd create --title="..." --type=task|bug|feature` - New issue - `bd dep add ` - Add dependency **Session end**: `git status`, `git add`, `git commit`. Ephemeral branch - merge to main locally. ## Overview NixOS-based Matrix homeserver (conduwuit) with mautrix-slack bridge for Slack ↔ Matrix messaging. **Technologies**: Nix 2.x, NixOS 24.05+, conduwuit, mautrix-slack, PostgreSQL 15, sops-nix ## Project Structure ``` . ├── hosts/ # NixOS host configurations │ └── ops-jrz1.nix # VPS configuration ├── modules/ # NixOS modules │ ├── dev-services.nix # PostgreSQL, Forgejo, bridge coordination │ ├── mautrix-slack.nix # Slack bridge module │ └── matrix-continuwuity.nix # Matrix homeserver ├── secrets/ # sops-encrypted secrets │ └── secrets.yaml # Encrypted credentials (age) ├── specs/ # Feature specifications │ ├── 001-extract-matrix-platform/ │ └── 002-slack-bridge-integration/ ├── docs/ # Documentation │ ├── platform-vision.md # North star document │ └── worklogs/ # Deployment logs └── scripts/ # Utility scripts (packaged via writeShellApplication) ├── killswitch # Emergency user termination ├── cpu-watchdog # CPU abuse detection ├── egress-watchdog # Egress rate limit abuse detection ├── dev-add.sh # Add dev user account └── dev-remove.sh # Remove dev user account ``` ## Commands ### Deployment ```bash # Deploy to VPS nixos-rebuild switch --flake .#ops-jrz1 --target-host root@ops-jrz1 --build-host localhost # Validate before deploy nix flake check nix build .#nixosConfigurations.ops-jrz1 ``` ### Bridge Management ```bash # Check bridge status ssh root@ops-jrz1 'systemctl status mautrix-slack' # View bridge logs ssh root@ops-jrz1 'journalctl -u mautrix-slack -f' # Check for errors ssh root@ops-jrz1 'journalctl -u mautrix-slack --since "1 hour ago" | grep -E "ERR|WRN|FTL"' ``` ### Secrets Management ```bash # Edit encrypted secrets sops secrets/secrets.yaml # View decrypted (never commit output) sops -d secrets/secrets.yaml ``` ### SSH Tunnels ```bash # Maubot web UI ssh -L 29316:localhost:29316 root@ops-jrz1 # Access: http://localhost:29316 # Matrix homeserver (debugging) ssh -L 8008:localhost:8008 root@ops-jrz1 ``` ## Coding Conventions - Two-space indentation in Nix files - Use `lowerCamelCase` for options, kebab-case for filenames - Format with `nix fmt` before committing - NixOS modules: Use nixpkgs pattern (options, config, mkIf) - Never hardcode secrets, use sops-nix ## Git Workflow **Trunk-Based Development:** - `main`: Single long-lived branch, always deployable - Feature branches: Short-lived, naming `###-feature-name` - Tag releases after merging: `v0.MINOR.PATCH` **Commits:** - Clear, concise messages (~70 chars) - No emojis or marketing language - Reference specs/worklogs in body ## Development Patterns ### Slack Bridge - **Authentication**: Interactive login via Matrix chat (`login app` command) - **Socket Mode**: WebSocket connection, no public endpoint needed - **Portal Creation**: Automatic based on activity - **Tokens**: Bot token (xoxb-) + app-level token (xapp-) ### Secrets Flow - Encryption: Age via SSH host key - Storage: secrets/secrets.yaml (encrypted, safe to commit) - Runtime: Decrypted to /run/secrets/ (tmpfs) ### Deployment Workflow 1. Make configuration changes locally 2. Run `nix flake check` to validate 3. Commit to git 4. Deploy via nixos-rebuild (scripts deploy automatically) 5. Verify service status and logs 6. Document in worklogs/ ## Architecture ``` ┌─────────────────────────────────────────────────────┐ │ clarun.xyz VPS │ │ │ │ nginx :443 (HTTPS) │ │ ├─→ conduwuit :8008 (Matrix homeserver) │ │ └─→ Forgejo :3000 │ │ │ │ mautrix-slack :29319 │ │ └─→ PostgreSQL (unix socket) │ │ │ └─────────────────────────────────────────────────────┘ │ └─→ Slack API (Socket Mode WebSocket) ``` **Critical**: All internal services use IPv4 (127.0.0.1), NOT "localhost" (which resolves to IPv6). ## Known Issues - olm-3.2.16 marked insecure (permitted via nixpkgs.config) - Fresh database required after conduwuit version upgrades ## Testing - `nix flake check` - minimum gate - Add VM tests in `hosts/ops-jrz1-vm.nix` for new services - Capture verification steps in `docs/worklogs/` - Test message latency: should be <5 seconds