I let an agent pull its own tickets from Linear and drive them to Done. One command: /implement
Let me disarm that right away. This is not an autonomous agent doing whatever it wants. It is a fairly narrow pipe with several points where it stops and waits for me. Yes, I know this will be done better later. But right now this is the most conservative version I can run, and more importantly, the version I can explain to someone else.
The project is Luštírna, a gamification POC for an ecosystem of thirteen sites: daily games, a credit wallet, a three-way paywall. Around forty tasks, milestones M1 to M6, one developer, a second person feeding the backlog. What follows is how the loop is wired, because almost none of the interesting decisions in it are about models. They are about where you put the gates.
How you start it
Two modes.
/implement is a single pass. It takes the queue and goes task by task for as long as there is something unblocked left in Linear, then summarizes what is waiting and why. This is just an init prompt. I did not want to retype the same three paragraphs every morning.
/loop 45m /implement is the long run. Same thing, except it does not shut down when the queue empties. Every 45 minutes it wakes up, orients itself (git status, Linear, the check gate, beta health) and picks work back up as soon as anything unblocks: a merged PR, a new task, a changed priority. Thirty to sixty minutes is fine as an interval. Shorter does not help, because the thing doing the unblocking is a human.
Both are typed into a fresh context. Everything that has to survive lives in the repo (docs/progress.md) and in Linear, never in the conversation. That sounds like a style preference. It is not, and there is a story at the end of this post about what happens when you ignore it.
The main session writes no code
This is the part that changed the most since the first version.
The orchestrator session does not write a single line of production code. It writes a brief, spawns an agent, waits for the result. The working context lives inside those agents, the main thread stays free for steering: Linear, the gates, the decisions.
One iteration is one task taken to Done, and the steps are always the same: orient, pick a task, design, implement, verify, review, deploy, close.
Step zero is the underrated one. Context does not survive between iterations, the repo does. So every iteration starts identically: git state, recent commits, read docs/progress.md, reload conventions, run the check gate. If something is red before any work has started, that is the first job, because the previous iteration left a mess. Skip this ritual and after a few hours the loop is building on foundations it does not know are crooked.
Who does what
| Model | Role |
|---|---|
| Fable | Orchestrates. Writes the design and brief for every task, then runs the review workflow over the diff once verification is green. Also handles diagnosis when a fix fails twice. |
| Opus | Writes all production code and fixes findings. Always as a spawned agent with its own brief, never the main context. |
| Sonnet | Clicks through the acceptance criteria in a browser, writes a report with screenshots. |
| Codex / Cursor | Independent review at the end of a loop, deliberately outside the Claude family. Cursor is wired in through my plugin: cursor-plugin-cc |
Two rules hold this together. Writing code is never delegated to a smaller model. And the agent that tests never fixes what it tested, otherwise it is grading its own homework.
The Fable allocation is worth a note. The original design used the strongest model at three expert moments and one big review at the end of the phase. That ended on August 8. Review in one large batch catches less than continuous review of small changes, and by the time you audit six months of code at once, half the findings are too expensive to act on. Fable now writes the brief for every task and reviews every diff. Routine code stays with Opus agents, because in routine code the gap between models is small, while in design it is enormous. An append only ledger does not get rewritten after a month in production. You live with it.
The verifier must not see the code
This is the single most important rule in the loop.
The test agent gets the acceptance criteria and a URL. It does not get the diff, the plan, or any implementation reasoning. The reason is simple: a verifier that knows how the thing is written stops testing the requirement and starts confirming the code.
The quiet failure mode of agentic development is not bad code. It is tests written to pass. The agent runs the code, sees the output, and records it as the expectation. That test will never catch the bug it was written for.
So the verifier owes three things beyond the happy path.
Nasty cases, not just the sunny one: repeat a scored action and confirm the second credit was not granted, spoof a client side value and expect the server to reject it, search the page, the bundles and the network responses for today's puzzle solution and seed.
Evidence instead of conclusions: the report is criterion by criterion, pass or fail, each with a screenshot, a URL, a commit SHA and a console error count. A conclusion without an artifact does not count.
And no fixes. Whoever tests does not repair.
Gates the loop cannot rewrite
An agent that can edit its own checks has no checks. It sounds obvious. It was not in the first version, and the loop was allowed to touch anything.
The perimeter now:
- CI config, deploy files, Dockerfile, env files and anything on the server change only with human confirmation. Confirmation given in the conversation counts immediately and gets recorded in a task comment.
- Merges go through a pull request, never a direct push.
- Tests are never deleted, skipped or softened to get green. A red test is a finding, not an obstacle.
- Four domains (login, credit ledger, migrations, paywall) get implemented by the loop but merged by a human.
- Migrations in a release may only add. Dropping and renaming columns waits for a later release, otherwise rollback stops working.
The cheapest rule of the set is also the most effective: whatever slipped through gets a check. Every bug that made it as far as verification is converted into a test or a lint rule in the same iteration. A rule written in a conventions file holds only until the context fills up. A check holds always.
The thing you only find by accident
There are gaps in all of this, and some of them you find sideways.
I thought my router had died. Latency in the hundreds of milliseconds, identical over cable and over Wi-Fi. Ping to my own router: 1 ms, zero loss. Ping one hop past it: 363 ms average, spikes over a second.
It had not died. It was the orchestrator session of this loop, which had been running for 2 days and 17 hours in a single context.
What confused me first was that it should have been compacting. Then I found the issue on GitHub. Claude Code resends the entire conversation on every turn, every message and every tool output. Prompt cache saves compute on the server, not bytes on the wire. Upload volume scales with the size of the live context, not with the length of what you just typed. A fifty character question can ship half a megabyte.
There is no built in network usage indicator, so a session strangling your uplink looks exactly like a session doing nothing. Low minimum latency with a huge spread is the signature of bufferbloat: a saturated outbound queue on the router, paid for by every device on the network, including the ones on cable. Which is exactly why it presents as dead hardware.
I wrote a plugin for it: a statusline with an estimated upload per turn, a hook that warns as a session grows, and a scan that shows which running session is currently eating the link. context-guard
So the fresh context rule turns out not to be context hygiene. It is also a network rule. 😅
What I would tell someone wiring this up
The bottleneck moves. It does not disappear. You stop writing code and you start reading diffs and saying yes or no, and the throughput of the whole thing is set by how good your verification is, not by how good your model is. Everything else is downstream of that.
The payoff is unattended flow: you wake up to a deployed task with evidence attached to each acceptance criterion. Not the feeling of going faster. That feeling, in my experience, lies.
Top comments (1)
One hell of a learning gems hidden in the text, I ll await the second hell to come in the next one