Harness Engineering · Part 2 of 3
Wrong Every Time, Right in the End
What an agent loop is, and why repeating a flawed process converges on a correct one
If you have used an AI coding assistant you know the shape of the disappointment. You describe what you want, it produces something impressively close, and then you spend the rest of the afternoon discovering the six ways it isn’t right.
The obvious response is to try to make the AI better at getting it right the first time. Better prompts, better models, more context loaded up front. That is where most people put their effort, and it is where I put mine for a long while too. But the approach that actually started working for me is different, and the reason it works turns out to be more interesting than the technique itself.
The approach is: stop trying to get it right. Run it again. And again. Hundreds of times.
I know how that sounds, like a joke or like giving up. It isn’t. Under specific conditions, and the conditions are the whole story, a process made of unreliable steps produces a reliable result. Not by accident, and not eventually-if-you’re-lucky, but reliably and for reasons you can point at.
The thing that is hard to believe
Repetition improving a flawed process is genuinely counterintuitive, so it is worth being clear about why. If a machine gets something 80% right and you run it again, why wouldn’t you just get a different 80%? Run it a thousand times and you would expect a thousand different mediocre answers, not one good one. Anyone who has asked a chatbot the same question twice knows repetition alone doesn’t create quality.
That intuition is correct. Repetition alone does nothing. But add one ingredient, a way for the process to check itself against something, and repetition stops being repetition. It becomes correction. And correction applied over and over is one of the most powerful things we know how to build.
We already trust this pattern everywhere. Your thermostat is never at the right temperature; it is always slightly too hot or slightly too cold, correcting. The room feels comfortable not because the thermostat is accurate but because it is relentlessly wrong in decreasing amounts. Sanding a table works the same way: no single stroke makes wood smooth, each one removes a bit of material in a slightly wrong direction, but the high spots get hit more than the low spots. Smoothness isn’t in any stroke, it emerges from thousands of them. And your GPS doesn’t plan a perfect route and hope. It recalculates continuously, and it doesn’t care at all that you missed the exit.
None of these systems is accurate. All of them are correct. Sit with that distinction for a sec, because it is the entire subject.
The ball and the bowl
Here is the picture I keep coming back to. Drop a marble into a bowl. It doesn’t matter where: the rim, the side, anywhere. It rattles around and ends up at the bottom. Drop it a thousand times from a thousand places and you get the same result every time.
The marble has no idea where the bottom is. It has no plan, no map, no strategy. It is just responding to the shape it is in. The intelligence is in the bowl, not the marble.
That is the whole architecture. The AI agent is the marble: fast, capable, and unreliable in any given moment. It bounces off in odd directions, sometimes it even goes up the side. That is fine, expected even. What matters is that the shape it is operating in has a bottom, and that every bounce on average gets it a little closer.
My job stopped being “make the marble smarter.” It became “build a better bowl.” That reframe is doing more work than it sounds like. Almost every hard problem in this space turns out to be a bowl problem, and the metaphor is precise enough to diagnose all of them.
Three things a bowl needs
Readers of The Future Loops will recognize the three pillars here in bowl form: the bottom is the back pressure, the fixed shape is the canon firewall, and the steep sides are context management.
A bottom. There has to be a definition of done that the system can measure itself against. Not a description of what you want in prose, but something checkable: tests, specifications, invariants, constraints. Something that can say no.
This is the one people skip, and skipping it is fatal in a specific way. Without a checkable target you don’t have a shallow bowl, you have a flat table. The marble rolls forever and never settles, and from the outside this looks remarkably like progress: constant motion, plausible commits, endless activity, no convergence. I burned a lot of time and money on flat tables before I understood what I was looking at.
A shape the marble can’t change. This is the one I got wrong the longest, and it is the most important. If the agent that writes the code can also edit the definition of correct, it will. Not maliciously, helpfully! It will notice a mismatch between the spec and the code and resolve it, and resolving it by adjusting the spec is easier and looks completely reasonable in isolation.
What you get is a marble that flattens the bowl wherever it happens to be sitting, then reports it has reached the bottom. Every test passes, the spec and the code agree perfectly, and it means nothing, because the agreement was achieved from the wrong end. So I keep them physically separate. One process establishes what correct means, and a different process with different permissions builds toward it and is never allowed to touch it. The easiest way to hit a target is to move it, and the only real defense is making that impossible rather than discouraged.
Sides steeper than the wobble. Every bounce has some randomness in it. For the marble to settle, the pull toward the bottom has to be stronger than the noise, otherwise it just jitters around forever, technically in a bowl, practically going nowhere.
In practice the noise comes from a place people don’t expect: how much the agent is holding in its head. These systems have a working memory, and quality degrades noticeably as it fills, the same way your judgment degrades in hour three of a meeting. An agent working from a clean, curated, deliberately small view of the problem makes edits that are mostly signal. An agent drowning in a giant pile of context makes edits that are mostly noise. Same model, same task, completely different behavior.
So the loop deliberately forgets. Every iteration starts fresh: pick the single most important next thing, do only that, throw everything away, start clean. The agent never accumulates a long confused history because it never accumulates a history at all. Forgetting is a feature! It is the least intuitive part of the design and one of the most important. Continuity of memory is what we prize in a human collaborator, but here it is a liability, because a fresh start can’t be confused about work that is already done. It just looks at what is actually there.
What falls out of this
Once the bowl is shaped right, a few things become true that feel genuinely strange coming from normal software practice.
Starting badly costs nothing. Where you drop the marble doesn’t change where it ends up. The first pass can be a disaster and it makes no difference to the final product, it just takes slightly longer. I stopped reviewing early output entirely. It is noise, and treating it as signal was making me miserable.
Mistakes undo themselves. If an iteration does something wrong, the next one is looking at a fresh picture of reality that now includes the damage, and it fixes it. The system doesn’t need to know a mistake was made or who made it. The bowl doesn’t remember how the marble got there, only where it is. Self-healing isn’t a feature I built, it is just what a bowl does.
You stop caring about any individual output. This was the biggest personal adjustment. The unit of quality is no longer a commit or a file or a response, it is the trajectory. Asking whether one iteration was good is like asking whether one sanding stroke made the table smooth. Wrong question, wrong scale.
The work moves. I spend almost no time now on what I would have called programming. I spend it on defining what correct means, precisely enough to be checkable, and on shaping the process that converges toward it. The thinking is the same or harder. It just happens one level up.
Where the bowl fails
I would rather you hear the limits from me than discover them at 2am, and the nice thing about the metaphor is that it predicts every failure mode.
Flat-bottomed bowls. If the bottom of the bowl is a wide flat plain, the marble settles somewhere down there, but not any particular place. This is what happens when your definition of correct is incomplete. Everything you specified is satisfied, everything you didn’t specify is arbitrary, and it will drift, and it will surprise you. The lesson here is the most important practical rule I know in this space: when the output is wrong but everything passes, the target was wrong, not the agent. The reflex is to blame the model and rewrite the prompt, and it is nearly always the wrong move. The system did exactly what you asked, and your ask was silent on the thing that broke.
Two dips. A bowl with a secondary depression will trap the marble in the shallow one. It has settled, it is stable, and it is in the wrong place, and no amount of additional bouncing will get it out, because every small movement makes things locally worse. This is what a wrong architecture looks like. The loop will cheerfully generate a hundred small improvements to something that should be deleted and rebuilt, and each one is a real improvement, and none of them help. Escaping requires a jump, a decision to demolish, and a system built entirely from small careful steps cannot make it. That decision is still mine.
Bowls with no bottom. If your requirements contradict each other there is nothing to converge to, and the marble oscillates between two positions forever. Worth knowing because the symptom is unmistakable once you have seen it, and because the fix is never “try harder.” It is “you asked for something impossible, go decide which thing you actually want.”
Bowls you can’t build at all. The whole approach depends on checking being cheaper than doing. That holds beautifully for a huge class of questions: does it compile, does it pass, does the output match. It collapses entirely for others. Is this the right abstraction? Will this scale? Is this the product people actually want? Verifying those is as hard as answering them, no loop will help, and pretending otherwise is how people end up with an enormous, well-tested, thoroughly wrong system.
What it is actually for
Nothing here is specific to code. The requirements are just a target you can check against, a way to generate attempts, and iteration cheap enough that being wrong repeatedly is affordable. Code satisfies all three unusually well, which is why this is happening there first, not because code is special.
But the shape generalizes to anything with a checkable target, and the constraint that bites is almost always the same one. It is not the AI. It is whether you can say what correct means in a form that can say no. That is a harder question than it sounds, and it is a human question. In most organizations nobody has ever had to answer it explicitly, because a person was quietly filling the gap with judgment. Take the person out of the inner loop and every place you were vague becomes a place the system wanders.
The part I didn’t expect
I went into this trying to build something that could write software without me. What I built instead is something that needs me for different work, and I think more interesting work. I no longer write much of the implementation. I define what correct means and defend it, I decide when the whole approach is wrong and needs to be thrown out, and I am the final judge of the things no test can check. The machine does the part that is mechanical, tirelessly, at a scale I could never match.
It is still wrong every single time. That stopped mattering to me the moment I understood it was never supposed to be right, just relentlessly, decreasingly wrong, in a bowl I built carefully enough to trust. My working motto has become: guess wildly, check strictly, forget completely.
The harness is open source at [repo link]. And if you want the version of this with the actual mathematics (it turns out to be a 1922 fixed-point theorem, and the three parts of the bowl are its three hypotheses) that is in the companion post: Fixed Point in a Dumb Loop.