Concept
Architecture drift
Architecture drift is the gradual divergence between a system's intended structure and its real one, accrued through changes that each looked reasonable alone.
The shape of the problem
Nobody decides to degrade an architecture. Drift is the sum of changes that were each locally reasonable.
A developer needs a token cache and writes one. Six weeks later somebody else needs a token cache, does not find the first one, and writes another. Neither change is wrong at review time — each is a small, sensible addition that passes review because the thing it duplicates is not in the diff.
Twelve months later the authentication domain has three token abstractions, two session managers and four cross-domain dependencies, and the honest description of how it got there is "one PR at a time".
Why agents accelerate it
This is not a new phenomenon. What is new is the rate.
An agent creates files very easily and has no memory of your codebase's history. It does not know that this argument was settled two years ago, that this domain does not call that one, or that the abstraction it is about to write already exists under a different name. Given a problem, it writes a reasonable solution to that problem — which is exactly the behaviour that produces drift, performed faster than a team of humans could.
The result is that a codebase can accumulate in three months the structural debt that used to take three years, while every individual pull request still looks fine. That is the whole difficulty: drift is invisible at the granularity review operates at.
The signals worth tracking
Drift is not directly measurable, but a small number of structural properties correlate with it and are computable from the code:
- Coupling — how many cross-component dependencies exist, and whether that number is growing faster than the code.
- Overlapping abstractions — several names in one domain doing recognisably
the same job.
TokenManager,TokenService,TokenHelperis the canonical smell. - Dependency depth — how many hops a request travels. Depth growing from 3 to 6 means every change now reaches further.
- Public interface growth — how much surface a component exposes. A component whose exports keep growing is one that is becoming everybody's dependency.
- Component count within a domain — a domain that went from four modules to eleven without a corresponding increase in what it does.
None of these is a verdict. Each is a number whose trend is the signal, which is why drift can only be seen across many changes and never within one.
Why a small set of signals, and interpretable ones
The temptation is to compute a score. Resist it: a single "architecture health: 64" number is unactionable and, worse, unfalsifiable — nobody can check it, so nobody can disagree with it, so it changes no decisions.
Five interpretable signals with visible definitions are more useful than one composite, because a reviewer can look at "three token abstractions detected" and either fix it or decide it is fine. That is a real decision. "Your score dropped four points" is not.
What honest tracking requires
Measuring drift means keeping the structural shape of each merged change and comparing shapes over time. That is a different capability from analysing one pull request, and it needs history rather than a single diff.
Worth being explicit, since this page could otherwise be read as a product claim: Cutplane today analyses one change at a time and does not yet track drift across merged pull requests. The per-change analysis is what ships; the cross-change trend is the direction, and saying so is cheaper than being caught overstating it.
Related
- Architecture diff — the per-change unit drift is measured in.
- Change impact analysis — how far a single change reaches.
- Claude Code vs Cursor vs Codex — the shared failure mode.
← All concepts