Why AI-Generated Comments Rot Faster Than the Code They Describe
When an agent writes a function and a comment in the same diff, the comment is not documentation. It is a paraphrase of the code at write-time, generated by the same model from the same context, and it is silently wrong the first time the code shifts. The function gets refactored, an argument changes type, an early-return gets added, the comment stays. By next quarter, the comment is encoding a specification that no longer matches the code, and the next reader trusts the comment because the comment is easier.
This is an old failure mode — humans-edit-code-comments-stay-stale — but agents accelerate it across three dimensions at once. Comment volume goes up because agents add a doc block to every function whether it needs one or not. The comments are grammatically perfect, so reviewers don't flag them as low-quality. And the comments paraphrase the code in different terms than the code actually executes, so they look like documentation but encode a second specification that drifts independently of the first.
The cost shows up later, in the form of a maintenance trap that compounds. A future reader builds their mental model from the comment. A future agent — or a future engineer — "fixes" the code to match the comment when the two diverge. The bug that ships isn't a hallucination. It's a faithful execution of the wrong spec.
The Second-Specification Problem
A code comment that paraphrases the function it sits on top of is a second specification. The function says one thing in code; the comment says something close to that thing in English. As long as both are written by the same author at the same moment, they agree. The instant the code moves, they disagree, and there is no mechanism that makes them agree again.
For human-written comments, this problem self-limits. Humans are lazy about writing comments, so the comments that exist tend to encode something the author thought was worth saying — an invariant, a workaround, a non-obvious reason. Those are still vulnerable to drift, but the volume is small and the surviving comments often encode load-bearing information that a careful reviewer notices when the surrounding code changes.
Agents do not have that filter. An agent will gladly write a four-line docstring describing a three-line function. The docstring restates the parameter names, restates the return type, and restates the obvious. None of it is wrong on day one. None of it is useful on day one either. But every line of it is a hostage to fortune: when the function changes, every clause in the docstring is now a candidate to be wrong. The probability that the whole block is still accurate after two refactors approaches zero, and nobody notices because the comment still reads fluently.
The asymmetry is what makes this dangerous. AI-generated code that breaks tends to break loudly — a type error, a failed test, a 500 in staging. AI-generated comments that drift break quietly. There is no test that fails when a docstring lies. There is no compiler that warns when the prose says "returns null on missing key" and the code now throws. The comment rot is invisible until a reader acts on it.
Why Reviewers Wave Comments Through
In a 2025 GitHub blog post on Copilot code review, the team noted that the agent now averages about 5.1 comments per review and stays silent on 29% of PRs entirely — the result of explicit work to reduce noise so that high-signal feedback survives. The reviewer-side discipline is well understood at this point: when AI review comments have less than a 30–40% action rate, you're generating noise, and the configuration needs tightening.
But the same discipline rarely gets applied to AI-authored docstrings and inline comments inside the diff itself. Two reasons.
First, comments don't break the build. A reviewer scanning a 400-line PR for problems is looking at signatures, control flow, error handling, and the obvious places things go wrong. A grammatically clean docstring on a helper function is a green light visually — it looks like the author cared enough to document. The reviewer's pattern-matcher treats it as a positive signal and moves on.
Second, the comments are uniformly fluent. Human-written comments come in a range of styles that betray the author's relationship to the code: terse for code they wrote and trust, defensive for code they're nervous about, expansive for code that surprised them. Agent-written comments are uniformly polished, uniformly grammatically complete, and uniformly written in the same neutral documentation voice. There is no tonal signal that this comment is more or less load-bearing than the next one. So reviewers either trust them all (the common case) or distrust them all (rare and exhausting).
The fluency gap is the trap. A reviewer who would push back on "ok now we add the user" will not push back on "Adds the user to the database after validating the email and normalizing the username for case-insensitive lookup." The second sentence is no more verified than the first. It is just better-formatted.
The Compounding Maintenance Trap
The first time a comment drifts from the code, the cost is small — a confused reader, a few minutes lost. The compounding cost lives one cycle further out, when the drift starts to influence future edits.
Three patterns recur. The first is the trust-the-comment edit, where a future engineer or agent reads the comment, doesn't carefully re-derive the code's behavior, and writes code that depends on what the comment says rather than what the code does. The second is the fix-the-code edit, where the engineer or agent notices the divergence and "fixes" the code to match the comment, on the assumption that the comment encodes the original intent. The third is the doc-as-API edit, where downstream consumers — including agents in other parts of the codebase — quote the comment as if it were a contract.
Each of these failures is worse than the simple "comment is stale" failure, because each one propagates the wrong specification into new code. By the time the bug surfaces, the comment, the calling code, and possibly some tests are all consistent with each other and inconsistent with what the system actually needs to do. Bisecting that is expensive. There is no single bad commit; there is a slow drift driven by the comment acting as gravitational mass on every nearby edit.
A version of this is already documented in AI-assisted development as "documentation drift" — the silent killer of agent workflows, where an agent's configuration references outdated architecture docs and every suggestion is built on a foundation of lies. The same dynamic plays out at the function level inside source files. Once an agent has written a wrong comment, the next agent reads the wrong comment as ground truth.
Treating Agent Comments as a Separate Artifact Class
The fix is not "stop using AI to write code." The fix is to treat AI-generated comments as a separate class of artifact in code review, with stricter rules than AI-generated code, because the failure mode is sneakier and the verification is weaker.
Three rules cover most of it.
Don't merge a comment unless you would have written it. This is the simplest filter and it eliminates most of the rot at the source. If the function is self-explanatory and you wouldn't have written a docstring, delete the agent's. If the comment paraphrases the code, delete the comment. If the comment encodes a non-obvious invariant — the kind a future reader could not derive from the code — keep it, but rewrite it in your own words so you take ownership of the claim. The agent is a draft, not a co-author.
Hoist load-bearing comments into tests. A comment that says "fails if the input list is empty" is encoding a precondition. Rather than trusting prose to stay accurate, write the test that fails when the precondition is violated. The test is the comment that doesn't drift, because a refactor that breaks the contract breaks the test. This is not a new idea — it's the executable-specification argument from a decade ago — but it lands differently in an AI-assisted codebase, where the alternative is letting the model's generated prose stand in for the contract.
Review comments for the six-month version, not the day-one version. Day one, the comment is accurate by construction. The reviewer's job is to ask: "If the function shape changes in two refactors, will this comment still be accurate, or will it be silently wrong?" If the answer is "silently wrong," the comment is a liability and should either be removed or rewritten to encode something resilient — an intent, a reason, a constraint — rather than a paraphrase of the current implementation.
These rules are uncomfortable because they ask the reviewer to delete code that someone (or some agent) wrote. The defense is that an empty function is closer to correct than a function with a wrong docstring on it. Silence is better than a confident lie.
Lints, Heuristics, and Team Policy
There is also a tooling layer worth building, even though it is imperfect. The signals that a comment was written by an agent are statistical, not deterministic — uniform grammatical structure, doc-style formatting on small functions, vocabulary that mirrors the function name and parameter names too closely. None of those are dispositive on a single comment, but in aggregate they give you a useful prior.
A lint rule that flags grammatically uniform doc-style comments on functions under N lines is annoying but useful. It surfaces the exact category of comment that is most likely to be paraphrase-rot in disguise. A pre-commit hook that requires a justification when a docstring is added without an accompanying behavior change is heavier-handed but plugs the most common leak. A CI check that re-validates docstrings against function signatures — at least to confirm parameters and return types still line up — catches the most mechanical drift.
None of these tools catch semantic drift. A comment that says "this function deduplicates by primary key" doesn't lint as wrong when the deduplication logic switches to a hash of the whole row. The only safeguard against semantic drift is a reviewer who reads the comment and the code together and asks whether they say the same thing. Agents can help with that review, but cautiously: an LLM-as-judge that checks "does this comment match this code" inherits the same paraphrase tendencies that produced the comment in the first place, and is more likely to confirm a fluent comment than to flag it.
The team-policy version of this is to make the standard explicit. Comments are reviewed for what they will say in six months, not for what they say today. AI-generated docstrings are deletable by default unless they encode something prose can do that code cannot — usually a why, occasionally a workaround, rarely a why-not. Anything else is paraphrase, and paraphrase is rot waiting to happen.
The Forward Path
The pragmatic position is that AI-generated comments are net-negative by default and net-positive only when they pass an explicit filter. That filter is the same one humans should already be applying to their own comments — does this comment encode information the code cannot — but it is more important now, because the volume has gone up by a factor of five and the fluency has gone up by a factor of ten.
Codebases that get this right will look slightly under-commented compared to the AI-assisted average. The functions will have signatures, types, and tests doing the work that prose used to attempt. The few comments that survive will encode reasons, constraints, and warnings that a future reader genuinely could not reconstruct from the code. Those comments will be worth reading because they are the ones nobody could be bothered to delete.
Codebases that get this wrong will look immaculately documented and will quietly accumulate a parallel specification, written in English, drifting further from the code with every refactor, gravitationally pulling future edits toward the wrong answer. The bug that finally ships will look like an agent hallucination. It will actually be the agent faithfully executing a spec that the team approved six months earlier without reading carefully. The fix will not be a better model. The fix will be a delete key, used earlier and more often.
- https://github.blog/ai-and-ml/github-copilot/60-million-copilot-code-reviews-and-counting/
- https://github.blog/changelog/2025-10-28-new-public-preview-features-in-copilot-code-review-ai-reviews-that-see-the-full-picture/
- https://blog.cloudflare.com/ai-code-review/
- https://simonwillison.net/2025/Mar/2/hallucinations-in-code/
- https://news.mit.edu/2025/can-ai-really-code-study-maps-roadblocks-to-autonomous-software-engineering-0716
- https://smarterarticles.co.uk/the-ai-coding-productivity-illusion-why-developers-feel-faster-but-deliver
- https://swimm.io/learn/code-collaboration/comments-in-code-best-practices-and-mistakes-to-avoid
- https://swimm.io/blog/code-comments-vs-documentation
- https://dev.to/mossrussell/your-ai-agent-is-coding-against-fiction-how-i-fixed-doc-drift-with-a-pre-commit-hook-1acn
- https://diffray.ai/agents/documentation/
- https://dev.to/singhdevhub/how-we-prevent-ai-agents-drift-code-slop-generation-2eb7
- https://arxiv.org/html/2404.00971v3
- https://dl.acm.org/doi/10.1145/3735636
