October 13, 2026
A passing test tells you the destination was reached. It says nothing about whether the path there made architectural sense, and that gap is where AI-generated code quietly accumulates debt.
The Details:
When a human developer skips a service layer and hits the database directly, the shortcut reads as a visible choice, something a reviewer can question. When AI does the same thing, it looks like plumbing rather than a decision, because the model simply followed the path of least resistance to satisfy the test in front of it. Nothing flags it as a judgment call, so nothing gets questioned.
The model isn't choosing badly; it's choosing locally, with no visibility into the larger system. It optimizes for the immediate task and produces clean, confident code that is reasonable in isolation and wrong for the system it joins. By the time that routing surfaces in review, it's often already load-bearing, so removing it feels like a rewrite nobody wants to do.
Catching this in code review rarely works, because a line-by-line diff isn't built to detect a boundary crossing. The fix has to happen before generation: a short document, half a page, naming layers, dependency direction, and ownership. Phrase constraints as refusals rather than suggestions. "Handlers never import directly from the data layer" closes a door; "handlers should generally use the service layer" leaves too many open.
The best boundary documents stay honest by moving with the code. When a developer needs to cross a boundary, the pull request updates both the rule and the check together, with a reason attached. That keeps the document from becoming a stale fence nobody enforces, and it keeps the automated guardrail aligned with what the team actually allows.
Bottom Line: Working software proves you arrived; it never proves the route was right, so the boundaries have to be set before generation, not discovered after.
Enjoy this article?
Listen to the Claude Code Conversations radio show or join the community.