AI Won't Delete Your Code. That's Your Job.
Why your job just shifted from writing code to deleting it.
I used to be a nice code reviewer.
I read lots of books about not being a micromanaging asshole. Don’t over nitpick and really just trust your team.
This is great advice for humans.
Terrible advice for AI.
I’ve spent years softening my opinions, letting things slide in PRs, being more of a collaborative engineer.
However, now that I’m generating 95%+ of my code. my codebase can quickly turn into garbage.
The reason being there’s too much code.
PS: This newsletter grows from your shares. Sharing is free & helps me stay laser focused on making content for you.
AI only knows how to add.
Ask it to fix a bug and watch what happens. It’ll add a bunch of guard clauses, or write a path beside the old one, marking the original as “legacy”.
That “legacy” code was never released, though.
It almost never says “delete this.” Why would it? It’s pattern matching. It genuinely cannot tell the difference between tech debt and value because that requires knowing what the code is for. It doesn’t completely know that.
So, it always does the safe thing: it adds.
The 20 case switch problem that should have been zero.
I had a generic type in a codebase that could resolve to any of 20 specific types. AI needed to write a function that should only ever receive one of the specific types.
It always reached for the generic type, then wrote a 20-case switch statement to handle every possibility.
It was very hard to catch, but the function needed zero branching. It just needed to use the one specific type.
I didn’t catch it straight away because it looked right. I caught it a week later when I went to refactor. The whole thing refactored into something simple, clean, and obvious.
I personally think this happens because LLMs are trained on open source code, and open source code is full of generic defensive “handle every single case” patterns.
Addition compounds
Every fix that adds instead of deleting makes the next fix harder to do.
Six months later, you’re maintaining a mess.
Our jobs have completely changed. We used to be paid for writing code.
Now we are paid for deleting it.
The structure that makes AI’s mess visible
Here’s what I actually do.
It’s opinionated (to me).
One function per file.
Lots of files.
Lots of folders.
Back-end follows predictable service and controller patterns.
Front-end easily organised by features.
This is about readability.
When AI works in a codebase structured like this, every change is easily visible. It deletes a function, and a whole file disappears in the same diff.
If it adds something, there’s a whole new file, and I can immediately see it. I can read the shape of the change before reading a single item of code.
This brings me to the scariest bug I’ve had this year.
100,000 candidates and two monolithic files
At work, we had a feature that was originally tested with 50 candidates. Then a big client needed to handle 100,000.
A document bug came up. Customer Support flagged the issue, and then AI went to fix it.
It worked.
Then I looked at the diff, and every single change was inside two enormous files.
I sat there staring and thinking, “Did this only touch the document logic?”.
Is it possible it accidentally changed something a hundred lines down?
I just wasn’t confident.
So I restructured, pulled everything apart into proper files, and ran the fix again.
My anxiety disappeared immediately.
Now, when AI edits something, I can see exactly what’s touched.
That feeling and confidence is worth the refactor.
I’ve trained junior engineers. AI is the same job.
When I was a CTO at Cub, I trained a lot of junior engineers. The pattern was always similar.
The functionality was fine; they’d solve the problem, but the PR would come up with everything in the wrong place, structured in a way that wouldn’t survive the future.
I’d send it back saying, “Move this here, split that out, and this won’t scale. Let’s have a talk.”
That is exactly how I review AI code now.
Generate something, review it like a real PR. The functionality is always the easiest part. What I’m actually looking at is whether the next person can work on this codebase without drowning.
I stopped doing this for a while because when I joined Popp, I let go of that opinionated CTO energy. I had it at Cub. I read a lot about trusting your team and not sweating the small stuff, especially when you’re working with senior engineers.
Then my CTO said something that made me think: everyone needs to be way more opinionated and take way more ownership.
He was talking about the engineering team, but this clicked for me with everything to do with AI coding.
Be the asshole
I’m completely serious.
With humans, nitpicking every PR is bad leadership. Micromanaging every single file name is exhausting for both sides. Blocking a merge because you don’t like a little thing makes you the person that’s hard to work with.
With AI? That’s every day.
Model has no opinions of its own. If you don’t bring yours, then nobody will. You’ll end up with average open-source code with terrible to average architecture, generic types everywhere, a codebase that grows but will never get better.
Be an opinionated engineer. Be the one who sends back everything and says, “No, change this, restructure this. No, that’s not good enough.”
Be the person who cares about:
file names
folder patterns
where types live
future refactoring
AI has made me pick that back up after years of letting it go.
My code and confidence are better than ever.
Stop reviewing AI code for whether it just works
It usually does work. Given a good AI model and harness.
Start reviewing it for what it added that shouldn’t exist.
Then delete things. Refactor them.
That’s the job now: pruning.
If this hit home, share it. This newsletter grows because you send it to people who need it.
It costs nothing to share, and sharing is caring.
If someone sent you this, then please subscribe here for free:




