Cognitive Debt - The Debt You Can't See in the Code
Technical debt lives in the repo. Cognitive debt lives in your team's heads — as an absence.
The code is clean. It follows the style guide, the tests pass, CI is green, and it shipped on Friday without incident. There’s just one problem: nobody on your team can explain why it works.
“Nobody remembers” — that’s normal, six months after the fact. Nobody ever knew. The code was generated, reviewed at a glance, approved, and merged. The understanding was never built in the first place.
Itamar Friedman calls this cognitive debt, and his recent InfoWorld piece, Why AI coding debt is different, is the best articulation I’ve seen of the problem. The scale is not hypothetical: Google has disclosed that AI now generates around 75% of its new code, and Meta has set internal targets for most engineers to have the majority of their committed code AI-generated by mid-2026. Whatever your organisation’s number is today, it’s going up.
Friedman names the disease well. This post is about the architecture of the cure — because I believe the answer is less about discipline and more about design.
What is cognitive debt?
Cognitive debt is the gap between code that exists and code that is understood.
That definition sounds abstract until you put it next to its older cousin. Technical debt and cognitive debt are not the same thing on a spectrum — they sit on entirely different axes. One is about the state of the code. The other is about the state of the team’s mental model.
Two things jump out of this matrix.
First, the dangerous quadrant is not the bottom-left. Everyone recognises a write-off when they see one; the ugliness is the warning label. The dangerous quadrant is the bottom-right, because it is visually indistinguishable from the top-right. Your dashboards, your linters, your code review tooling — all of them will tell you everything is fine.
Second, there’s a natural drift. Bottom-right decays into bottom-left. Code that nobody understands gets patched by people who don’t understand it, one urgent fix at a time, until it is neither clean nor comprehensible. Cognitive debt is how healthy-looking codebases become legacy systems — quietly, and faster than you think.
Here’s the mechanism, and it’s the sharpest insight in Friedman’s piece: when a human writes code, the typing is the least valuable output. The valuable output is everything that happened in the developer’s head along the way — the edge cases mentally simulated, the dependency trade-offs weighed, the three alternative designs considered and rejected. That reasoning is where institutional knowledge comes from. AI code generation delivers the artifact and skips the knowledge entirely.
We optimised for the artifact. The knowledge was the point.
Why it occurs
The comprehension loop is severed
Reviewing code is a fundamentally shallower cognitive act than writing it. When you author a function, you have simulated its failure modes before the first line compiles. When you review someone else’s 500-line diff, you are pattern-matching for anomalies. These are different mental operations, and only one of them builds a durable mental model.
For thirty years, this didn’t matter much because the author existed. Somebody on the team had an in-depth understanding of every line. Review was a second layer of comprehension, not the only one. AI generation removes the first layer and leaves review — the shallow layer — carrying the entire weight.
LGTM economics
Now put a rational developer in front of that 500-line PR. The AI produced it in three minutes. Genuinely understanding it — tracing the data flow, checking the edge cases, questioning the design — would take two hours. The tests pass. The code looks idiomatic. The sprint ends Thursday.
The individually rational choice is obvious, and it’s catastrophic at team scale. Every “LGTM” on code nobody deeply read is a small loan taken out against the team’s collective understanding.
The data says this is exactly what’s happening. GitClear’s analysis of hundreds of millions of changed lines found that duplicated code blocks of five-plus lines increased eightfold during 2024, while refactoring collapsed from about 25% of code changes to under 10%. And the DORA research found that a 25% increase in AI adoption correlates with a 7.2% decrease in delivery stability. We are shipping faster and understanding less, and the instruments are starting to show it.
Vibe coding is 100% cognitive debt
I want to be precise about this claim because it’s the strongest one in this post.
Most cognitive debt is erosion — understanding that existed and decayed, or partial understanding that was never deepened. Vibe coding is different in kind. Vibe coding is, by definition, shipping code you never intended to understand. You describe the outcome, accept what appears, run it, and iterate on the behaviour — never the comprehension.
There is no mental model decaying because no mental model was ever built. The debt isn’t accrued over time; it’s taken out in full at the moment of the merger. Bottom-right quadrant, by construction.
Let me be clear: this is fine for a weekend prototype, a throwaway script, a demo. I vibe-code utilities all the time. But in a production system, vibe coding is borrowing at maximum interest from day one — and as I argued in The Rider, Not the Horse, the rider who never looks down at the horse eventually discovers, at speed, that he has no idea what he’s sitting on.
Why this matters more than technical debt
Three reasons, and I’ll keep this short because the stakes are simple.
Cognitive debt has no early-warning system. Technical debt announces itself through friction — the module everyone dreads touching, the estimate that keeps tripling. Cognitive debt is silent right up until the incident. And then you’re reverse-engineering a black box at 2 a.m. while production burns, which is the most expensive possible time to be learning your own system.
The first-change cliff. The first non-trivial modification to un-understood code routinely costs more than the original feature did. The AI wrote the feature in an afternoon; your team spends a week reconstructing the reasoning before they can safely change one branch of it. The velocity you gained at generation time gets repaid, with interest, at modification time.
It’s now a competitive variable. Teams that preserve understanding while adopting AI get the velocity and the maintainability. Teams that don’t are building their next legacy system at 10x speed. Same tools, opposite outcomes. The reckoning, as Friedman puts it, arrives either way — the only choice is whether you pay now or pay compound interest later.
How to address it: minimize, contain, verify, own
The remedy isn’t one practice. It’s a chain: minimize what needs understanding, contain what’s generated, verify at generation speed, and own the logic that matters. Each link reduces the burden on the next.
1. Minimize — framework-driven development
The less novel the code the AI writes, the less there is to misunderstand.
Constrain generation to opinionated frameworks and well-worn idioms. On my stack, that means Spring Boot conventions: standard controller-service-repository shapes, standard configuration patterns, standard Kafka consumer setups. When the AI produces a REST controller that looks like every Spring controller your team has read for a decade, the cognitive debt on that code is near zero — the team’s mental model existed before the code did.
Framework conventions are pre-paid comprehension. Every line the AI generates inside a known idiom is a line nobody has to newly understand. The corollary: be most suspicious of AI output precisely where it’s most impressive — the clever, novel, bespoke solution is the one carrying the debt.
2. Contain — clear layer boundaries with segregated domain logic
Hexagonal architecture, clean architecture, ports-and-adapters — pick your flavour. These were always good ideas. In the AI era, they get a new job title: cognitive debt containment.
The principle: let AI-generated plumbing live in the adapters and infrastructure layers, and keep your domain logic segregated, small, and human-comprehended. The insight this unlocks is that you don’t need to understand every line in the system. You need to fully understand the domain core and merely trust the boundaries around everything else.
An adapter that maps a REST payload to a domain object can be trusted and tested. The interest-calculation rule at the heart of a lending platform cannot — it must be understood. Architecture is what makes that distinction enforceable rather than aspirational. Good boundaries shrink the surface area that steps 3 and 4 have to cover.
3. Verify — a verification loop at generation velocity
Friedman’s sharpest industry observation: nearly all the investment has gone into code generation, and almost none into verification. We built a blue team with no red team. The evidence that this matters is striking — in his data, teams that integrated AI into code review saw quality improvements in 81% of cases, versus 55% for teams using AI for generation alone.
But verification has to mean more than “the tests pass.” Passing tests is table stakes; it verifies behaviour, not comprehension and not structure. A real verification loop, running at the same speed as generation, checks:
Architectural conformance — does this change respect the layer boundaries from step 2? (Tools like ArchUnit make this a failing build, not a review comment.)
Standards enforcement — does generated code follow the team’s idioms from step 1, or has the AI invented a fourth way to do configuration?
Traceability — can every change be traced to a requirement? Code with no articulable reason to exist is cognitive debt in its purest form.
If generation is automated and verification is manual, verification loses. Every time. The loop must run at machine speed.
4. Own — every piece of business logic verified by a human who owns it
This is the non-negotiable and the last link in the chain.
Infrastructure code can be trusted and tested. Business logic must be understood — by a specific, named human. My working rule: every business rule in production needs someone who can explain it without opening the file. Not “the team owns it.” A name. Collective ownership of comprehension is how comprehension quietly becomes nobody’s job.
The practical mechanism that makes this survivable at AI velocity: tests as executable specifications of intent. If your test suite expresses the business behaviour in readable, domain-language form — given a floating-rate loan, when the benchmark resets mid-cycle, then interest accrues from the reset date — comprehension survives even when the implementation underneath is machine-generated and machine-regenerated. The AI can rewrite the how every week; the humans own the what and the why.
Now walk the chain backwards and notice why it works. Ownership (4) is tractable only because verification (3) catches drift automatically. Verification is tractable only because containment (2) shrank the surface that needs deep checking. Containment works only because minimization (1) reduced the novelty in the first place. Skip a link, and the next one collapses under the volume.
The debt you re-learn
Here is the reframe I’d leave you with: AI didn’t create a code-quality problem. The code, by most measurable standards, is fine — often better than what a rushed human would write. AI created a knowledge-distribution problem. The code is in the repo. The understanding is nowhere.
Technical debt you refactor. Cognitive debt you re-learn — and re-learning your own system during a production incident is the most expensive education there is.
This post builds on Itamar Friedman’s Why AI coding debt is different (InfoWorld). The prescriptions are mine; argue with me in the comments.


