clavitor/forge/dispatcher
James 8400acffb9 Add Agent Dispatcher - runs on forge, polls Zurich Gitea
Simple Go binary that:
- Polls git.clavitor.ai every 60 seconds from forge
- Dispatches 1 task per minute max (rate limited)
- Priority order: CRITICAL > HIGH > NORMAL > LOW
- Writes task files to .agent-tasks/<agent>/issue-#.md
- Built-in web UI at http://forge:8098
- Full verbose logging to .agent-dispatcher.log
- No external deps (no Prometheus, etc.)

Files:
- forge/dispatcher/main.go (the dispatcher)
- forge/dispatcher/README.md (instructions)
- forge/dispatcher/go.mod

Monitoring:
- Web dashboard: http://localhost:8098 (auto-refresh)
- Live logs: tail -f .agent-dispatcher.log
- Task files: ls .agent-tasks/<agent>/
2026-04-09 01:33:10 -04:00
..
README.md Add Agent Dispatcher - runs on forge, polls Zurich Gitea 2026-04-09 01:33:10 -04:00
dispatcher Add Agent Dispatcher - runs on forge, polls Zurich Gitea 2026-04-09 01:33:10 -04:00
go.mod Add Agent Dispatcher - runs on forge, polls Zurich Gitea 2026-04-09 01:33:10 -04:00
main.go Add Agent Dispatcher - runs on forge, polls Zurich Gitea 2026-04-09 01:33:10 -04:00

README.md

Agent Dispatcher

Auto-dispatches Gitea issues to agent task files. Runs on forge (development center).

Quick Start

# 1. Set token
export GITEA_TOKEN="775a12730a65cbaf1673da048b7d01859b8b58e0"

# 2. Build
cd /home/johan/dev/clavitor/forge/dispatcher
go build -o dispatcher .

# 3. Run
./dispatcher

Web Dashboard

Open: http://forge:8098 (or http://localhost:8098)

Shows:

  • Real-time dispatch status
  • Tasks by agent
  • Recent dispatches (with priority highlighting)
  • Live log tail

How It Works

  1. Polls Gitea every 60 seconds (from forge, connects to Zurich)
  2. Finds open issues with assignees
  3. Dispatches 1 task per minute max (rate limit)
  4. Priority order: CRITICAL → HIGH → NORMAL → LOW
  5. Writes to: /home/johan/dev/clavitor/.agent-tasks/<agent>/issue-#.md

Task File Format

Each dispatched task creates a file like:

/home/johan/dev/clavitor/.agent-tasks/hans/issue-2.md

Contains full instructions, links, context from the issue.

Monitoring

Web UI

http://localhost:8098 — Auto-refresh every 10 seconds

Command Line

# Watch live log
tail -f /home/johan/dev/clavitor/.agent-dispatcher.log

# See tasks for an agent
ls /home/johan/dev/clavitor/.agent-tasks/hans/

# Read specific task
cat /home/johan/dev/clavitor/.agent-tasks/hans/issue-2.md

Systemd Service (Run Always)

# Create service file
sudo tee /etc/systemd/system/clavitor-dispatcher.service << 'EOF'
[Unit]
Description=Clavitor Agent Dispatcher
After=network.target

[Service]
Type=simple
User=johan
WorkingDirectory=/home/johan/dev/clavitor/forge/dispatcher
Environment="GITEA_TOKEN=775a12730a65cbaf1673da048b7d01859b8b58e0"
ExecStart=/home/johan/dev/clavitor/forge/dispatcher/dispatcher
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable clavitor-dispatcher
sudo systemctl start clavitor-dispatcher

# Check status
sudo systemctl status clavitor-dispatcher
journalctl -u clavitor-dispatcher -f

Logs

All activity logged to:

  • Console (stdout)
  • File: /home/johan/dev/clavitor/.agent-dispatcher.log

Log format:

[DISPATCHER] 2026/04/09 14:32:15.123456 ✅ DISPATCHED: hans → Issue #2 (CRITICAL: silent DB errors) [Priority: CRITICAL]

Rate Limiting

Hard limit: 1 task per minute

Prevents runaway dispatching. Even if 10 CRITICAL issues appear, only 1 dispatched per minute.

Manual Override

If you need to dispatch urgently:

# Just tell the agent directly:
"Hans, execute issue #5 now: cat /home/johan/dev/clavitor/.agent-tasks/hans/issue-5.md"

The dispatcher will skip already-dispatched issues (checks file existence).

Troubleshooting

Problem Check
No tasks appearing tail -f .agent-dispatcher.log — is Gitea reachable?
Web UI not loading netstat -tlnp | grep 8098 — port in use?
Auth errors echo $GITEA_TOKEN — token set?
Not dispatching Issues must be: open + assigned + not already dispatched

Architecture

Forge (This Machine)          Zurich (Gitea)
┌──────────────────┐          ┌─────────────┐
│ Dispatcher       │◄────────►│ git.clavitor.ai
│ :8098            │  HTTPS   │ (issues API)
│ .agent-tasks/    │          └─────────────┘
└──────────────────┘

Key point: Dispatcher runs on forge (your control), polls Zurich (Gitea).