BoBit worked. Nothing managed it. Two bridges were running when this program started — one for Rough Industries, one for Will Artley — both hand-launched, both from a developer’s own build. Everything about them lived in filesystem and flag conventions rather than in the product.
- Config was CLI flags. Nineteen of them. Nothing was in the database.
- Lifecycle was
makeandnohup.make stop-bobitfell back topkill -f "./bobit"when the pidfile was missing — which would have killed both bridges. - One bridge had no make target and no pidfile at all. Its exact flags existed only in the process table; had it died, the launch command was unrecoverable. Written down is not managed.
- Cost was invisible. Every message spawns
claude -p, which spends real money, and none of it was recorded anywhere. - Port allocation was manual. A third bridge meant remembering that 8766 and 8767 were taken.
The key finding was that the agent system already fitted, and safely. Agent already carried everything a process manager needs — status, heartbeats, config revisions, cost events, budgets — while the dispatcher’s existing agent_type = worker filter kept a bridge out of task execution by construction. That property is what made the whole approach safe.
The verification pass that followed then narrowed it honestly, which is the more useful half: “by construction” covered dispatch, not assignment. Two paths handed a bridge a task with no type filter at all, and Phase 1 closed the gap. The enum audit that came with it was a list rather than a feeling — 12 agent_type sites, 6 templates, 4 seeds, and 27 Agent.Query() call sites of which 6 lacked a type filter — and every later phase applied that list instead of re-deriving it.