Blog
How to Use AI Coding Without Accumulating Comprehension Debt
10 min read
"I merged it, but I couldn't really explain it if someone asked." Most developers who use AI coding tools heavily have thought this — usually after a PR review where the AI-generated diff was correct, the tests passed, and the feature worked. Approving it felt fine in the moment. The discomfort is the point. That feeling is comprehension debt being created.
Comprehension debt is not technical debt. It does not show up in the code. It accumulates in the developer — specifically, in the widening gap between what the codebase does and what any individual on the team actually understands. Technical debt slows you down when you change the system. Comprehension debt slows you down before you even know where to start.
The fix is not to stop using AI. The developers who avoid comprehension debt are the ones who use AI to understand code, not just to produce it. This post is about how to do that — specifically, practically, with concrete changes to how you prompt and review AI output.
The comprehension debt trap
Speed is the reward AI coding tools deliver first. A feature that took a day of careful implementation now takes an hour of prompt iteration. A refactor that required deep reading of unfamiliar code now arrives as a generated diff with a one-line explanation. The velocity is real and the incentive to keep moving is strong.
The cost is also real and it is deferred. Each piece of AI-generated code you approve without understanding is a unit of comprehension debt. Individually, each unit feels negligible — one function you could explain if you read it carefully, one design decision you could reconstruct if you had the time. Collectively, after weeks of AI-accelerated shipping, the debt reaches a threshold where the codebase moves faster than your mental model of it.
When that gap opens up, debugging gets slow. Not because the code is bad — it may be excellent. Because you do not know where to look. Because the system has changed in ways you never fully processed. Because the AI-generated path through the payment flow is subtly different from the one you thought you understood, and you spend four hours finding that out instead of four minutes.
This is the same mechanism that causes the 90-day reckoning in vibe-coded codebases: the system grows faster than human understanding of it, and eventually every new change requires archaeology of things nobody fully learned.
The difference between "AI wrote it" and "I understand what AI wrote"
There are two ways to get a feature shipped with AI. The first: prompt, review that it looks plausible, run tests, merge. The second: prompt, read carefully, ask questions, trace the execution, form an opinion on the approach, then merge.
The outputs look identical at merge time. They are not identical six months later. The developer who used the second approach owns the decision. They can explain it, modify it, and debug it without rereading the code from scratch. The developer who used the first approach is revisiting the feature as a stranger every time they need to touch it.
The distinction matters most for code that sits at the center of important system behavior — authentication flows, payment processing, data pipelines, service integration points. These are the places where comprehension debt causes the worst outages and the slowest debugging cycles. They are also the places where AI-generated code is most likely to look correct on the surface while containing a subtle misunderstanding of the system's requirements.
Senior engineers often describe this as the difference between using AI as a drafting tool versus using it as a ghost writer. A drafter produces something you then own. A ghost writer produces something under your name that you never fully read.
Five practices that prevent comprehension debt from accumulating
These practices do not require abandoning AI-assisted development. They require changing where in the workflow you slow down — not at the start (before you prompt) but in the middle (before you approve).
Five practices that prevent comprehension debt from accumulating:
1. Explain before you accept
Before approving AI-generated code, prompt:
"Explain what this implementation does and why you made each structural choice."
If the explanation reveals something you did not understand, you now understand it.
If the explanation reveals a wrong assumption, you catch it before it ships.
2. Trace the logic yourself
After reading the AI's explanation, trace the execution path manually.
Follow one request from entry point to response. Don't just read — trace.
This is slower. That is the point. Slowing down for three minutes per change
is the cost of not spending three days debugging it later.
3. Ask about alternatives before accepting the first answer
"What are two other approaches to this, and what are the tradeoffs?"
Reviewing alternatives forces you to form an opinion, not just accept output.
Engineers who understand tradeoffs own the decision. Engineers who accept
the first output are just approving something they do not understand.
4. Write the integration yourself
Let AI generate the core logic. Write the integration code yourself.
The seam between a new piece of code and the existing system is where
comprehension gaps cause the worst bugs. Own that seam.
5. Require yourself to explain it to a colleague
Before closing the PR, answer this question out loud or in writing:
"If someone asked me tomorrow why this works the way it does, what would I say?"
If you cannot answer it, you have accumulated comprehension debt on this change.The key principle across all five is that the obligation to understand has not been transferred to the AI. AI drafts the code. You own it. Owning code means being able to explain it, modify it, and debug it without starting from scratch every time you encounter it.
The "explain before you accept" practice is the single highest-leverage change. It costs two minutes per change. It surfaces the misunderstandings — both yours and the AI's — before they become bugs. It also forces the AI to articulate the reasoning, which frequently reveals assumptions that do not hold in your specific system context.
The comprehension test
A comprehension test is a structured set of questions you require yourself to answer before approving an AI-generated change. It is not a code review checklist — it is a comprehension check. The goal is not to verify that the code is correct. The goal is to verify that you understand it well enough to own it.
The comprehension test — questions to answer before approving AI-generated code:
Structural questions:
-> What does this function/module do, in one sentence?
-> What does it depend on? What depends on it?
-> What happens when the main happy path fails?
Decision questions:
-> Why this approach and not the obvious alternative?
-> Is there already something in the codebase that does this?
-> What will break if the input shape changes?
Integration questions:
-> Where does this get called? How often? Under what conditions?
-> Does this match how similar things are handled elsewhere in the system?
-> What would a future engineer need to know to modify this safely?
Fail threshold: if you cannot answer 6 of these 9, do not approve the PR.
Understand first. Ship second.The nine-question threshold is not arbitrary. It covers the three planes of understanding that matter for long-term ownership: what the code does structurally, why it was designed the way it was, and how it fits into the running system. A developer who can answer six of nine on every AI-generated change they approve is a developer who is maintaining comprehension, not just shipping features.
For teams managing AI-assisted onboarding to legacy codebases, this test also serves as an onboarding filter — ensuring that new developers build genuine understanding rather than pattern-matching their way through changes they do not actually grasp.
How codebase context tools change the equation
The comprehension practices above are necessary but incomplete in one specific scenario: when the AI does not have accurate knowledge of what already exists in your system. This is where comprehension debt and technical debt intersect. An AI that builds a second implementation of a retry pattern — because it does not know the first one exists — creates technical debt and comprehension debt simultaneously. You end up approving code that looks correct in isolation but is architecturally inconsistent with the rest of the system. Understanding the function is not enough. You would also need to know about the existing pattern, which the AI did not surface.
A semantic codebase context layer changes this by giving the AI system knowledge before it generates. When the AI knows that RetryManager already exists, it extends it rather than creating a duplicate. When it knows that NotificationOrchestrator handles all notification dispatching, it routes through that rather than building a new path. The code it generates is architecturally consistent — which means understanding it is not just a matter of reading the function, but of seeing how it connects to what already exists.
This also changes what comprehension means in practice. When AI has system context, understanding what it generated includes understanding how it connects to the existing system — because the AI built those connections deliberately rather than accidentally. The developer reviewing the change is not trying to reconstruct architectural intent from generated code; the intent is visible in how the new code was integrated.
AI-assisted development without system context ("accept and ship"):
Prompt: "Add retry logic to the payment processor."
Result: AI generates a new RetryHelper with exponential backoff.
Problem: RetryManager already exists in /services/shared/retry.ts
PaymentProcessor now has two retry implementations.
One handles transient network errors. The other does not.
In 6 months, nobody knows which one is canonical.
AI-assisted development with system context ("understand and apply"):
Prompt: "Add retry logic to the payment processor."
Context: Semantic index surfaces RetryManager in shared services.
Result: AI extends RetryManager with a PaymentRetryStrategy.
One canonical implementation. Consistent error handling.
A future engineer can understand the retry logic in one place.
The difference is not AI vs. no AI.
The difference is operating with system knowledge vs. operating in the dark.What the codebase looks like six months in
Two teams. Same stack. Same AI tooling. Same feature velocity in month one. At month six, their codebases look different in ways that are not immediately visible in the code itself — they are visible in who can answer questions about the code.
The team that accumulated comprehension debt has a codebase that works but that only the original author can navigate without significant ramp-up time. When that author is out, debugging takes twice as long. When a new engineer joins, onboarding is slow not because the codebase is particularly complex, but because the accumulated context that explains the decisions lives nowhere except in the heads of the people who generated the prompts. There is no "why" document. There is no institutional memory. There are only the merge commits and the AI-generated code that represents them.
The team that maintained comprehension — using the practices above, treating AI as a drafting tool rather than a ghost writer — has a codebase where most engineers can explain most decisions. Not because they wrote more code, but because they processed what was generated. They own the implementation choices. They know which patterns are canonical. They can explain the retry logic without rereading it from scratch.
At the six-month mark, the second codebase is also significantly faster to extend. New features start from actual system knowledge, not from reverse-engineering what the AI previously built. Debugging is faster because the mental models are accurate. On-call shifts are less chaotic because the people holding the pager understand the system they are responsible for.
Final take
The developers who get the most out of AI coding tools are not the ones who trust AI output the most. They are the ones who process AI output the most — who use the AI to draft and then spend the time to genuinely understand what was drafted before they approve it.
Comprehension debt is a choice. Every merge where you approved code you did not fully understand was a decision to move fast now and pay the understanding cost later. The developers who avoid it have simply decided that understanding is not optional — it is the work. AI handles more of the drafting. That frees up time to understand what was drafted. Use that time.