How to deliver high-quality software with AI-native development / Keep the codebase easy to work in
Keeping one codebase when everything is generated
Every agent session starts without memory of the last one. Given the same problem twice it will produce two reasonable solutions that differ, and a year of that turns one codebase into a collection of different styles. This page covers why this drift (the slow spread of different styles) is the default, which conventions are worth enforcing mechanically, and how to keep a system a person can still understand as a whole.
Published September 1, 2026. Editorial.
Key takeaways
- Inconsistency is the default behaviour. A session with no memory of your conventions will invent a reasonable one.
- Conventions that live in a document get followed sometimes. Conventions the codebase enforces get followed always.
- Consistency is an economic argument: an inconsistent codebase makes every future change more expensive, including the AI-assisted ones.
- Pick a small number of conventions that matter and enforce those absolutely, rather than a style guide nobody can apply.
Ask two engineers to solve the same problem and you get two solutions with a shared style, because they work in the same team and have read the same code. Ask six agent sessions and you get six solutions with no shared style at all, because each one started from nothing and inferred a style from whatever it happened to read.
That is the whole problem in one paragraph. It is not a defect. It is what happens when the memory between units of work is zero and the volume of work is high.
Why this costs money
It is tempting to treat consistency as an aesthetic preference. It is not, and the argument is easiest to see from the AI side.
An agent working in a consistent codebase can infer the pattern from any file it reads, and its output fits. An agent working in a codebase with four ways to fetch data, three error-handling styles and two module layouts will pick one at random, and its output fits nowhere. The inconsistency grows with each change: each new change is generated from a sample of an increasingly mixed codebase.
The human cost follows the same pattern. Every reviewer has to decide, per change, which of the local conventions applies. Onboarding takes longer because there is no single answer to how we do things. And the cost of a refactor rises, because a search-and-replace across one pattern misses the three other ways it is written.
The measurable version is delivery speed falling over a period when nothing else changed. Teams usually attribute that to scale or complexity. Often it is inconsistency.
Conventions that last, and where to keep them
A convention has to be in a place the thing following it will read. That is a stronger requirement than it sounds, and it rules out most wikis.
For agents, that means in the repository: a project instruction file the tool loads on every session, plus the code itself. Anthropic's guidance for a CLAUDE.md file is worth reading as a general principle, including the part most teams get wrong: keep it short, since a long file full of extra detail causes the model to ignore the actual instructions [1]. A five-page style guide in the context window is a five-page style guide the model skims.
The practical order, from most reliable to least:
Mechanical enforcement. A linter rule, a type, a module boundary, a formatter. This is followed one hundred percent of the time by both humans and agents because it fails otherwise.
A visible example. One standard implementation of the pattern, named in the instruction file. Agents follow examples well: naming a file is more effective than describing the rule in prose.
A written rule. Useful for things a tool cannot check, such as naming intent. Followed most of the time if the file stays short.
A rule in a document outside the repository. Followed by nobody, human or machine.
Move as much as possible up that list. Every rule you can convert from prose into a failing check is a rule you never have to enforce in review again, which is the argument in the quality gates that should block a merge.
Choose few conventions and enforce them absolutely
The instinct when inconsistency appears is to write a comprehensive style guide. That fails for the same reason a twenty-item blocking gate list fails: enforcement effort is finite, and a rule that is sometimes enforced teaches everyone that rules are negotiable.
The set worth enforcing is small. In our experience it is these:
How data is fetched and errors are handled. The single highest-value convention, because it appears in almost every change and inconsistency here produces real bugs rather than only extra effort.
Where things live. One module layout, enforced by structure and, where the tooling allows, by import rules. This is what keeps an agent from creating a second place for the same concept.
How things are named. Not a naming style so much as a vocabulary: one word per concept, used everywhere. When a customer is a customer in one module and an account in another, every future change has a translation step in it.
What is allowed to call what. Layer and boundary rules, enforced mechanically. This is the one that protects architecture rather than tidiness, and it is the reason to spend time on it.
Everything else, including formatting, should be applied automatically by a tool and never discussed.
Detecting inconsistency before it is expensive
Inconsistency is easier to fix early, and it is invisible unless you look for it. Three cheap checks.
Count the ways. Once a quarter, pick one common operation and count how many distinct implementations of it exist. Going from one to three is normal and manageable. Going from three to nine is a signal to stop and consolidate.
Watch the review comments. Repeated comments about structure or approach are inconsistency being noticed by humans. That is expensive detection: convert those comments into checks.
Ask an agent about the codebase. An agent is good at this specific task: give it the repository and ask for the distinct patterns used for a given job, with file references. It reads faster than any human and it does not get bored. This is one of the highest-value uses of AI on an existing codebase, and it costs almost nothing.
Consolidating without a rewrite
When drift has already happened, the temptation is one large project to make everything the same. Those usually stop partway, because they are large, risky, and produce no visible value for weeks.
The approach that works is narrower. Pick one pattern. Write down the standard version and name it in the instruction file. Then convert the existing instances in small, separately reviewable changes, in risk order, verifying behaviour is unchanged as you go. That last part is the hard part and it has its own page: refactoring with agents without changing behaviour.
The important discipline is to stop the problem growing first. There is no point converting forty call sites while new ones are still being generated in the old pattern. Enforce the rule mechanically, then convert.
Several repositories make it harder, not easier
Splitting a system into many repositories used to limit how far inconsistency could spread. With agents it does the opposite, for one specific reason: an agent working in repository A cannot see the convention that repository B settled on last week, so the inconsistency grows between repositories where nobody is reviewing both.
Three things reduce that.
Put the shared conventions somewhere every repository loads, rather than copying them into each one. Copies diverge, and a divergent copy is worse than no copy because two agents will both believe they are following the standard.
Keep genuinely shared behaviour in a shared library with one owner, rather than letting each repository grow its own version of the same helper. The version that gets generated independently in six places will differ in six ways, and the differences will be in error handling, which is where they cause the most harm.
Decide deliberately which conventions are global and which are local. Trying to enforce every rule across every repository produces a governance process nobody follows. Trying to enforce none produces a company with six different styles. The set worth making global is small: how services communicate with each other, how errors cross a boundary, and the vocabulary.
The limit worth respecting
There is a version of consistency that becomes its own problem: a codebase so rule-bound that every change requires a policy discussion. The test is whether a convention prevents a class of bug, reduces the cost of change, or only satisfies a preference. If it is the third, drop it and put the effort somewhere more useful.
The related mistake is enforcing a convention the codebase does not actually follow. A rule that most existing code violates produces two bad outcomes at once: agents infer the real pattern from the code and ignore the written rule, and every new change generates an argument about which is authoritative. Either bring the code to the rule or change the rule to match the code, but do not publish a written standard that most of the repository contradicts.
Where this connects
Consistency is what makes the documentation an agent and a new hire can use short enough to stay accurate, and it is what makes safe refactoring possible at all. The architectural version of the same argument, about which boundaries need a human, is the decisions that stay with your engineers. The main guide sets out where this sits in the delivery model.
Common questions
Why does a codebase become inconsistent faster when agents write the code?
Because each session starts with no memory of the last one. Given the same problem twice, an agent produces two reasonable solutions that differ, and it infers style from whatever files it happened to read. With high change volume that produces several different styles inside one repository within a few months.
Is codebase consistency worth spending time on, or is it just tidiness?
It is an economic argument. An agent working in a consistent codebase infers the pattern from any file and its output fits; in a mixed codebase it picks one of four patterns at random and fits nowhere. Reviewers then decide per change which local convention applies, onboarding slows, and refactors miss instances spelled differently.
Where should coding conventions live so agents follow them?
In the repository, in a project instruction file the tool loads every session, and in the code itself. Anthropic's guidance is to keep that file short, because a long one full of extra detail causes the model to ignore the actual instructions. A convention in a wiki outside the repository is followed by nobody, human or machine.
Which conventions are worth enforcing mechanically?
Four carry most of the value: how data is fetched and errors handled, where things live, one vocabulary word per concept, and what is allowed to depend on what. Formatting should be applied automatically by a tool and never discussed, and everything outside that list is usually preference rather than protection.
How do we detect codebase inconsistency before it gets expensive?
Count the ways. Once a quarter, pick a common operation and count how many distinct implementations exist. One to three is normal; three to nine is a signal to consolidate. Repeated review comments about structure are the same signal arriving through humans, which is a more expensive way to detect it.
Can an agent help find inconsistency in our own codebase?
Yes, and it is one of the best uses of AI on an existing codebase. Give it the repository and ask for the distinct patterns used for a given job, with file references. It reads faster than any person, does not get bored, and produces a list you can act on in an afternoon.
Should we run a project to unify all the patterns at once?
No. Large projects to make every pattern the same usually stop partway, because they are large, risky and produce no visible value for weeks. Pick one pattern, write down the standard version, enforce it mechanically so no new instances appear, then convert the existing ones in small separately reviewable changes in risk order.
What is the first step when drift has already happened?
Stop the problem growing before converting anything. There is no point migrating forty call sites while new ones are still being generated in the old pattern. Add the mechanical enforcement and the standard example first, then start the conversion, otherwise the work never finishes.
Can a codebase be too consistent?
Yes, when every change needs a policy discussion. The test for any convention is whether it prevents a class of bug, reduces the cost of change, or only satisfies a preference. If it is only preference, drop it and spend the enforcement effort on a rule that protects something real.
How does inconsistency show up in delivery numbers?
As delivery speed falling over a period when nothing else changed. Teams usually attribute that to scale or growing complexity, and often it is inconsistency: reviewers making more decisions per change, agents generating output that matches nothing, and refactors that keep missing instances written in another style.
Related reading
What to do when the AI writes the wrong abstraction
A wrong abstraction does not fail a test or break a build. It makes the next twenty changes harder without anyone noticing, and by the time someone does, removing it has become a project of its own.
What technical debt really is, and when to pay it back
Technical debt is not messy code. It is a deliberate choice to give up some quality for speed. Here is how to tell smart debt from reckless debt, and when to pay each one back.
What good code review looks like when nobody wrote the code
With human code, the author is the first check and review is the second. With generated code, review is the only check. That one change alters most of what a reviewer should be doing.
More in Keep the codebase easy to work in
Documentation an agent and a new hire can both use
Documentation used to be read occasionally by people. It is now read constantly by agents, which changes what is worth writing. Short, current, and in the repository beats comprehensive and out of date, because a wrong document does not just mislead a new hire once, it is loaded into every session and reproduced at volume.
Refactoring with agents without changing behaviour
Refactoring is the work agents are best at and the work where their failure mode is most dangerous: a change that looks like restructuring and alters what the software does without anyone noticing. The protection is a behaviour guarantee established before the refactor starts, plus a discipline of never mixing restructuring with a functional change.