Bug-fix days are the easy case for an agent fleet. I've written about ours — 22 fixes merged in a day, 18 more from a same-day adversarial pass. Bugs parallelize well: each is independent, each has a failing scenario, and no two fixes have to agree with each other.
An epic is the harder test. One feature, cut into tickets that depend on each other, that has to hold together as a design when the last branch merges. This is a log of how such a day is structured when it works — and where it falls apart, which is usually my fault, not the agents'.
The day is decided in the morning
An epic arrives as a paragraph and has to leave the morning as tickets. Each ticket gets a scope sized for one agent, the modules involved, acceptance criteria concrete enough to refute, and a verification command that either passes or doesn't.
Two things matter beyond the individual tickets. Order: the ticket that defines the interface — the schema change, the contract, the shared module — goes first, because everything else builds against it. And disjointness: parallel tickets must not touch the same files, or the branches come back unmergeable and the afternoon goes to conflict archaeology instead of review.
I still do the cut by hand. Agents can draft tickets, but where one ticket ends and the next begins encodes design decisions I'll answer for at the merge gate. Delegating the cut means discovering the design at review time — the most expensive place to discover it.
Dispatch is a state change
There's no kickoff prompt. Dispatch is moving a ticket to Ready — that state change is the trigger, and the queue does the rest. The ticket carries its context: the epic it belongs to, linked design notes, acceptance criteria, what already merged ahead of it. (More on the pipeline in the agentic SDLC use case.)
The interface ticket goes to Ready alone. Once its branch merges, the dependent tickets move to Ready as a batch and the parallel phase begins.
The loop, per ticket
Each agent works the same loop: read the ticket, plan against the codebase — which by mid-day includes the morning's merges — implement in an isolated worktree, run the full test gate, and hand back a branch with a structured report. Every step lands in the run record, so when something goes sideways I read steps, not transcripts.
A pull request is one possible outcome of a run, not the point. Some tickets produce a migration, a config change, or an update to the design doc the later tickets read. The queue doesn't care what shape the artifact takes; it cares that the acceptance criteria are met.
The adversarial pass works the queue again
After the build wave lands, a second wave works the same queue with the opposite brief: don't fix anything, refute. On a bug day that pass catches incomplete fixes. On an epic day it earns its keep at the seams — ticket four was written against ticket one's interface as designed; does it still hold against the interface as merged? Each branch passed its own gate; do they compose?
The bug day taught us that builders write tests that confirm their own understanding. On an epic that bias compounds, because every builder's understanding is one ticket wide. The refuting agents get the whole epic as context and no loyalty to any branch. Findings go back onto the queue as new tickets, and the loop runs again. When the second pass comes back quiet — quiet after visibly trying, which the run record lets you judge — that's the closest thing to a green light the day produces.
What I actually do all day
From the outside, the agents work and I wait. From the inside it's the densest review day I know how to have.
I read diffs. In merge order, with the epic's design in my head — each agent sees one ticket; the composition risk lives with me.
I write notes back. When a diff is wrong, I don't fix it — I write what's wrong onto the ticket and move it back to Ready. Fixing it myself repairs one branch; the note repairs the ticket, and tickets are what carries over to the next epic. Slower for that one branch, faster for every branch after it.
I hold the gate. Every merge is a recorded act with my name on it. That means merging in dependency order, and saying no — sending a branch back even when the tests are green, because green tests written by the same process that wrote the code are a weak signal. The adversarial pass exists because of that weakness.
And I decide, usually mid-afternoon, whether this is still a one-day epic. Some aren't: the cut reveals an unknown, or implementation surfaces a decision that needs a night's thought. Calling that early is part of the job. The process makes a day-sized attempt cheap to stop, which matters more than forcing the calendar to win.
Where the day is won
Not on the agents' brilliance. Every good epic day traces to two variables set before and after the agents run: how well the tickets were cut, and how hard the adversarial pass tried to break the result. Every bad day traces back to me at the ticket editor — a vague criterion, a missed file collision, an interface ticket sequenced too late.
I don't yet have clean numbers for what an epic day costs or how the spend splits between building and refuting [TK: token cost and build/refute split from a measured epic run]. When there's a measured run worth publishing, that's the next post.
One rule has held every day we've run this way: the fleet doesn't make the epic easy. It moves the hard part into the morning, into the tickets — where one person can do it well.