A repository is a training signal
Every codebase teaches. An agent asked to add a feature looks at how similar things are already done and follows that. On a healthy codebase this is the behaviour you want, and it is most of what makes coding agents useful. Consistency with the surrounding code is a reasonable proxy for correctness.
A migration breaks the proxy. For the duration of the project the repository demonstrates two architectures, and it demonstrates the one you are removing far more thoroughly, because that one has been accumulating for years and the replacement has existed for months.
The dominant pattern in a repository may be precisely the pattern you are trying to remove.
This is not a memory failure
It is tempting to file this under context loss. The agent forgot the migration plan, so remind it. That diagnosis leads to the wrong fix, because the agent is not failing to recall anything. It is reasoning correctly from evidence that is genuinely present in the repository.
Consider what the agent can actually observe. Two hundred call sites use direct database access. Twenty use the repository abstraction. Both compile. Both pass tests. Both were written by employees of the same company. Nothing in the code marks one as historical. The inference that the majority pattern is the house style is not a hallucination. It is a sound reading of the available evidence.
The information that would change the conclusion is not in the codebase at all. It is a decision, made once, that the twenty are the future and the two hundred are debt. That fact has no representation in code, which is why no amount of code-reading recovers it.
Better retrieval makes it worse
The intuitive fix is to give the agent more of the codebase. Larger context windows, better indexing, more thorough semantic search. During a migration each of those improvements strengthens the wrong signal.
A weak search returns a handful of examples, and the agent may happen to draw from either architecture. A thorough search returns a representative sample, and a representative sample of a mid-migration repository is mostly legacy. The retrieval system is working exactly as designed. It surfaces what is there, and what is there is the architecture you are leaving.
This is the specific sense in which migration is a governance problem rather than a context problem. No improvement to recall changes the ratio.
Three ways the old pattern gets in
The failure is rarely a single dramatic mistake. It arrives through ordinary, defensible-looking moves.
- Direct imitation. The agent finds the nearest similar function and mirrors its structure. This is the common case and the easiest to spot in review, though only if the reviewer knows which side of the migration the file sits on.
- Consistency reasoning. The agent notices that a file already contains legacy-style calls and matches them deliberately, on the grounds that mixing styles within one file is worse than following the local convention. That argument is usually right. During a migration it is precisely wrong, because the mixed state is the intended transitional condition.
- Test-shaped imitation. Existing tests are written against the legacy structure. An agent working toward passing tests infers the architecture from the fixtures and mocks it has to satisfy, and reproduces it faithfully.
The third is the most durable, because the tests keep teaching the old shape long after the source has moved on.
Why review does not catch it
A reviewer looking at a diff sees a function that follows the conventions of the file it sits in. Nothing about it looks wrong. Determining that it is wrong requires knowing that this particular module was migrated in March, that direct persistence access was superseded for migrated modules, and that the file's remaining legacy-style neighbours are themselves scheduled for removal.
That knowledge is per-path, changes over the life of the project, and is held by a small number of people. Expecting it to be applied consistently across every diff produced by agents working at machine speed is not a realistic control.
The result is that migrations regain ground slowly and lose it quickly. A component gets migrated once, deliberately, by someone who understood the target. It then accumulates new code from agents that read only the local evidence.
What actually separates the two architectures
The difference between the legacy pattern and the target pattern is not a property of the code. Both are valid code. The difference is a decision about which one survives, and decisions have to be recorded somewhere an agent is checked against rather than somewhere it might read.
That recording needs three properties to be useful during a migration. It has to be explicit, so the target is stated rather than inferred from counting. It has to be scoped, so the rule that governs migrated modules stays silent in the tree that has not moved yet. And it has to be evaluated at the moment the agent acts, because a document the agent never opens constrains nothing.
The agent is not misreading the repository. It is reading it correctly, and the repository is a record of the past.
The practical consequence
Teams running migrations with coding agents usually discover this the same way. The migration's completion percentage stops moving, or moves backwards, while activity stays high. Individual pull requests all look fine. The aggregate effect is that migrated components are quietly reacquiring the structure they were migrated out of.
The fix is not to slow the agents down or to keep them away from the migration. It is to make the distinction they cannot infer available to them as an enforceable constraint, scoped to the paths where it applies.