Skip to content
Rezha Julio

ai

I Refuse to Let the Loop Ship My Code

5 min read

Armin Ronacher's 'The Coming Loop' describes a future where harnesses decide when code is done. I'm keeping the human at the approval gate, using plannotator.ai to review agent output before it ships.

Armin Ronacher published “The Coming Loop” on his blog (lucumr.pocoo.org) on June 23, 2026. It hit the Hacker News front page the same day, which tracks: as the creator of Flask and a long-time voice in the Python and Rust worlds, his take on AI coding tools carries weight. Reading it made me uncomfortable in a way I recognized. He describes a pattern that is now everywhere: work goes into a queue, a machine picks it up, attempts it, stops, and a harness decides whether that was actually the end. If not, the loop keeps going. The task stays alive longer than the model would have let it on its own.

Armin is honest about his own discomfort. He argues that, at least for his taste, hands-off harnesses like Claude Code with ultracode or Fable produce worse code than what was produced in the autumn of 2025. The model adds a local defense for every local failure. It avoids strong invariants. It papers over unclear design with more machinery. Put that behavior behind a loop and you amplify it. Each pass adds another small guardrail until the system looks robust but no longer makes sense.

I read that and thought, yes, exactly.

The loop he means is not the agent loop we already live with. Every coding agent has a loop inside it: the model calls a tool, reads a file, edits it, runs a test, produces an answer. That loop is fine. The one Armin worries about is the harness loop, the one outside the agent. The machine decides when the work is done, then hands the “done” signal to another machine that judges it. Your role shrinks to messenger.

I don’t want that role. Not for code I care about.

Here is the part I keep returning to. Armin points out that models are, in Andrej Karpathy’s words, “mortally terrified of exceptions.” They see a failure and add a handler instead of making the bad state impossible. The right fix for malformed input is often to make malformed input unrepresentable. But the model will still write the error handler for the case that can no longer happen. Across thirty minutes of uninterrupted harness work, that compounds. You end up with code that is defensive in all the wrong places and clear in none of them.

Note

My rule: no hands-off loops. If a machine writes the code, a human reads it before it ships. That human is me.

This is where plannotator.ai comes in. I have been using the free, open-source tool developed by the backnotprop GitHub organization to review agent output, and it fits the way I want to work. I run most of my agent work through Pi (pi.dev), and Plannotator plugs into it directly. Two features matter to me.

The first is plan review. I run /plannotator-annotate on the agent’s proposed plan, which opens it in a review surface before it starts implementing. I select a section, mark it for deletion, write a comment, or draft a replacement. Approve and the agent proceeds; deny and my annotations go back as structured feedback. The agent revises, and a plan diff shows me what changed.

The second is code review. After the agent finishes, I run /plannotator-review. That starts a local Bun server, captures git diff HEAD, and opens a diff viewer with a file tree, split or unified views, and line-level annotations. When I send feedback, Plannotator formats my notes into structured markdown and drops it straight back into the session. Same workflow I use for a teammate’s pull request, except the patch never leaves my machine.

Both features run locally. Plans never leave the machine. Sharing, when I want it, is an encrypted URL where the data lives in the link itself. That matters because the whole point is that I stay in control of the spec.

What I like about this setup is that it pushes back against the exact failure mode Armin describes. The harness loop decides completion on its own signal. Plannotator makes completion depend on a human reading the diff. The model can still suggest the defensive handler. I get to delete it. The agent can still propose three new abstractions. I get to tell it to use one.

Armin is right that opting out may not be fully possible. Attackers loop. Security researchers loop. In his June 15, 2026 post, “curl’s summer of bliss”, Daniel Stenberg detailed how curl maintainers were overwhelmed by a wave of AI-generated reports. If the other side runs machines continuously, defenders eventually need machines too. My own stance is a response to this: while I cannot stop the industry from moving toward loops, I refuse to let them run completely unsupervised. I am keeping the human at the approval gate for any code that has a long shelf life or touches something load-bearing.

There is a line in the post I can’t shake. Armin says codebases are turning into organisms that can only be diagnosed by more machines. Useful and messy at the same time. I don’t want to build that. When I merge code, I want to explain what it does without first asking a machine to explain it to me. Plannotator helps me keep that ability, because I have read every line before it lands.

I will probably use loops for the boring parts: porting, benchmarking, anything that is a mechanical transform with no shelf life. Armin uses them for that and gets good results. But for the code that stays, the code other people depend on, I keep the human in the loop.

The loop is coming. Fine. I just refuse to let it ship without me.


Related Posts


Previous Post
Giving pi a Memory: Wiring claude-mem Into the Coding Agent