Agent John, from client request to shipped PR
activeHow a plain-language client request becomes a ticket, a verified code analysis, then a pull request, across three agents with strictly separated permissions.
case study · updated August 31, 2026
Three agents, three narrow jobs, one pipeline. A client request becomes a ticket. A ticket becomes a code analysis. An approved analysis becomes a pull request. No single agent does all three steps, and that separation is the whole design.
This runs in production today, for our own client delivery. It is recent: renamed from an earlier internal name a few weeks ago, still gaining hours in production. What follows is what it actually does, including what it got wrong along the way.
A mini-PRD, not a summary
A client user describes a problem on a "Demandes" page inside their app. Agent John does not take the first sentence at face value. It asks one sharp question at a time, digs into what is actually broken, who is affected, and what "done" looks like, then files a ticket built as a mini-PRD with five fixed sections: Contexte, Besoin, Comportement attendu, Critères d'acceptation, Hors périmètre. A section is never dropped, even when the answer is "none."
The acceptance criteria matter more than the rest. They are what the next agent in the chain checks the code against.
Read before you judge
As soon as a ticket lands, the Instruction Agent opens the client's actual GitHub repo, read-only, and reads it before writing anything. This is enforced, not just prompted: an analysis submitted without having opened a single file is rejected and never saved. A plausible-sounding analysis based only on the ticket text is exactly the failure mode this guards against.
The output is capped at roughly 200 words: which files are involved, what the request means, what it proposes to change, and what remains unknown. It ends with one of three verdicts: proposed (ready for a green light), needs_info (a blocking unknown), or escalated (the change touches the database schema or core business logic, and belongs to a human).
The green light is atomic
A human reviews the analysis, not the raw ticket, and approves it. That approval and the ticket's move into development happen in the same transaction. A ticket sitting in "in development" with no recorded approver cannot exist: not a rule enforced by convention, a state the data model does not allow.
When the analysis is right but the wording is off, correcting it by hand is faster and more reliable than rejecting it and hoping the agent converges on a second pass.
Design-only, on purpose
Only after the green light does the Development Agent get write access. Its scope is deliberately narrow: CSS, UI components, Tailwind config. No business logic, no API routes, no schema changes. It reads the files it needs, makes targeted edits, and opens a pull request. It never merges its own PR. A GitHub webhook is the only thing that closes the loop, marking the ticket done once a human merges the PR.
What the first weeks caught
Two real defects showed the design working as intended.
The Instruction Agent's analyses were supposed to average 200 words. They drifted to 680, seven times the target, without anything measuring it until someone read fifteen in a row. The fix was a warning at double the target: catch drift, not the odd ten words over.
A branch-naming bug once collapsed 22 tickets onto just two branch names, stalling development completely. Branch names now derive from the ticket number, one ticket, one branch, and a second green light on the same ticket pushes to the branch already open instead of creating a second one.
Why there is no LangGraph here
Batch ticket processing needed to survive an interrupted run without losing work, which briefly looked like a job for a full graph orchestrator. It was scoped, then set aside: with the queue runner already in place, a retried run replays for about $0.50 once agent calls are cached. That is cheaper than rewriting the tool loop as a graph. The deletion test was the deciding argument: remove the orchestrator and nothing about the current design breaks. It stays on the shelf until replay cost is the actual bottleneck, not before.
The three agents
Agent John, the Instruction Agent, and the Development Agent each have their own page: system prompt, tools, and model.