Running agents as a delivery team
Eight defined roles, a written backlog, and seventeen checks that reject work breaking the architecture. Most of what I've learned is about the guardrails, not the prompts.
Most writing about coding agents is about prompting. Almost none of it is about what happens on the fiftieth story, when the agent has no memory of the architectural decision it made on the twelfth.
I’ve been building a consumer product this way for months. Not autocomplete — agents with defined roles, working stories out of a written backlog, opening pull requests that get rejected by CI when they break something. The setup now has eight roles, seventeen enforcement checks (thirteen of them wired into CI), and a backlog of 359 stories, 231 of them done.
Almost everything I’ve learned sits in the checks, not the prompts.
The loop
Roles, not one long conversation
There are eight agent definitions: product owner, business analyst, tech lead and architect, developer, QA, infrastructure, security reviewer, and a founder role that holds decisions the others aren’t allowed to make.
Each has its own written rules and is entered deliberately. This matters more than it sounds. A single conversation that drifts from “what should we build” to “how should we build it” to “ship it” produces an agent that is optimistic about its own work at exactly the moment it should be sceptical. Separating the roles means the thing reviewing the code is not the thing that just wrote it.
The backlog is the interface
Nothing gets built from a chat message. Stories live in a versioned file with acceptance criteria attached, and a story that isn’t ready doesn’t get picked up — there’s a check for that.
Why this exists
In one autonomous run, five stories marked ready turned out not to be buildable, and every one was discovered only after the loop had selected it, read its spec and started looking at the code. “Ready” had been asserting that a human groomed the story, not that the things it needs exist.
So the check asks three questions of every story before it can be picked up:
- Is every dependency it declares actually finished?
- Does its description or its acceptance criteria name a story it does not declare?
- Does it tell the agent to build on code that does not exist anywhere in the repository?
The discipline this forces is on me, not the agent. If a story is ambiguous, the correct move is to raise it as a gap rather than let something plausible get built. Most of my bad outcomes came from underspecified stories, not from bad code generation.
The guardrails are a record of every surprise
This is the part I’d tell anyone starting. The seventeen checks weren’t designed up front. Each one exists because something went wrong once, and I decided a written instruction wasn’t enough to stop it happening again.
They fall into four groups:
Architecture. A module may not reach into another module’s tables. The presentation layers may not reference each other. The boundaries are enforced at build time, so the architecture is a fact rather than an agreement.
Discipline the agent will otherwise quietly skip. No sleep in tests. No
bare constants in specs. No story shipping with empty acceptance tests. Every
one of these is a shortcut an agent takes when it is trying to make a suite go
green, and none of them is visible in a diff review.
Provenance. Branch provenance, detached-HEAD detection, migration versions, schema provenance. Agents are startlingly good at producing a change that works and is impossible to trace afterwards.
Drift. Design tokens — no raw colour outside the tokens file. Module READMEs going stale against the code they describe. Documentation that quietly stops being true is worse than no documentation, because the next agent reads it and believes it.
The pattern underneath all four: an instruction is a hope, a failing build is a fact. Anything you would have to remember, the agent will eventually not remember either.
- module_boundaries
- protected_files
- design_tokens
- migration_versions
- branch_provenance
- no_sleep
- no_bare_constants_in_specs
- spec_directory_coverage
- i18n_hardcoded_copy
- i18n_date_time_usage
- module_readme_freshness
- backlog_test_coverage
- os_conformance
- schema_provenance
- detached_head
- product_boundary
- ticket_readiness
What this does not fix
It doesn’t make product decisions. The proportion of my time spent on “what should this do” versus “how do I build it” has moved dramatically toward the former, and that work has not gotten easier — it’s just now the whole job.
It doesn’t help with taste. The agent will happily build a well-tested, cleanly bounded, correctly provenanced version of the wrong feature.
And it isn’t free. Seventeen checks is real infrastructure with its own maintenance cost. I think it pays for itself somewhere around the point a codebase outgrows what one person can hold in their head — which, with agents, arrives much sooner than it used to.
What I’d take to a team
The transferable part isn’t the tooling. It’s the idea that when work is produced faster than it can be reviewed, review has to become mechanical to survive. That’s true of a team of agents. I suspect it’s about to be true of a lot of engineering teams.