Skip to content

Your AI-Generated Codebase Has an “Epigenome”

You ask an AI coding agent to add a feature.

It edits several files, creates a migration, updates the interface, and writes a few tests. Everything passes. The pull request looks reasonable. You merge it.

Weeks later, you ask the same agent, or a different one, to extend that feature. This time the work gets strangely brittle. The agent duplicates a business rule, invents a second error format, bypasses an existing service, or changes something that should have been unrelated.

The first implementation worked. It also quietly made the next implementation worse.

We usually call this technical debt, but that phrase is broad enough to hide the mechanism. In AI-assisted codebases, the more useful question is often not “Is this code bad?” It is:

What did this change teach the repository to become?

A helpful metaphor comes from an unexpected place: epigenetics. Your codebase may have something resembling an epigenome, not literally, but in the way inherited state influences what happens next.

Sequence of code modules showing a small implementation mark being inherited and amplified across later changes
A small implementation choice can become a precedent that future AI-assisted changes copy and amplify.

DNA is not the whole inheritance story

DNA is often compared to source code. It contains the genetic sequence an organism inherits.

But sequence is not the whole story.

Cells also contain epigenetic marks, such as DNA methylation. These chemical modifications can affect how genes behave without changing the underlying DNA letters.

A study published in Nature Genetics on May 20, 2026 examined how DNA methylation patterns were inherited across generations of mice. About 93% of the autosomal patterns identified followed familiar Mendelian rules. Roughly 7% followed non-Mendelian patterns.

The researchers also reported evidence of naturally occurring paramutation. In simple terms, paramutation is an unusual process where the state of one inherited version of a genomic region appears to influence the state of its counterpart. See the Nature Genetics article on non-Mendelian inheritance of DNA methylation patterns in mice.

This does not mean software behaves biologically. It does not justify broad claims about human traits, and it is not a reason to overfit biology onto code.

But it gives us a useful software question:

What gets inherited is not always limited to the main sequence.

Source code is not the whole codebase either

The source files describe what the application does, but future changes are influenced by more than the visible feature code.

They are influenced by:

  • folder boundaries and abstractions;
  • tests and what those tests fail to forbid;
  • naming conventions;
  • error-handling patterns;
  • database constraints and missing constraints;
  • build and deployment configuration;
  • linter exceptions and ignored warnings;
  • comments, prompts, and repository instructions;
  • duplicate implementations that look like accepted precedents.

Some of these inherited patterns are intentional. Others are residue from earlier work.

I think of their combined effect as the codebase epigenome:

The inherited collection of patterns, assumptions, and constraints that influences how future changes are implemented without being part of the product’s written requirements.

A ticket may say, “Add discount codes.”

The codebase epigenome tells the next agent whether discount calculations belong in a domain service, an API route, a frontend component, a database trigger, or all four.

AI agents inherit more than context

Human developers also copy existing code. We search nearby files, follow precedent, and imitate the project’s local style.

Coding agents do the same thing at greater speed and with less judgment about which precedent is intentional. When an agent explores a repository, it treats existing code as evidence. A workaround can look like an architecture. An untested branch can look intentionally unsupported. A duplicated validation rule can become the template for a third copy.

That is where rapid AI-assisted development can compound.

A 2026 study presented at the International Conference on Mining Software Repositories examined coding-agent adoption across open-source repositories. The researchers reported front-loaded development gains, especially when agents were the first observable AI tool used in a project. They also found persistent increases in static-analysis warnings and cognitive complexity, approximately 18% and 39% respectively in their analysis.

Static-analysis warnings are issues detected automatically without running the program. Cognitive complexity estimates how difficult code is for a person to follow. Neither metric is perfect, and the study does not prove that every coding agent makes every repository worse. It does suggest that faster output can leave behind conditions that affect later work. See AI IDEs or Autonomous Agents? Measuring the Impact of Coding Agents on Software Development.

Another preprint, posted June 19, 2026, tested what happens when coding agents perform a second task on top of earlier code. In some experimental settings, agents were up to 13.1% less successful when extending agent-written code than when extending human-written code.

