Skip to main content

Command Palette

Search for a command to run...

I Deleted Every Document the AI Had Written

Updated
5 min readView as Markdown
I Deleted Every Document the AI Had Written

The first thing I did with the codebase I inherited was delete all of its documentation.

For a month I filled in for another team that was short-staffed. The code I took over had been fully delegated to AI — not just the implementation, but the judgment behind it. Every requirement was there. The tests passed. Deployments went out cleanly. From the outside nothing looked wrong, and the service was genuinely running. Strictly speaking, all it did was run.

Documents born without a question

The docs existed because someone had said "write documentation."

They looked the part. Overviews, structural explanations, tidy lists of items. What they didn't have was any sense of whose question they were answering. That was never decided — the documents were generated before anyone settled on what they were for.

Meanwhile the code kept changing and the documents didn't. Eventually the AI started reading those stale documents and editing the code to match them. At that point they were worse than nothing. So I deleted them.

To be clear, this isn't an argument against documentation. Anything that can be derived from the code will rot. What earns a place in a document is the thing code can never carry: why the decision was made.

The documentation wasn't the only problem

The next thing I noticed was API performance.

The cause didn't take long to find. Data that could have been read once and reused was being fetched fresh every single time it was needed. The same thing was happening in reverse: the service was diligently writing information nothing ever queried, data no screen ever displayed. Unnecessary IO had piled up on both the read and write paths, and it was eating the performance whole.

What matters here is that this doesn't read as a performance problem. Fetching the same data repeatedly means no part of the code knows that data is already in hand. Persisting data nobody reads means no one ever decided what that information was for. This is what you get when work is sliced into features, requested feature by feature, and stitched back together. Each fragment fetches whatever it needs and saves whatever it produces, because it has no idea what came before it or what comes after.

I read through the code and reorganized the IO paths. Nothing clever was required. Sketching out where data enters and where it flows was enough to make it all visible — it's just that nobody had ever looked at this code from that angle.

Code that is responsible for nothing

The same illness had a third symptom.

There was a lot of dead code — functions that had been superseded and never removed, scattered throughout, with comments sitting on top of them that no longer matched what the code did. Stale comments are the worst of it. A wrong comment is more harmful than no comment: it points the reader in the wrong direction, and the only way to discover it's wrong is to read all the code anyway.

More serious than that, the responsibilities of each module were unclear. Which concept belonged where, why a piece of logic lived in this file and not another — you couldn't tell from the code. Every fragment satisfied its requirement faithfully. What was missing were the boundaries that should have existed between them.

These problems all have the same shape

None of them ever turn a light green.

Tests don't tell you how many round trips produced a response. CI doesn't flag dead code. No pipeline asks "what is this module responsible for," and none asks "whose question does this document answer."

AI converges on conditions that can be verified. Put a checkbox in front of it and it will fill the box precisely. The trouble is everything without a checkbox. Questions nobody asks simply stay unasked — and accumulate as debt.

What I did after that

Deleting the documents mattered less than what came next. I restructured the internal architecture around the business concepts.

The point was to make the code itself say what the documentation should have said: what each concept is, and where its responsibility ends. Carve the boundaries into the structure and there's nothing left to rot, because the code is the answer. Only once those boundaries existed could anyone say where data enters once and how far it travels.

This part can't be handed to an AI. The boundaries of a business concept are drawn by someone who understands the domain — and more to the point, there is no automated signal anywhere that tells you when you've drawn them wrong.

The line

What you can delegate is implementation. Not judgment.

And the line between them isn't an abstract principle. It's one very concrete question.

When this decision turns out to be wrong, what turns red?

If nothing does, that decision belongs to a person. And that decision is the architect's decision.