跪拜 Guibai
← All articles
Frontend · AI Programming

AI Writes the Code, You Build the Cage

By 玄星啊 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

As AI coding tools become the default, the bottleneck moves from typing speed to architectural judgment. A developer who cannot define module boundaries and failure domains will ship faster but break production more often, because AI optimizes for the happy path and has no model of implicit context or blast radius.

Summary

A production outage traced to a missing ErrorBoundary exposes a pattern: AI-generated code works on the happy path but silently omits failure isolation, and developers reviewing it often lack the mental model to spot the gap. The incident forces a return to first principles of software complexity. Accidental complexity—language quirks, type-runtime mismatches, implicit coercion—still demands human muscle memory during review; AI cannot perceive the danger. Essential complexity—the tangled business rules, historical compromises, and implicit context of real systems—leaks when modules lack clear boundaries, and AI only amplifies the mess.

The core discipline shifts from writing code to defining change boundaries. Modules should be grouped by why they change, not by superficial similarity. Interfaces exist primarily to isolate and contain complexity, not for reuse; reuse is often a premature bet. A five-layer boundary framework—business, change, data, interface, and failure—keeps complexity from leaking across modules. The hard rule that follows: never merge code you cannot read and explain, because incomprehensible code is a signal that complexity has escaped its cage.

Takeaways
AI-generated code frequently omits error boundaries and failure isolation, causing local errors to crash entire applications.
Accidental complexity—like TypeScript's type-runtime mismatches and JavaScript's implicit coercion—still requires human recognition during code review; AI is blind to these risks.
Essential complexity from tangled business rules and historical compromises cannot be delegated to AI, which only enlarges an already incomprehensible codebase.
Modules should be grouped by their reason for change; binding things that change for different reasons guarantees future contamination.
Interfaces exist primarily to isolate and contain complexity, not to enable reuse—reuse is often a premature and wrong bet.
A five-layer boundary framework—business, change, data, interface, failure—prevents complexity from leaking across a system.
The non-negotiable rule is to never merge code you cannot understand; illegible code means complexity has not been contained.
Conclusions

AI coding tools invert the traditional skill stack: the premium skill is no longer writing code but reading it critically and spotting what is absent.

The happy-path bias of AI-generated code makes manual testing less reliable, because the developer's mental model is shaped by the code they would have written, not the code the AI actually produced.

Calling interfaces a reuse mechanism gets the priority backwards; their real job is to create a firewall so that a change in one module cannot cascade into others.

Low coupling is not an aesthetic preference—it directly reduces the mental burden of reasoning about a system, which is the scarcest resource on a team.

The five-layer boundary framework is effectively a checklist for whether complexity is caged: if any layer is fuzzy, the system is already leaking.

Refusing to merge incomprehensible code is a forcing function for architectural discipline; it stops AI from accelerating entropy.

Concepts & terms
Accidental complexity
Complexity that arises from the tools, languages, or frameworks themselves rather than from the problem domain—such as TypeScript type-runtime mismatches or JavaScript implicit coercion. It can be reduced with better tooling and disciplined review.
Essential complexity
Complexity inherent to the business problem itself—payment flows, permission systems, historical data compatibility. It cannot be eliminated, only contained within well-defined module boundaries.
ErrorBoundary
A React component that catches JavaScript errors in its child component tree, logs those errors, and displays a fallback UI instead of crashing the whole application. A missing ErrorBoundary lets a single component failure propagate globally.
Dependency Inversion Principle
The 'D' in SOLID: high-level modules should not depend on low-level modules; both should depend on abstractions. In practice, modules depend on interfaces rather than concrete implementations, so implementation changes do not cascade.
Change boundary
A design heuristic: group code by the reason it would change. Two pieces of logic that change for different business reasons belong in separate modules, or future edits will pollute each other.
From the discussion

The lone comment suggests a pragmatic, iterative approach: continue using AI coding tools until the failure-boundary problem is understood well enough to solve, then document the solution. No competing views or deeper technical arguments surfaced.

Keep using AI assistance and address the fragility problem through direct experience rather than avoidance.
Featured comments
用户1408486877502

Suggestion: keep using it until you can solve this problem, then write another article [thinking]

See top comments, translated →
Source: juejin.cn ↗ Google Translate ↗ Backup ↗