I’ve barely written a line of code by hand in months. Neither has a lot of the industry, which seems to have decided that means the old rules don’t apply any more. Massive diffs are fine now, apparently. Some of the popular planning skills will happily generate a plan running to thousands of lines and then plough straight through it like it’s gospel, nobody having read it and with no checkpoint for a human to even pretend they’re still driving.

That’s not a new way of working. That’s just slop.

The rules didn’t change for me. The quality bar for what ships hasn’t moved — that’s the part that matters. What has changed is how much of the manual labour I still do myself.

Over the last few months I’ve been iterating daily on a single-file command and a companion agent that encodes the workflow I used to follow when it was just me. The speed of AI without the slop.

The unit of work hasn’t changed

Before AI wrote any code, it was well understood that a large PR was a bad PR. To be a good PR, it had to be reviewable, and to be reviewable it needed to be small enough to keep in your head. It had to be a coherent slice of behaviour, not a pile of unrelated edits, and definitely not three months of work lumped into one commit. That was the unit of work. That should never have changed.

We’ve all seen the memes on r/ProgrammerHumor: nobody reads a 5,000-line diff. We used to joke about interns doing it. Now we let agents do it, clap them on the back, and shove it into production.

LGTM

I, at least, don’t. I don’t type the code any more, but that only means I review it harder. It’s still my name on the PR, and I can explain any of it as if I had written it. Before I submit I make sure I can understand what it does and why, and if it doesn’t meet my quality bar I don’t submit it — I go back and say what needs to change until it does.

If I don't like it, I don't submit it

What I used to do

First, context. Read the ticket, look at the designs, poke around the codebase. Ask the same few questions: what am I building and why; what classes are involved; what existing patterns am I going to mirror; what’s the shape of the change I’m going to make. Work out the commits that get me there.

Then the manual labour. Typing time. If something came up mid-way that I hadn’t accounted for, I’d stop and ask myself whether the shape of the work had changed, rather than just ploughing on regardless.

Then review. Open a draft PR and read it as if I’d never seen it before, the way a peer would — anything I think someone would flag, I fix before it’s ever a comment.

That’s the process, and it’s not novel. It’s just how one person builds something properly. What I’ve spent the last few months doing is encoding it into a command, development-pipeline, and a companion agent, Arwen, who does the actual manual labour now — plus a lot of the codebase archaeology I used to do by hand.

Context, then a plan

The first step mirrors what I used to do alone — read the ticket, the designs, the code — except I’m not the only one doing the reading any more. I ask, and the coordinator — the main conversation — goes and finds it: which files, which existing pattern to mirror, what’s already been decided elsewhere in the codebase; anything I would have gone looking for myself.

Then a plan. Common off-the-shelf planning skills write this down as a document, usually thousands of lines of dense prose and half-related code fragments. Mine doesn’t produce a file at all. It happens right there in the conversation. When the plan’s ready it’s echoed back to me — usually not much more than a page of my terminal. I can actually read the whole thing. I can hold it in my head. So I can push back — on a step, a decision, a consequence — and if I do, it gets refreshed and echoed back again, until I’m happy with it.

Once I’ve agreed the plan, it gets one thing I never had working alone: a peer review of it, before a single line of implementation exists. It goes to Arwen for a completely separate pass — not implementing anything, not reviewing a diff, just reading the plan cold and trying to find a reason it’s wrong. The same thing you could get from a design review with your principal engineer or by producing an RFC for your team, except I can get it in minutes instead of waiting days for feedback or a meeting.

It’s no substitute for a real design review; but that’s not the point. Previously, if the plan was wrong I’d find out three hours into typing, if I was lucky. In review, or after it had gone into production, if I wasn’t. Now it’s the rubber duck that talks back.

Mostly it’s little things that would have been handled during implementation anyway. Sometimes it’s wrong, or paranoid, or raising something that doesn’t apply here — it is still just a duck. Which is why this isn’t “fix everything in the plan and go ahead”. It’s a genuine review: it comes back to me. And every so often it catches something worth catching — an edge case I hadn’t thought about, a security principle broken, a pattern or piece of documentation it would invalidate. Then we talk it through while changing the plan is still cheap.

