Architecture Drift in AI-Assisted Codebases
AI agents bypass architectural rules unless constraints block noncompliant changes.

Architecture drift in AI-assisted codebases is a structural problem. Agents do not remember a team’s module boundaries, layering rules, or deliberate tradeoffs across sessions unless they are given that intent. Functionally correct code can therefore diverge from the intended design by default. Preventing that divergence requires architectural constraints that block noncompliant changes, supported by scoped context before generation.
Why AI-driven architecture drift is categorically different from the drift teams already know
Human developers internalize conventions over time, even though deadlines and incomplete knowledge can lead them to break those conventions. An agent has no equivalent continuity at the session boundary. Unless it is given architectural context, it starts without knowing what the team has decided about dependencies, ownership, or separation of responsibilities. Its violation of a boundary is therefore not evidence of laziness or disregard for the design. The architecture was absent from the information available to it, which makes drift a predictable consequence of the interface between the architecture and the codebase.
Giving the agent the entire repository does not resolve that mismatch. Grabowski’s The Spec Growth Engine names context explosion as the failure in which an agent conflates concerns from unrelated modules, and silent spec-code drift as the failure in which implementation changes without corresponding specification updates. Agent scope creep compounds both problems by modifying files outside the requested task and crossing boundaries no reviewer expected to examine. The developer is left choosing between supplying everything and guessing which fragments matter, unless context can be scoped by an explicit ownership rule. Graphide treats the architecture graph as live, enforceable constraints rather than documentation, addressing the same structural need that motivates spec-coupled drift gates and dependency assertions.
How to detect when AI-generated code is diverging from the intended architecture
The clearest signs often lie in how files relate to each other, even when there are no defects within a function. Consider a staff engineer’s PR with 340 lines of clean code and tests that pass. The implementation writes directly to the customer table, bypassing the customer service API. That shortcut also bypasses the API’s audit hooks, violating an architectural decision that banned direct database access.
The distinction matters because this is not a hallucination or a model-quality failure. The ADR existed in the repository and accurately recorded the decision, but neither the agent nor the reviewer encountered it. The missing element was organizational memory made available at the point of implementation and approval. Reviewing the database write in isolation could establish that it worked while missing why it was prohibited. Detecting the drift requires comparing the implementation’s dependencies with the intended boundary.
Kashif et al.’s study of AI-generated large-scale projects provides structural corroboration. It identifies prevalent issues including Code Duplication, high Code Complexity, Large Methods, Framework Best-Practice Violations, Exception-Handling Issues, Design Principle Violations, and Accessibility Issues. These findings show why functional correctness cannot stand in for design quality, particularly where code violates SRP, Separation of Concerns, or DRY without breaking a test. Optimization within the visible task can leave the whole design unprotected. A live, navigable map of call relationships and module boundaries, as provided by Graphide, makes cross-file violations visible at the level where they occur rather than leaving them scattered across individual diffs.
How agent-generated volume makes drift invisible to the review process that's supposed to catch it
As agents make more changes, it gets harder to keep that cross-file view. Architectural review requires understanding not only what changed, but which contracts and ownership boundaries those changes affect. When a diff grows beyond what a reviewer can reason about across files, attention shifts toward local correctness. The reviewer then repeats the kind of judgment the agent already made, checking that the implementation works while overlooking whether its dependencies are allowed. This is a mismatch between the task and the available review capacity.
Faros AI’s 2026 report, based on telemetry from thousands of developers across thousands of teams, found sharply rising AI-code acceptance rates together with increased code churn. Churn counts lines deleted within days of being added, so it shows how much code enters the repository but does not stay there. Faros AI cautions that churn can include productive refactoring. It is not a direct measure of architectural damage. More accepted code does not, by itself, establish that the code fits the system.
The customer-table scenario illustrates how volume interacts with a separate weakness in review, namely the loss of architectural memory. The reviewer was three months into the team, while the violated decision was two years old and its author had left. The relevant document lived outside the workflow, so approval depended on knowledge the reviewer did not have. Grabowski’s paper describes how a specification becomes a historical artifact while future agent runs continue to rely on it. Passing tests leave the divergence unflagged, and review alone cannot reliably restore the missing connection between intent and implementation.
Why soft conventions — ADRs, context files, prompt instructions — cannot hold the design alone
Architecture Decision Records, AGENTS.md files, and prompt instructions help make that missing connection by giving the agent access to intent. AGENTS.md is a genuine and widely adopted improvement over expecting an agent to infer every convention from implementation. Its architectural role can vary: it can serve as the governance document itself, a pointer to governance elsewhere, or a hybrid of the two. That ambiguity affects what the agent receives, but even a clear and complete file provides instructions without enforcing them.
The decisive test is what happens when generated code contradicts the instruction. An agent may read a constraint in AGENTS.md and then receive a prompt that conflicts with it. The document has no outside check that forces the resulting change to follow the constraint. Likewise, a correctly formatted ADR does not stop a prohibited dependency from entering the repository. Better documentation improves the chance of compliance, but its existence does not make noncompliance a blocking event.
Grabowski’s paper expresses this distinction through the terms “spec-anchored” and “drift-enforced”. That model needs a specification for every node, but it also needs divergence to become a blocking merge error. Any approach that depends only on an agent honoring instructions or a reviewer noticing a violation produces probabilistic compliance. Structural compliance begins when a defined violation prevents the merge, without requiring anyone to remember the rule at that moment.
What mechanical enforcement of architectural constraints actually looks like in practice
Mechanical enforcement starts by expressing a decision in a form that a CI gate can evaluate deterministically. A rule such as “no service in the payments domain may import directly from the user profile domain” defines a prohibited relationship. ArchUnitTS applies this pattern in TypeScript by turning architectural rules into assertions that the pipeline runs on changes. The rule no longer depends on the author’s familiarity with the system or the reviewer’s memory. Its force comes from the merge condition attached to the assertion.
A report can identify a forbidden dependency and still allow that dependency to ship. A warning can be accurate, useful, and routinely overlooked without changing the outcome of the pipeline. Enforcement means that the architectural check exits non-zero on a violation and blocks the merge. The important criterion is therefore not whether a tool can display drift, but whether the workflow refuses the change when the defined constraint fails.
At the graph level, Graphide’s gr check verifies the repository’s living architecture graph and can run as a CI gate. ArchUnitTS illustrates enforcement through dependency assertions, while Graphide applies the principle through the architecture graph. These are concrete ways to move cross-file boundary checking out of the reviewer’s memory and into the pipeline. The human reviewer can then examine the meaning of a change without being the sole mechanism protecting every encoded boundary.
Grabowski’s Spec Growth Engine proposes blocking a merge when there is spec-code divergence, with code and specification changing together in the same commit. Its status as a proposal matters, but the enforcement principle is clear. A specification that can silently fall behind the code cannot remain a dependable source of architectural intent.
Feeding architectural intent into the agent before it writes, not just checking after it finishes
A merge gate protects the repository, but it acts after the agent has already produced a change. Upstream controls tackle the earlier failure by giving the agent the right architectural context before it starts to generate code. The goal is enough context to understand what the component is responsible for and which dependencies it is allowed to have, without inviting changes to unrelated modules. This makes context selection an architectural operation rather than a search for whichever files appear relevant to the prompt.
The Spec Growth Engine’s Spine assembler makes that selection through an ownership path. It limits context to the path from the repository root to the component under development, together with the contracts of declared dependencies. The agent receives a principled subset of the repository instead of everything or a manually guessed selection. That scope addresses context explosion while reducing the opportunity for unrequested global fixes. It does not eliminate the need to check the generated change, because supplying the right boundary and enforcing that boundary remain different operations.
AWS Kiro’s spec-driven IDE addresses the same blank-context problem by codifying architectural intent before generation. Grabowski’s paper places its approach between spec-first development, where full specifications come before code, and spec-as-source systems, where generated code depends on a single point of truth that could be fragile. Its “lean middle ground” keeps code and specification evolving in the same commit. Constitutional constraints provide a related way to encode rules that generation must satisfy. Constitutional Spec-Driven Development research found a 73% reduction in security defects compared with unconstrained generation while preserving velocity, although that finding should not be treated as a measured reduction in architecture drift.
At the workspace level, developers can use Graphide’s gr init and graph-based planning interface to direct agent work through the component boundaries represented in the architecture graph. Context scoping limits what the agent needs to take into account, spec coupling keeps intent in step with implementation, and enforcement gates block changes that meet the definition of divergence. These controls complement one another because they act at different points in the workflow.
What the developer's job becomes when the architecture enforces itself
Once encoded constraints protect the architecture, the developer spends more of the work deciding what those constraints should mean. A failed gate still calls for a decision: the code is wrong, the rule is wrong, or the architecture has legitimately evolved. That decision depends on system-level understanding. Engineers risk becoming able to generate code without being able to debug or reason about it. Developers should preserve that judgment by applying it where it governs many changes, moving beyond line-by-line inspection for the same recurring violation.
Grabowski’s paper frames this role as authorship of the spec graph, including module contracts, ownership paths, and the growth protocol within which agents operate. The developer owns intent, the agent implements within it, and the drift gate protects the encoded agreement. Organizational maturity then depends less on how much autonomy an agent receives than on the feedback loop through which its work is measured and governed. Architecture remains a human responsibility, but its routine protection no longer depends on human recollection. Developers who can encode constraints precisely and steer architectural evolution become more valuable in an agent-assisted codebase.


