
Don't Review Your Agent at the End
Published: November 8, 2026
You have probably been there. You hand a task to the agent, and while it works, you grab a coffee or pick up another ticket. When you come back, there is a 1,400-line diff waiting for you across thirty files, the tests are green, and the PR description sounds quite convincing. So you do what everyone does: you scroll for a while, look for something familiar, and then, because what else are you going to do, you approve it.
Most agentic trends today point in this direction. Longer autonomous runs, agents working in parallel, background tasks, and as little human involvement as possible. It looks impressive in demos, but it doesn't remove the burden of review. It just piles all of it up in one place, at the very end of the process. That is exactly where you have the least context about what happened and why, and where the temptation to just hit approve is strongest.
So I wrote a skill that deliberately goes the other way. It's called baby-steps, and the idea is simple: the agent proposes one tiny step at a time, explains why that step, and doesn't touch the code until you approve it. Slower? Yes. That's the whole point.
Review doesn't scale with diff size
You can still read a 50-line change properly, line by line, and think about whether it's right while you do. With 1,400 lines that no longer works, and honestly, nobody does it. Past a certain size, review quietly switches from reading to pattern matching: you stop asking whether the code is correct and only check whether it looks familiar.
A big diff also loses the order of things. You can't see which decision followed from which, why that helper was born, or why that if ended up exactly there. The agent knew all of this along the way, since it made those decisions, but the final diff keeps only the result, not the reasoning.
The third problem is the most expensive one. If the agent went in the wrong direction at step three, the remaining twenty-seven steps build on top of it, stacking up and pouring more concrete over the mistake. By the time you notice at the end, there is nothing left to fix. You throw the whole thing away.
One step, one file, one reason
baby-steps turns these three problems around, but there is one thing it deliberately doesn't do: it doesn't plan. I have two other skills for that. clarify is a question-and-answer session where the agent asks one question at a time until we reach a shared understanding of what exactly the problem is and what is out of scope. If the task is still too big after that, vertical-slice breaks it into vertical slices: pieces that cut through the whole stack, from UI to data, and can be demoed on their own. So baby-steps doesn't coordinate one giant task. After the task breakdown, it implements a single slice.
Roughly, this is how the skills fit together:
Even within that slice, you don't get a step list up front, only the next step. The agent tells you what it changes, why now and why this way, then shows the full diff in the chat, with no ... and no "rest unchanged". At that point, not a single file has changed on disk.
A step touches exactly one file and usually stays around twenty lines: a new function, the skeleton of an endpoint, a new if branch. If a logical change spans several files, say a new function and its import, that becomes two consecutive steps. And if the diff is too long to show in full in the chat, the skill doesn't treat that as a display problem. It's a sign that the step is too big and needs to be split.
After each step you have four options. You approve it, request changes, reject it because the direction is wrong, or allow bigger steps, but only for the current part, say a test group or a single endpoint. Once approved, the agent applies exactly what it showed, runs the narrowest relevant test or build, and briefly reports the result. It will never commit on its own, though. A commit is a separate step with its own approval.
In the chat, a step looks something like this:
**Next step:** Add `parseDuration`, which turns input like "1h30m" into minutes.
**Why:** The endpoint needs minutes, and the test written in the previous step, still red, pins exactly this behavior. Parsing goes into a pure helper so it stays testable on its own.
**File:** `src/duration.ts`
```diff
+export function parseDuration(input: string): number {
+ const m = /^(?:(\d+)h)?(?:(\d+)m)?$/.exec(input);
+ if (!m) throw new Error(`Invalid duration: ${input}`);
+ return Number(m[1] ?? 0) * 60 + Number(m[2] ?? 0);
+}
```
Approve, request changes, reject, or allow a bigger step for this part?
Four lines, so you actually read them, and if you pay attention, you notice that the regex also matches an empty string, so parseDuration("") quietly returns zero instead of throwing. You simply request changes, and the next step becomes a test for that edge case. In a 1,400-line diff, those four lines would almost certainly slip past you.
At first this may sound like plain manual approval, which most coding agents support out of the box: before every file edit, they stop and ask whether they may proceed. The two serve very different purposes, though. Manual approval is a safety brake. It slows the agent down and keeps it from doing things you don't want, but it says nothing about what the change is for. You get a file name and a diff, and the decisions behind it, why this, why now and what comes next, are left for you to reverse-engineer. Nothing limits the size of a step either, so a single approval can hide three hundred lines. In baby-steps, the approval is only the end of a step. The weight is on the reasoning that comes before it, and on keeping the change small enough that you actually understand it. You're not braking the agent here. You're keeping your own understanding in step with it.
Slower, but the slowness is the review
At first it's annoying, of course. Nodding through something twenty lines at a time, when the agent could write it all in one go in a minute, feels like rewinding the whole agentic progress. But with a big diff you don't save the review time either. You just push it to the end of the process, where you either do it badly or not at all.
With tiny steps, all three earlier problems go away. You actually read a twenty-line diff, because it fits in your head, so review stays reading and doesn't slide into pattern matching. The reasoning doesn't get lost either, since every step comes with its why, right at the moment the decision is made, not reconstructed after the fact. And a wrong direction gets stopped where it starts: if step three is wrong, you reject a twenty-line proposal instead of throwing away a PR that touches thirty files.
There is a less visible effect too: you stay in the loop the whole time. At the end of the slice you don't have to make sense of unfamiliar code, because you know exactly what went where and why, having been there for every decision. And if a part is genuinely boring, like a generated file or a row of near-identical test cases, there's the bigger-step option, but only for that one part.
The fast path isn't cheap either
There is one more angle that gets mentioned less often: cost. If a bad decision slips in early in an autonomous run, the agent doesn't stop. It carries it through consistently, using the same wrong abstraction in the next ten files, writing the tests against it, and shaping the error handling around it. Often you don't even throw the whole thing away, because too much of it is usable, but you have to fix every place the mistake reached. That's token cost again. You paid once while it wrote the wrong direction, then again while it goes around fixing it, and since every fix means re-reading the affected files, the context keeps growing along the way.
With tiny steps, this double cost never comes up. The bad decision stays in a single proposal that nothing has been built on yet, so rejecting it costs almost nothing.
When you don't need it
Not every task needs this pace. For a throwaway prototype or a quick spike, where the code ends up in the bin anyway, reading every twenty lines is pointless, so let the agent run on its own. baby-steps pays off most where the code stays: in production code, in a module you'll have to maintain later, or anywhere a bad decision will still come back to haunt you months from now.
Agent speed on its own isn't the problem. It becomes one when review can't keep up, and all that's left of it at the end is pressing a button. With baby-steps, the approve button is still in the same place. You just know what you're pressing it for every time.