Coding

Once the plan’s agreed, I delegate the typing. Arwen builds it step by step, commit by commit, as agreed. I go and do something else.

Unless the plan turns out to be wrong. If something comes up that the plan didn’t anticipate — a wrong assumption, an edge case nobody saw, a constraint that changes what the next step should do — Arwen stops, rather than improvising around it or quietly hoping I don’t notice, and hands it back to the coordinator, which brings it to me. Maybe it’s fine, maybe it’s a total re-think.

That decision is mine to make.

That structure and hand-off took a couple of attempts to get right — it’s clearly not how these models want to act. I’ve seen other prebuilt planning skills, and an earlier version of my own, get it very wrong.

An early version ran the whole thing as a background workflow — hand it off, let it go, come back when it’s done. Sounds good, right? No. A workflow running unsupervised will happily drift from the agreed design and hand you a fait accompli an hour later, when untangling it costs far more than steering it would have.

Another version let the coordinator attempt to fix things directly rather than routing them through Arwen. That might sound efficient but it’s not. The coordinator holds all the conversational context, and letting it touch code and run tests meant it almost immediately entered the dumb zone. It forgot decisions we’d made, forgot rules laid out in the AGENTS.md/CLAUDE.md, needed compacting more than once, and eventually pushed me into writing code by hand again (what year is this!?).

Now entering the dumb zone

Neither of those is how it works now. Every step is a separate call the coordinator makes, one at a time. It reads Arwen’s report before deciding what happens next, and brings it to me if it needs to. A fresh instance of Arwen handles each step and hands back the result — not the noisy steps it took to get there.

Review

The last step was always review. That part hasn’t changed. What’s new is that I’m not the first reviewer any more.

Before any of this becomes a PR for me and my colleagues to read, Arwen reviews it — ruthlessly. The whole diff against the base branch, plus a summary of the conversation: what we’re building, why, and which decisions we made along the way. Real problems get fixed the same way they’d have been built: one commit at a time.

That didn’t work first time either. Early on, I let the coordinator loop between review and implementation until review said it was perfect. It never converged. Arwen always found something — given the chance, a model will always find something rather than say nothing. A couple of iterations settled it: the reviewer is told not to raise nits for the sake of it, and the coordinator judges whether what’s left is nitty anyway and ignores it if so.

The coordinator when Arwen leaves a nitty review: I have elected to ignore it

Anything significant is brought to me and planned the same way as the first round. Occasionally that’s a substantial conversation. Usually it’s a couple of commits of minor improvements that I wave through.

By the time it reaches me, most of what a first-time reviewer would have flagged has already been caught — the same benefit as the plan review, just later. Then it’s my turn. The command’s final step is to draft a PR, ready for me to read it the way I always have — as if I’d never seen it before. Except now I actually haven’t seen the code before. My review is fresh and, since it’s “my code”, brutal and honest. If we have to go back to the drawing board we will — but that rarely happens. We did a lot of that thinking up front.

What I get out of it

A PR I can stand behind, even though I didn’t type it. Not just the decisions — the style, the architecture, every line of it. I can explain any part of it the same way I’d explain code I wrote myself, because by the time it reaches me I’ve read it, pushed back on it, and made it match what I’d have built by hand if I’d had the time. It reads like mine. It just isn’t.

And a conversation that’s still sharp enough to use. The whole plan — every decision, every reason we made it — is still sitting right there, but none of the noise that built it is. So when I look at the eventual PR and don’t like something, I say what’s wrong, in the same conversation that already knows what’s going on, and it gets fixed. No poking a tired conversation into making it worse, no starting again with a fresh one that’s forgotten the last few hours.

None of that is slower. I ship more than I used to, because the part that never needed my judgement doesn’t wait for me any more.

Most of all, the calls stay mine. A model can tell you what’s right on average. It can’t tell you what’s right for this codebase, this week, with these constraints — your project isn’t average. That judgement is the one thing this workflow never routes around, and it’s why nothing here runs off on its own: a workflow left to make the calls makes an average call, every time.