Essential Complexity

Modernizing high-risk systems in the age of AI.

4 min read

The Guardrail Is the Architecture

Most of what is marketed as agentic guardrails is quality gates. Quality gates operate on output. Guardrails constrain the system itself.

The Guardrail Is the Architecture
Joe Leo
Joe Leo

Founder, Def Method

In my last two articles, I argued that the right response to AI-generated code is containment architecture, not more review. Limit how far a failure can travel and treat blast radius as a design decision. A movement is forming around guardrails for agentic coding. These are automated constraints that sit between the agent and production and decide what ships. The questions being asked are the right ones. But the answers, so far, are mostly tooling dressed up as architecture.

What Guardrails Actually Mean

A guardrail is not a quality gate. A quality gate is a check that runs on output. A guardrail is a constraint on the system itself. The difference is the same one between a speed bump and a road that physically cannot be taken above 25 miles per hour. One relies on the driver to respond. The other makes the response automatic.

Most of what is currently marketed as agentic guardrails is quality gates. Code coverage thresholds; complexity scores; static analysis results — these are useful, and teams should run them. But they operate on output, after the agent has already made decisions about structure, dependencies, and scope. If the agent produces a plausible-looking feature that passes coverage checks while quietly importing three new gems, introducing a callback that touches your billing model, and making an assumption about transaction ordering that conflicts with a background job running in production, the gate will pass and the risk will ship.

The Rails community has been wrestling with this longer than most. Planet Argon has documented what they call "codebase drift" in AI-assisted Rails applications: agents accumulate architectural decisions over time, none of which break immediately, all of which compound. Service objects appear inconsistently. Callbacks multiply. Six months later, reviews take longer, onboarding slows, and developers hesitate before touching older areas because the architecture no longer feels internally consistent. No threshold on cyclomatic complexity catches that. Drift is a structural failure that quality gates are not designed to detect.

The Measurement Impulse

Bob Martin sparked a productive argument in April when he posted that developers should stop reading AI code line by line and start measuring it instead. The Codeminer42 team turned it into a concrete Rails playbook: a single rake task that runs coverage, complexity, and mutation scores against configured thresholds and exits non-zero if any gate fails. The AI either clears the bar or it doesn't.

Mutation testing is the closest thing to a real guardrail in the current toolkit. It doesn't ask whether tests run. It asks whether tests catch failures. Apiiro's research found that nearly half of AI-generated code introduces behavior that existing tests do not adequately cover. Mutation testing surfaces exactly that failure mode. But it is still a post-generation check. It validates that output is tested. It does not constrain what the agent is allowed to generate.

The Scope Problem

The harder problem is scope. Agentic coding tools do not just write code. They make decisions about what code to write. They choose abstractions, select dependencies, determine where logic lives. Those decisions accumulate across sessions, invisible to any single reviewer looking at a diff, and they determine whether the system is maintainable six months from now.

The Gurzu team described it precisely in their work rescuing a vibe-coded Rails application: the product looked fine, had paying users, was shipping features. The codebase told a different story. What saved it was not better tooling. It was realignment with Rails conventions, which "act like guardrails" because they encode where logic belongs and how components should relate to each other. Convention over configuration is, at its core, a containment mechanism. A controller that follows Rails conventions has a predictable structure and a bounded scope. A controller the agent has decided to make "more flexible" is an ungoverned blast radius waiting to be discovered.

What This Means for Engineering Leadership

Architectural guardrails look different from quality gates. Scope before execution: the agent receives a bounded spec that defines what it is allowed to touch, not just what it should accomplish. Least privilege at the tool layer: an agent fixing a view template does not need write access to your schema. Convention enforcement as a structural gate: checking not just whether the code works, but whether it is in the right place.

These are containment decisions, not performance optimizations. Most teams have invested in measurement and treated the rest as a tooling problem, when in fact it is a design problem. What can your agent decide on its own? What does it require explicit authorization to do? Where are the boundaries that force it to operate within the structure of your system rather than around it?

If you cannot answer those questions, you have quality gates, not guardrails. The guardrail is the architecture. The only question is whether you designed it deliberately, or whether you're discovering it by finding out what failed.

Ready to modernize your Rails system?

We help teams modernize high-stakes Rails applications without disrupting their business.

If this was useful, you might enjoy Essential Complexity — a bi-weekly letter on modernizing high-risk systems in the age of AI.