# Nothing failed. That's why no one caught it.

> Source: <https://miralume.dev/the-architect/nothing-failed>
> Published: 2026-08-10 23:48:41+00:00

[← The Architect](/the-architect)

# Nothing failed. That's why no one caught it.

Generation got cheap, understanding got expensive, and nothing in your toolchain measures the expensive half.

An agent shipped a change last month. The tests were green. The diff was clean. Two reviewers approved it — one of them a bot, and honestly, so was the other, in every way that matters. The change merged and life went on.

Weeks later, something was wrong. Not broken, *wrong*. The kind of wrong that doesn't throw. A number came out slightly off in a report nobody reads closely until a customer does. When we traced it back, the change looks correct. Every line did exactly what it said. It was just built on an assumption nobody had made on purpose — an idea about how one part of the system related to another that was true 3 weeks ago but no longer is, and no line of code was responsible for knowing that, and the AI's context somehow missed it.

No alarm fired. There was nothing to fire on. Nothing failed. That's why no one caught it.

If you've shipped software with AI in the last two years, you've probably felt some version of this even if it never cost you a customer. A creeping sense that the code is fine but the *understanding* is thinning. That you're merging more and knowing less. This trend represents a is a systematic shift in software development, and it has a name.

## This isn't technical debt

We already have a word for bad code, and this isn't that. Technical debt is the messy function, the shortcut you took under deadline, the module everyone agrees needs a rewrite but no one dares to touch with a ten-foot pole. It's *visible*. You can see it, point at it, schedule the refactor. It's a debt precisely because you know you owe it.

The debt created by AI is quite the opposite. The code is clean and tested, all markers are green, and yet no one can tell say *why* it's shaped the way it is, what it assumes, or what breaks if you touch it. The messiness isn't in the source — it's in the gap between the source and anyone's understanding of it. The term of this is **cognitive debt.** The moment I read it, the feeling I'd been trying to put a name to for months finally made sense.

The code isn't the liability. The liability is the missing mental model.

Unlike technical debt, you can't see this one on a dashboard. There's no linter for "nobody understands this anymore."

## Why understanding was always the real asset

There's a 1985 essay by Peter Naur, *Programming as Theory Building*, that has aged into something close to prophecy. Naur's claim was that the real product of programming was never the text on disk, but rather a *theory* held in the minds of the people who built it — a living model of how the thing works, why it's arranged this way, what it's for. The source code is a lossy projection of that theory, a shadow.

His unsettling corollary: when the people who hold the theory leave, the theory dies, even though every line of code remains. You're left with a shadow and no object casting it. Anyone who has inherited a (badly || un)-documented codebase knows this feeling quite well.

For forty years, the theory and the text were built together, by the same hands, at the same time. Now we generate the shadow at superhuman speed while the object — the model, the theory, the understanding — never forms at all

## Cognitive debt is measurable

This analysis could be waved off as the nostalgia of the "hand-crafting programmers" if it weren't for the actual data backing it. Faros studied 22,000 developers this year: incidents per pull request up 243%, and 31% of PRs now merged with no review at all. Things fail more per change, and get looked at less.

The tell isn't the failure rate, though — it's that satisfaction stayed high the whole time. Everyone reports feeling faster and more productive while the floor quietly rots underneath. That's the trap: **satisfaction is a lagging indicator, and right now it's lying.** The feeling of velocity and the accumulation of cognitive debt are the same sensation viewed from two distances.

## Every tool you own measures the cheap half

When I'm writing my own code by hand, understanding rides along for free. You can't write the code without building at least a rough theory of it; you'd type and rethink and delete and rewrite and on and on.

Authorship and understanding are requirements to growing the codebase.

AI code generation severs that. The code arrives without the theory that used to come attached. And though you direct the intent, and can read the agent's thinking, it's not yours and you are therefore more likely to lose track of it in time.

Our current set of tools don't help with this. Continuous integration checks that the artifact runs, test overage checks that the artifact is exercised, and linters check that the artifact is tidy. Every one of them inspects the code, the cheap half. **The green checkmark tests the code. It was never able to test whether anyone still understands it.** We've built an entire quality apparatus around the one thing generation made abundant, and none of it around the thing generation made scarce.

## Three ways it fails silently

When cognitive debt comes due, it tends to arrive in one of three shapes, and a senior engineer will recognize all three:

**Incomplete context.** The change is locally correct but was made without knowing something that lived only in someone's head — a constraint, a history, a reason - or more likely the info exists and is documented somewhere but the agent failed to fetch it.

**Architectural drift.** Each change is individually reasonable (the agent does exactly what you tell it to do), and the sum of changes slowly deform the structure away from any coherent design. No single commit or prompt is the culprit, the shape just slowly erodes.

**Unflagged assumptions.** The code encodes a belief about the world — an constraint, a relationship — that no one stated and no test guards. The code holds until it doesn't.

None of these trip a test, because none of them are wrong in the sense a test understands. They're wrong in the sense a *person* understands, and that person is slowly distancing themselves from the code.

## You can't pay it down. You can only not incur it.

This is the hard part, and the reason cognitive debt is nastier than the technical kind. Technical debt you can pay down later, the code sits there and waits for you to refactor it (the eternal "TODO" comments). Cognitive debt can't be paid down after the fact, because the understanding was never captured, and the person who could have captured it never had it. There's nothing to go back to. You can't reconstruct a theory that no one ever held.

Which means the only move is prevention. The understanding has to be made visible *while it's still being formed* — at the moment of the change, by whatever or whoever is making it — or it's gone. Not documented after the fact. Made visible in the act.

That reframes what a tool is even for. For forty years we built tools to help us *write* code faster. If the scarce resource is now understanding rather than typing, the next decade of tools gets built somewhere else entirely — on the expensive half.

Generation got cheap, understanding got expensive. Every tool worth building in this field for the next ten years lives on the expensive side of that line.

Keep reading The Architect.

Essays on staying the author of your codebase in the AI era.
