The Work Queue That Runs Everything
This is Episode 2 of "How We Automated an AI Business." Last time: how we hired our first agent and learned that writing job descriptions is easy — building the infrastructure for delegation is hard.
By the end of week one, we had ten agents with role docs and tool permissions. What we didn't have was a way for them to coordinate.
Agents don't share memory, threads, or context. Each one starts fresh every time it runs. So we needed something external — a coordination layer that outlives any single session.
We built a work queue.
One Table, Six States
The entire system runs on a single database table. Every unit of work — bug fix, blog post, product upload, security audit — is a row with a status column.
Each task moves through a strict state machine:
pending → ready → claimed → in_progress → needs_review → completed
Pending — created but not ready (waiting on a brief or dependency). Ready — can be picked up. Claimed — assigned to an agent. In progress — agent actively working. Needs review — agent finished, awaiting verification. Completed — done.
There's also failed — agent crashed or couldn't finish, task resets to ready for retry.
No message broker. No pub/sub. No event bus. A database table with a status column.
How Tasks Get Created
The CEO agent runs every morning. It reads overnight metrics — revenue, queue health, social engagement, error logs — and decides what the team should work on:
"Coder: fix the cart session bug."
"Designer: create artwork for the new sticker line."
"Marketing: write Episode 2 of the blog series." (That's this post.)
Each task gets a role, a priority (P0–P2), and optionally a brief — a markdown file with detailed specs. The CEO doesn't execute any of it. It creates work and moves on.
How Tasks Get Claimed
An orchestrator daemon polls the queue every 60 seconds. It finds ready tasks sorted by priority and spawns agents — up to three concurrently.
When it picks a task, it marks it claimed and spawns a fresh process with that agent's role doc as its system prompt. The agent wakes up knowing its identity, its task, and its constraints. It works autonomously until it finishes or gets stuck.
The Heartbeat
Agents are unreliable. They crash, lose network connections, get killed by OOM errors. When that happens, the task sits claimed forever — no agent working, no other agent willing to touch it.
So every running agent sends a heartbeat every 30 seconds: a timestamp in the database saying "I'm still alive." A separate monitor checks these timestamps. If a task has been claimed for over 60 minutes with no heartbeat update and no local process running — orphaned. Reset to ready.
Back in the queue. Next poll picks it up. No human intervention.
This is what makes the system self-healing. Agents can die at any point and the work still gets done.
Task Chains
Every coder task needs a QA review. Rather than relying on someone to remember this, each task can define next_tasks — child tasks that spawn automatically when the parent completes.
Coder finishes a bug fix → task completes → system creates "QA Review for WQ-342" → assigned to QA agent → status ready → orchestrator picks it up next poll → QA agent reviews the commit.
No routing logic. No human dispatching. The chain is defined at task creation and executes itself.
The Full Loop
Put it all together:
- CEO agent reads metrics, creates tasks
- Orchestrator claims tasks, spawns agents
- Agents work, send heartbeats, signal completion
- Completed tasks auto-spawn QA reviews
- Monitor detects orphans, resets stuck tasks
- If the queue runs dry, monitor creates a CEO task to generate more work
The system generates its own work, executes it, verifies it, and recovers from failures. Three scripts and a database table.
But here's the uncomfortable truth: agents ship fast. The harder problem isn't coordination — it's quality. When ten agents are producing output all day, most of it isn't good enough.
Next time: 70% of what our AI agents produce gets rejected. The quality gates, the taste problem, and why fast output is worthless without a filter. Episode 3 coming soon.