If you edit code with Claude Code or Cursor, you have probably run into this situation. You ask a coding agent to tweak the styling of a button, and instead it goes digging through a pile of unrelated old files, even rewriting hundreds of lines of legacy code nobody asked it to touch. At times like that, we tend to assume today’s models simply aren’t smart enough yet, and that once the next generation of stronger reasoning models arrives, the problem will take care of itself.
Then on November 6, 2026, Google’s developer productivity team
published an empirical
study backed by data
from over 913,000 real internal coding sessions that delivered the
exact opposite answer. Comparing sessions where the same developer
worked on the same type of task in the same part of the codebase, they
found that more capable models are actually more likely to get
sidetracked by a single old TODO comment in the source
code.
Once an agent starts chasing a historical comment it was never asked to handle, a single session takes 70% more steps and burns 77% more tokens on average. Worse, the time you spend waiting in front of your screen jumps by 105%, making the session more than twice as slow.
Why does a smarter model insist on going off-script to investigate B when you clearly only asked it to change A? It starts with how differently humans and large language models read source code.
Experienced human engineers carry a built-in attention filter: they
know the words just typed into the chat box are the active instruction,
while a TODO left in a source file years ago is merely
unfinished historical background from whoever came before. We glance at
an old comment, skip right past it, and don’t stop to pay off someone
else’s old debt.
Inside a large model’s context window, however, every piece of text
sits on equal footing. Whether words come from your prompt box or from a
source file the agent just read in, the model treats them as part of the
same flat plane of context. Worse still, a TODO comment is
grammatically structured as an unfinished imperative sentence, such as
an instruction to add a validation check or support an extra format.
Older, weaker models behaved like obedient puppets. Ask one to edit line 50, and it edited line 50, forgetting the surrounding comments the moment it read past them. Today’s frontier reasoning models, by contrast, suffer from acute straight-A student syndrome. Throughout reinforcement learning, they are repeatedly rewarded for two behaviors: proactively gathering clues when they hit friction, and proactively closing out open loops whenever they spot unfinished work.
Put an overeager straight-A student like that inside a legacy
codebase plastered with years-old sticky notes, and trouble follows. The
moment it hits minor friction on its main task and catches sight of a
nearby imperative TODO, it treats that old note as either
an investigative lead or extra credit waiting to be claimed. Right away,
it fires up global code search, internal documentation lookup, and
issue-tracker tools, burning compute cycles arguing with a relic of the
past. According to Google’s numbers, once an agent exposed to such a
comment takes an unprompted detour to meddle with it, 40% of the time it
goes right ahead and edits the code.
A real session shared in Google’s post puts this straight-A
compulsion on full display. Earlier in the very same session, the agent
had just verified a key fact on its own: the new downloader was already
100% rolled out in production, and the legacy downloader
ModelDownloaderV1 had long been deprecated.
While investigating its main task, however, the agent happened to
read that deprecated file and spotted an open TODO saying
an eligibility check needed to be implemented in the downloader. Because
the new downloader used dependency injection for modular decoupling and
stayed completely agnostic to specific product models, its code
naturally contained none of those feature-specific terms. Instead, it
was the dead file that spelled out the exact instruction in plain
text.
The agent’s compulsion kicked in immediately. Its codebase search matched across 4 files, it retrieved 10 internal documents, and it went straight to modifying that dead code.
Only when the human engineer lost patience and confronted it in chat,
asking why it was modifying a legacy file like
ModelDownloaderV1 instead of the new files right after
saying the new version was fully rolled out, did the agent admit its
mistake. It acknowledged that it had edited dead code that never
executes in production, while also violating the decoupled design of the
new architecture.
At this point, a straightforward fix probably comes to mind. If stale
sticky notes cause this much trouble, why not write an automated script
to check the issue tracker and delete every TODO comment
tied to a closed ticket?
According to Google’s data, 41% of the unprompted detours agents take
do in fact point to tickets that are already closed: 32% are bugs
someone already fixed while forgetting to remove the comment in code,
and another 9% are dead-end tickets long ago marked obsolete or
won’t-fix. Yet even for this batch of closed-ticket comments, nobody
dares wipe them all out with a single script. That is because
programmers share a widespread habit when writing comments: packing both
what should be done in the future and why the code must not be touched
right now into the exact same TODO line.
Another case from Google’s post stepped right into this trap. In that
session, an agent reading SurfaceControlTest.java, a
graphics test file in the Android Compatibility Test Suite, spotted a
TODO comment asking to add test coverage for the
YUV420 image format. It dropped its task to look up the
bug, only to discover the ticket had long been closed, wasting the
entire trip.
Looking up the commit
history of the Android Open Source Project makes the full story
clear. An engineer added that comment in April 2023 under bug ID
277348717 while fixing a test crash on production phones.
He removed the crash-inducing YUV420 image format from the
test parameters, kept only the YV12 format, and closed the
ticket at the same time. Yet in that very same commit, he reused the bug
ID he had just closed to add a TODO comment above the
function. The first half of the comment noted that at the very least
this format check should be added back in the future, while the second
half warned that even when the underlying hardware buffer interface
reports support, the image reader on certain devices still fails to
support that format.
That created an engineering trap. Even though the ticket linked to
this TODO was already closed from the moment the code
landed, the second half of the comment served as the only load-bearing
warning in the entire block explaining why the line below tested just a
single format. If an automated script saw the closed ticket and deleted
the whole comment line, that load-bearing wall would come right down.
The next human developer or AI editing the file would never see the
warning about the hardware quirk, assume test coverage was incomplete,
casually add YUV420 back into the test list, and bring the
test crashes right back to production phones.
To tackle this, Google built a dedicated cleanup agent. Before submitting a code change to delete any stale comment, the agent cross-examines years of bug discussions, file edits, and commit history to make sure no hidden load-bearing warning is buried inside before removing it. Over 6 months in operation, it cleared out thousands of obsolete comments, with human reviewers accepting over 95% of its changes.
Yet this heavy-duty Big Tech infrastructure has an obvious arithmetic blind spot. At best, it can only clean up the 41% of false sticky notes pointing to closed tickets, while leaving untouched the 57% of live sticky notes that point to real, still-open tickets.
More than half of the comments that lure agents into unprompted detours correspond to genuine, unfixed backlog bugs in the issue tracker, meaning no automated cleanup tool can delete them. And as long as those live sticky notes remain in the source files, the next overeager frontier model passing through will still drop what it is doing on its own initiative to look up the ticket or even rewrite code for you. Within this 57% bucket of open-ticket detours, the agent still went ahead and edited code 39% of the time.
Reining in these inline comments pays off far more than traditional
code refactoring. In May 2026, SonarSource ran a code cleanliness experiment.
They found that investing heavy effort to eliminate classic code smells
like overly long functions and high cognitive complexity reduced a
coding agent’s input token consumption by roughly 7.1% to 10.7%. By
comparison, letting a single imperative TODO lure an agent
off course burns an extra 77% in tokens in one session.
Once we see the two root causes clearly, straight-A student syndrome on one side and load-bearing warnings tangled up with action items on the other, we don’t need to build a Google-scale system that excavates years of archives. Spending 5 minutes today to set two team rules is enough to close off both the live-note and stale-note traps at once.
The first rule is written for the model, to contain the 57% of live
sticky notes. Open AGENTS.md or CLAUDE.md in
the root of your repository and spell out an explicit execution
boundary: all TODO and FIXME comments in
source files are read-only historical background; unless the user
explicitly asks to address one in the current prompt, even if a comment
points to a real open bug, do not look up its ticket, do not search
across files for it, and do not opportunistically edit related code.
Draw that bright red line for the straight-A student, and it will
dutifully leave background as background.
The second rule is written for ourselves, to defuse the 41% of false
sticky notes. From now on, separate load-bearing warnings cleanly from
action items whenever you leave comments in code. Put any hardware
limitation or domain quirk explaining why a piece of code must not be
touched on its own line under WARNING: or
NOTE:, and reserve TODO: strictly for work
that genuinely remains to be done in the future, so the entire line can
be safely deleted the moment its ticket closes. And whenever a module
upgrades to a new version while legacy files cannot yet be deleted,
place a prominent notice on line one of every legacy file stating that
the file is deprecated and must not be modified. Separate the
load-bearing walls from the sticky notes, add a few lines of rules to
rein in surplus curiosity, and your coding agent will spend far fewer
cycles wrestling with old ghosts and put its compute toward the work
that actually matters.