ops-jrz1/AGENTS.md

6.7 KiB

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 <id> - Issue details
  • bd update <id> --status=in_progress - Claim work
  • bd close <id> - Complete work
  • bd create --title="..." --type=task|bug|feature - New issue
  • bd dep add <issue> <depends-on> - 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

# 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

# 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

# Edit encrypted secrets
sops secrets/secrets.yaml

# View decrypted (never commit output)
sops -d secrets/secrets.yaml

SSH Tunnels

# 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

Forgejo Administration

# Find the correct gitea binary (Forgejo uses gitea internally)
# Use the version matching your deployed Forgejo - check with: systemctl status forgejo
GITEA_BIN=$(find /nix/store -name "gitea" -path "*forgejo-7*" -type f -executable | head -1)

# Generate a scoped API token (runs as forgejo user)
ssh root@ops-jrz1 "sudo -u forgejo $GITEA_BIN admin user generate-access-token \\
  --username dan \\
  --token-name 'temp-task-name' \\
  --scopes 'write:repository,read:repository' \\
  --config /var/lib/forgejo/custom/conf/app.ini"

# Common scopes:
#   write:admin,read:admin,write:user  - User provisioning (dev-add.sh)
#   write:repository,read:repository   - Repo settings (default branch, etc.)

# Update repo settings (e.g., default branch)
ssh root@ops-jrz1 'curl -s -X PATCH "http://localhost:3000/api/v1/repos/OWNER/REPO" \
  -H "Authorization: token YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"default_branch\": \"main\"}"'

# After using temp token, delete via: https://git.clarun.xyz/user/settings/applications

Gotchas:

  • Token at /run/secrets/forgejo-api-token has admin scope only (for dev-add.sh)
  • Binary version must match DB schema - newer binaries fail with column errors
  • Forgejo API docs: https://git.clarun.xyz/api/swagger

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