A staff engineer named Priya opened a 340-line pull request that added an endpoint which wrote directly to the customer table, bypassing the internal customer service API. The code was clean, tests passed, and the AI coding agent that produced it had been the team’s most productive contributor for six months. A reviewer who had been on the team for three months approved the change, and the PR shipped that afternoon.
Two weeks later, during an integration debugging session, someone noticed that customer records created by that endpoint lacked audit-log entries. The audit hooks live in the customer service API. Two years earlier the team had banned direct database access for precisely this reason and recorded the rule in an Architectural Decision Record (ADR) — a versioned markdown document that captures what was decided, why, and what was superseded. The engineer who wrote the ADR had left; no one on the current team remembered the decision, and the document sat in a directory the current workflow never touches.
The endpoint was rewritten, audit gaps were backfilled, and the team spent most of a sprint cleaning up. Nobody called this an AI-assisted development failure: the AI wrote functional code. It simply wrote code that violated a prior architectural decision that neither the AI nor the reviewer had seen.
Not a hallucination or model-quality problem
This failure mode is not a hallucination: the output was grounded, syntactically valid, and idiomatic. It’s not primarily a model-quality issue either, because a better model on the same prompt wouldn’t necessarily help if the relevant decision never appeared in its context. The issue is memory — not the model’s context window per se, but organizational memory. The ADR existed in the repository, but it was never surfaced to the agent and the reviewer hadn’t read it.
Quantitative signal: Faros AI’s 2026 report
Priya’s PR exemplifies one source of rework. Faros AI, an engineering analytics platform, published a report in 2026 based on telemetry from more than 22,000 developers across over 4,000 teams. The report found AI-code acceptance rates rising from 20% to 60% between periods of low and high AI adoption, while code churn (lines deleted within days of being added) increased 861% in the same interval.
Faros is careful about interpreting the churn figure: the increase can include productive refactoring, previously unaffordable cleanup, or faster iterative improvement. Still, the number exposes a gap between code entering the repository and code that survives there — a gap that has widened, at scale, alongside AI adoption. Engineers anecdotally report returning to code they had previously approved to fix issues that weren’t obvious during review. Architectural drift — code that individually looks fine but collectively pulls the codebase away from the team’s agreed direction — is a plausible contributor.
I will call the discipline of preventing this failure mode "architectural drift prevention": keeping generated code aligned with the architectural decisions a team has already made.
Why existing tools sit at the wrong layer
Teams commonly reach for several existing mechanisms to close this gap. Most are the wrong shape for the problem.
- Free-text files like Cursor Rules or CLAUDE.md are often dropped into the project root for agents to read as standing instructions. The instinct is right but the resolution is wrong: free text has no precedence rules, no versioning, and no lifecycle. When rules conflict nothing arbitrates; when a rule is violated nothing catches it.
- Linters and formatters operate a layer below. They enforce syntactic properties — return type annotations, naming conventions — but cannot enforce that customer-data writes must flow through the customer service API because that’s a semantic, architectural rule, not a syntactic one.
- Dependency scanners, SCA tools, and lockfile audits address vulnerabilities, license issues, and outdated versions. Priya’s PR would have flagged nothing: dependencies were current, had no known vulnerabilities, and were approved. The violation was a routing choice inside the team’s architecture, not a library problem.
- LLM-assisted code review is fashionable: a second AI reads the pull request and comments. That can catch surface issues like swallowed exceptions or off-by-one errors, but it doesn’t solve drift because the second AI shares the same blind spot as the first: neither has durable access to the team’s recorded decisions. Two probabilistic passes over the same blind spot aren’t equivalent to one deterministic pass with sight.
- Human review is the last line and it works when the reviewer knows the history and has time. Agentic development changes both conditions: agents can produce multiple implementations, pull requests, and revisions in the time it takes a human to assess one. Code output scales; review attention does not. Asking humans to compensate simply moves the bottleneck downstream.
None of these tools are bad; they’re just the wrong layer for the drift problem.
What the missing layer must do: engineering governance
The missing layer must connect recorded engineering decisions to the tools that generate, review, and merge code. Its job is to make a team’s accumulated architectural decisions machine-readable, retrievable, injectable, and enforceable. Call this layer engineering governance, analogous to data governance or security governance: a structured way for an organization to make explicit and enforceable the rules it already implicitly follows.
At the shape level the layer needs to do four things:
- Store decisions in a structured corpus with precedence and lifecycle metadata so a tool knows which ADR wins when two conflict and which decisions are still active.
- Retrieve reliably from that corpus so the same code produces the same set of relevant decisions each time.
- Inject those decisions into the AI’s context before the agent writes code so the output accounts for them rather than needing to be caught after the fact.
- Enforce them in continuous integration, blocking or flagging code that violates them, with the verdict traceable to a specific ADR, a specific term that matched, and the rule text.
The critical property tying these together is discipline about where probabilistic reasoning is allowed. Probabilistic systems may retrieve or recommend, but they shouldn’t independently determine an enforcement verdict. Every block or warning must be reconstructible from artifacts on disk: the code, the ADR, the retrieval log, the rule text. Then, when a developer asks “why did this fail?” or an auditor asks “on what basis?”, the answer isn’t “the AI said so.” That determinism is what makes the layer defensible in regulated environments, compliance reviews, incident retrospectives, and everyday discussions where an engineer has to justify a blocked merge.
AI can help surface relevant decisions, but it should not be the final authority. The enforcement path must remain deterministic and reproducible.
Defining boundaries: what engineering governance is not
To be clear about the category, engineering governance is not:
- An agent: no autonomy or iterative decision-making. The layer runs when called, produces a verdict, and stops.
- Merely retrieval-augmented memory: retrieval methods may be probabilistic, but the enforcement verdict cannot be. The corpus of decisions is the source of truth.
- AI-reviewed code: a second model reviewing generated code doesn’t address the root cause — the first model lacked access to the team’s decisions.
- Vendor-locked: production teams increasingly run Cursor, Claude Code, GitHub Copilot, and Codex in parallel, and may also use open-weight or self-hosted models for sensitive codebases. Engineering governance must remain independent of both the coding tool and the underlying model so the same architectural decisions and deterministic enforcement apply across them all.
The emerging stack and why it matters to every team
The AI coding stack is assembling itself in the open without a single architect. Major coding assistants are specializing on different parts of the loop — editing, autonomous execution, review, planning — but the stack still lacks engineering governance.
The need isn’t limited to regulated industries. Any team that values reliable engineering, long-term product quality, and customer trust needs assurance that generated code respects the decisions the system depends on. In higher-risk contexts this requirement becomes formal and auditable; elsewhere it’s part of responsible software engineering. In both cases the enforcement path should be deterministic and traceable, with rules, evidence, and verdict open to inspection rather than hidden inside another model or a proprietary black box.
Actions for engineering leaders this quarter
Priya’s PR is a pattern, not a one-off incident. Three practical steps to take this quarter regardless of tooling choices:
- Audit your Architectural Decision Records. Are they current? Do they explicitly name what they replace? If your team doesn’t write ADRs, start now; emerging tooling assumes structured architectural decisions as input.
- Choose an enforcement posture deliberately. Should the system warn developers and allow continuation, or block changes until issues are resolved? Both approaches work, but the team should agree which applies instead of leaving it to individual developers or PRs.
- Don’t assume a more powerful model will fix this. Better models can improve generated code, but they still won’t follow architectural decisions they haven’t been given. Preventing architectural drift requires changing the surrounding system, not just waiting for the next model.
The productivity gains from AI-assisted development are real and worth preserving — as is the architectural coherence teams have built over years. Engineering governance is the layer that lets you keep both.



