How do you stop AI coding agents from making your codebase messy?
Short answer: the mess an AI coding agent leaves behind is not spread across your project, it concentrates in the handful of files every task has to touch. Measuring this site's repository on August 11, 2026, 410 of the 641 tracked files appear in exactly one commit in their whole history, while three files appear in 56 commits each, more than two and a half times the fourth place. Watching those few files pays off more than any general style rule. This repository is written by AI agents in parallel git worktrees, and we know that from operating the project, not from deducing it out of git.
Why does AI written code look clean file by file and still rot?
Because the unit of work for an AI coding agent is the task, and the unit of quality for a codebase is the whole. Every delivery comes out internally coherent: consistent naming, a test present, impeccable formatting. The defect does not live inside a delivery, it lives between deliveries. The agent solving today's task does not know what Tuesday's agent invented, so it writes a function that already existed under another name, a second way to format a date, a third convention for handling errors. None of those choices is wrong in isolation, which is exactly why they pass. The question showed up in those words on r/ClaudeAI on August 5, 2026, in the title "How are people using Claude Code without letting it make the codebase messy?". The same day, r/ExperiencedDevs was discussing a neighboring and not identical problem, "What do you do when a developer submits AI generated code they clearly don't understand?": there the subject is who answers for the code, not accumulation. Our reading is that both conversations start from the same place, agent output being acceptable piece by piece.
Where does the mess actually accumulate?
In the shared files, and the concentration is sharper than intuition suggests. This site's repository has 324 commits between July 18 and August 10, 2026, across 641 tracked files. Counting with the command in the next section, 410 of those files appear in exactly one commit and never got a second. At the other end, the site's three translation catalogs, one per language, appear in 56 commits each, and the fourth most edited file in the project appears in 22. The drop from the top trio to fourth place, 34 commits, is larger than the distance between fourth place and the floor, which is the entire rest of the project. That moves the problem: a general style rule acts on a project where roughly two thirds of the files were never opened again. The wear is on the minority every task has to open.
How do you find the shared files in your own project?
With a single command, and it is the same one that produced the numbers above. Run git log --name-only --format='' | grep -v '^$' | sort | uniq -c | sort -rn | head -10 and read the list top down: those are the files the most commits touched. In our numbers, the top was taken by the three translation catalogs, the environment configuration file and the routes file, followed by a three way tie at 18 commits between the internal area layout, the application service provider and the home page. Two caveats for reading it. The first is about method: this command does not see what came in through merge commits, so it undercounts in a repository that integrates by merging, and in ours, counting merges as well, the three catalogs go from 56 to 59 commits, the first nine positions stay the same and only the tenth swaps files. What actually changes is not the order, it is the tie, because the trio at 18 becomes 19, 19 and 18 and breaks apart. The second is about appearance: with default git configuration, a path containing a character outside ASCII comes out escaped, and the line shows numeric codes instead of the name. It is reasonable to expect a project without internationalization to have a different champion, which is why you run the list on your own repository before writing any rule for your agents: it is what tells you where your rule needs to apply.
What do you do about the shared file specifically?
Three measures that attack the shared file rather than the agent. The first is giving it an explicit internal order, declared at the top of the file itself, alphabetical or by section, because an AI coding agent respects a convention it can read right there and ignores a convention that lives in the team's head. The second is making an inconsistency break something: a test that walks the three language catalogs and fails when a key exists in one and not in the others is worth more than any instruction in prose, because instructions get forgotten and a red test does not. The third is accepting that a shared file is a conflict point when several agents work in parallel, and scheduling integration so two agents are not holding it open at the same time. None of the three requires the agent to get better.
Doesn't code review catch duplicated code?
Code review does not catch it, and that distinction is what makes the problem hard. Code review judges a delivery: this change is correct, it does what it promises, there is a test that proves it. A duplicated function passes that bar comfortably, because it is correct. What delivery review cannot see is the effect of the fiftieth approved delivery on the whole, since nobody opens the previous forty nine to compare. If your problem is the delivery rather than the accumulation, the right order for reviewing agent output is a separate subject, and we cover it in how to review code written by multiple AI agents. Accumulation calls for a periodic pass with a different question, of the kind "does this already exist somewhere else", run against the whole project and not against the diff.
Do an instructions file and a linter solve the mess?
They solve part of it, and the community converges on that combination: on August 6, 2026, r/ClaudeWorkflows published a playbook titled "[Workflow] Claude Code Workflow: Preventing Messy Code with CLAUDE.md, Subagents, Linters, and TDD", which puts together an instructions file, subagents, a linter and tests before code. The caveat worth stating is that those four pieces attack different layers. Linters and formatters solve mechanical divergence, which is the cheapest and least damaging kind. An instructions file at the project root, whether CLAUDE.md or AGENTS.md, solves what the agent can read before acting. Neither of them can see that the function the agent is about to write already exists under another name three folders away, because that is not a rule, it is knowledge of the repository. For that part, what worked for us was shrinking the surface where duplication fits: an ordered shared file, a consistency test, and smaller tasks, which produce deliveries you are able to reject.
What this measurement does not prove
One repository, 24 days, one product. The concentration we measured here may be an effect of the kind of project, which is a site in three languages and therefore has translation catalogs as an obvious hot spot. A project without internationalization would have a different champion, and perhaps a less extreme concentration. There is also a method limit worth declaring: all 324 commits carry the same git author, because agents sign with the identity of the person running them. The author field cannot separate what an agent wrote from what was written by hand, and that is a traceability problem we did not solve, we only measured around it. What the measurement supports is the shape of the distribution, not the exact number: most files are never revisited and a tiny minority absorbs the rework.