Interestingly, conventional complexity measurements did not fully explain the difference. Subtler changes involving input validation and error handling were among the clearest signals. That paper is still a preprint, so treat it as early evidence rather than settled fact. See Is Agent Code Less Maintainable Than Human Code?.

The important question is no longer only:

Did the agent complete the task?

It is also:

What did that task teach the repository to become?

A feature can work and still leave bad inheritance

Imagine asking an agent to implement promotional codes.

The finished feature appears correct. Customers can enter a code and receive a discount. The tests pass.

But the implementation also:

  • repeats price-calculation logic inside an API route;
  • accesses the database directly instead of using the existing service;
  • catches every exception and returns HTTP 200 with an error message;
  • tests only the successful discount path;
  • introduces a new representation for monetary values.

None of those decisions necessarily breaks the first feature.

The problem appears when you ask for refunds, subscriptions, regional pricing, taxes, or multiple currencies.

The next agent searches the repository and sees the promotional-code implementation. It now has evidence that direct database access, duplicated calculations, and inconsistent error responses are acceptable.

The first feature did not merely add functionality. It changed the repository’s vocabulary of acceptable solutions.

That is inherited development state.

The dangerous marks are often small

The most damaging AI-generated changes are not always enormous architectural mistakes. They are often small marks that become precedents:

  • one try/catch that hides all failures;
  • one component that performs both rendering and business logic;
  • one temporary environment variable that becomes required in production;
  • one authentication check implemented differently from the rest;
  • one test that mocks the behavior it was supposed to verify;
  • one comment telling future agents to skip a broken test instead of repairing it.

Each mark looks manageable in isolation. The danger comes from repetition.

Once the same choice appears several times, both humans and agents begin treating it as the intended architecture.

Audit the inherited state before adding more features

Before asking an agent to implement the next major feature, inspect the last few AI-assisted changes and ask five questions.

What decision was duplicated?

Look for business rules, validation, database access, formatting, authorization, and transformations implemented in more than one place.

Duplication is not always bad. The dangerous version is duplication around decisions that must stay consistent under pressure: money, identity, permissions, ownership, subscription state, and user-visible failure behavior.

What behavior changed without becoming an explicit requirement?

Pay particular attention to defaults, fallbacks, error handling, authorization, and retry behavior.

An agent may make a test pass by changing what “success” means. That is not a harmless implementation detail if the new behavior becomes the next example copied across the app.

What architectural boundary was bypassed?

A feature may work while quietly routing around the service, domain, or data-access layer used elsewhere.

One bypass can be justified. Three bypasses become an architecture.

What did the tests fail to forbid?

Passing tests show that tested behavior works. They do not prove that important invariants were preserved.

For AI-assisted work, the more revealing review question is often: “What mistake could this implementation make while all tests still pass?”

What will the next agent copy from this implementation?

This may be the most useful question of all.

Imagine the next agent has no memory of your intent and only the repository as evidence. Which file will it imitate? Which shortcut will look official? Which weird response shape will become the template?

The goal is not to clean every file before making progress. It is to identify the inherited mark most likely to reproduce itself.

“Done” should include the next change

AI coding tools are usually evaluated one task at a time:

  • Did the build pass?
  • Did the interface appear?
  • Did the agent close the issue?
  • Did the tests turn green?

Those checks matter, but mature software is not a collection of isolated tasks. Every change becomes the environment for the next change.

A feature is therefore not fully successful merely because it works today. It should also leave the system understandable, testable, and safe to extend tomorrow.

That does not require perfect code. It requires resisting patterns that spread silently.

Before asking AI to add one more feature, ask what the previous feature taught the codebase.

You may discover that the next thing your app needs is not more generated code. It is the removal of one inherited assumption that should never have become a convention.


Is your Bolt, Lovable, Cursor, or Claude Code app working, but becoming harder to modify safely? A Code Rescue Audit examines not only visible bugs, but also duplicated logic, fragile architecture, missing validation, deployment risks, and other inherited patterns that can block a reliable launch.

Sources and further reading

Leave a Reply

Your email address will not be published. Required fields are marked *