docs/design/dog-execution-model.md
Created: 2026-02-27
Gas Town dogs (daemon patrol routines) use two execution models:
The formula-only dogs were broken because no agent interprets their molecules from ticker context. The molecule system requires an idle dog to execute the formula, but the ticker fires regardless of dog availability.
After the Beads Flows work, the Compactor has been upgraded to imperative Go. The Janitor dog was removed entirely — test infrastructure migrated from a dedicated port-3308 Dolt test server to testcontainers-go (Docker), eliminating the orphan test database problem at its source.
This document captures the target execution model going forward.
| Dog | Model | Works? | Notes |
|---|---|---|---|
| Doctor | Imperative Go (466 lines) | Yes | 7 health checks, GC, zombie kill |
| Reaper | Imperative Go (658 lines) | Yes | Close, purge, auto-close, mail purge |
| JSONL Backup | Imperative Go (619 lines) | Yes | Export, scrub, filter, spike detect, push |
| Dolt Backup | Imperative Go | Yes | Filesystem backup sync |
| Compactor | Imperative Go (new) | Yes | Flatten + GC when commits > threshold |
Dogs that MUST run on schedule, unattended, with no agent dependency:
Principle: If the dog's failure would cause a Clown Show, it must be imperative Go.
Dogs whose failure is merely inconvenient, not catastrophic:
For plugin-dispatched dogs:
Run() loopplugins/<dog>/plugin.md with cooldown gatehandleDogs() dispatches to idle dog when cooldown expiresKey constraint: The handleDogs() dispatch path already exists and works.
The issue is that ticker-based dogs bypass it. Plugin dogs use it correctly.
The Doctor, Reaper, Compactor, and backup dogs work reliably as imperative Go. Migrating them to formula+agent would:
The only dogs that should use formula dispatch are ones where agent intelligence adds value or where the dog's task is inherently non-critical.