Atlas / BUILD / AI Engineering / Vibe vs Production
DEEP-DIVE · AI ENGINEERING

From Vibe Coding to Production

Vibe coding, building software by loosely prompting AI, is a genuine superpower for prototypes and a genuine liability when the prototype ships as production. The line runs through blast radius and longevity.

TL;DR
  • Vibe coding, building software by loosely prompting AI without much engineering rigor, is genuinely excellent for prototypes, spikes, internal tools, and exploration. The failure is not the practice; it is shipping the prototype unchanged as a production system.
  • The gap to production-grade is concrete: tests, error handling, security, observability, performance, and maintainability, plus the underrated risk of shipping code the team does not understand and cannot debug under pressure.
  • Draw the line by blast radius and longevity, harden with tests, human review, security scanning, error handling, and observability, and make that hardening the paved road so a flood of un-hardened AI-built software never becomes the organization's liability.

What vibe coding is

Vibe coding is building software by loosely prompting an AI and steering by feel: describe what you want, run what comes back, nudge it when it is wrong, and keep going until the thing behaves. There is no upfront design, little structure, and often no close reading of what the model produced. The measure of progress is whether it works right now on the screen in front of you. For a large and growing class of problems, this is remarkably effective, and pretending otherwise is not sophistication, it is denial.

What makes it powerful is that it collapses the distance between an idea and a running artifact. A question that used to take a day of scaffolding, wiring, and boilerplate before you could even see whether the concept held now takes minutes. You can try five approaches in the time it once took to set up one. For prototyping, for exploring an unfamiliar API, for answering "would this even work," the loop is a genuine superpower. The rigor you would normally invest is exactly the rigor a throwaway artifact does not need, and skipping it is the correct call.

The risk lives entirely in what happens next. The same properties that make vibe coding excellent for exploration, speed over structure, output over understanding, working-now over correct-always, are precisely the properties that make it dangerous when the prototype is quietly promoted to production without anyone deciding to promote it. The demo impressed someone, the deadline arrived, and the exploratory artifact became the system of record. Nothing about the code changed; only the stakes did. This deep-dive is about that transition, and it is emphatically not an argument against the practice. It is an argument for knowing which side of the line you are on and hardening deliberately when you cross it.

The gap to production

"It works on my machine" and "it is safe to run in production" are separated by a set of properties that a vibe-coded prototype almost never has, because acquiring them is exactly the work the practice skips. The prototype demonstrates that a happy path exists. Production is the promise that the system behaves acceptably when the path is not happy: when input is malformed, when a dependency is down, when load spikes, when an attacker probes, and when someone six months from now has to change it. None of that is visible in the demo, which is why the demo is such a misleading signal of readiness.

The gap is specific enough to enumerate, and naming it is the first step to closing it deliberately rather than discovering it in an incident.

A prototype is not a product. The two look identical on the screen, which is the entire trap. A prototype answers a question, "is this possible, is this worth building," and its job ends the moment the question is answered. A product carries an obligation to keep working under conditions the prototype was never exposed to, for people who did not write it and cannot forgive it. Treating the first as the second because it happens to run is the single most expensive shortcut in software, and AI has made it far easier to take by accident.

Code nobody understands

Every gap in the previous section is a known category of engineering work, and each has a known fix. The problem that gets underrated is subtler and, at scale, more corrosive: with vibe coding you can ship a substantial system that no one on the team wrote and no one on the team understands. The code runs, so the absence of comprehension is invisible, right up until the day it matters most.

That day is an incident. Something is failing in production, customers are affected, and the on-call engineer opens a codebase they have never read, generated by a model in a session no one kept, structured according to no design anyone chose. Debugging is applied understanding, and there is nothing to apply. You cannot reason about a system you never internalized; you can only prompt the model again and hope its second guess is better than its first, under exactly the time pressure that makes hope a poor strategy. The velocity that felt like leverage during the build has become a debt payable at the worst possible moment.

The reframe worth internalizing is that comprehension is itself a hardening step, not a nicety layered on afterward. Reading, questioning, and restructuring generated code until a human actually understands it is not bureaucratic friction; it is what converts an opaque artifact into a system the team can operate. This is why human review earns its place in the hardening list that follows, and why spec-driven development matters: when a clear specification drives the work, the intent is legible even where the generated implementation is dense, and the reviewer has something durable to check the code against. Accepting code you do not understand is borrowing against a future incident. Some borrowing is fine. Doing it unknowingly, at production scale, is not.

Hardening to production

Hardening is the deliberate work of closing the gap between a prototype that runs and a system that can be trusted to keep running. It is not a rewrite and it is not a rejection of what the prototype taught you; it is adding, one property at a time, the things the exploratory phase correctly deferred. The useful discipline is to treat each gap named earlier as a checklist item with a specific fix, so hardening becomes a visible, finishable task rather than a vague aspiration to "clean it up later."

Gap from the prototypeWhat goes wrong in productionHardening step
No testsA later change silently breaks behavior no one is watchingAdd tests that encode expected behavior; treat them as the executable contract for future change
Code no one understandsNobody can debug or safely modify it under pressureHuman review that reads and restructures the code until a person actually understands it
Insecure patternsInjection, leaked secrets, unvalidated input reach real usersSecurity scanning as an automated gate: SAST, dependency, and secret scanning on every change
Happy-path onlyTimeouts, bad input, and partial failure crash or corrupt stateError handling for the failure paths: validation, retries, graceful degradation, sane defaults
No visibilityWhen it breaks, no one can tell what happened or whyObservability: structured logs, metrics, and traces wired in before the system carries load

Order matters less than completeness, but two steps deserve to go first because they gate the rest. Comprehension comes early, because you cannot meaningfully test, secure, or instrument code you do not understand. Tests come close behind, because they are what let you change everything else without fear: once behavior is pinned by tests, you can refactor for maintainability, add error handling, and tune performance while a machine watches for regressions. The remaining steps, security scanning, error handling, and observability, are the same automated gates the rest of the engineering organization already runs, applied to code that happens to have been generated rather than typed.

This is where vibe coding rejoins mainstream engineering discipline. The hardening path is not special to AI-built software; it is the ordinary bar for production, and the point is to route AI-built software through it rather than around it. That routing is the subject of governing AI code, and the lifecycle it lives inside is the AI-native SDLC. The prototype earned its speed by skipping these gates. Production is what you owe when you decide the prototype gets to stay.

When vibe coding is exactly right

None of the preceding is an argument against vibe coding. It is an argument for matching rigor to stakes, and there is an enormous category of work where the correct amount of rigor is very little. Insisting on production discipline for a throwaway artifact is its own failure mode: it burns the speed that made the practice valuable in the first place, and it dresses up caution as engineering maturity when it is really just waste. The skill is not choosing rigor over speed; it is knowing which situation you are in.

Two questions settle it almost every time. What is the blast radius if this is wrong, and how long is this going to live? When the blast radius is small, a spike no one depends on, an internal tool used by three consenting colleagues, an experiment you will read the output of and throw away, and the longevity is short, the gap to production simply does not need to be closed. The failure paths, the observability, the maintainability all cost effort to buy protection against risks that do not exist here. Vibe away.

Draw the line by blast radius and longevity. A prototype that answers a question and is deleted, an internal script that saves one team an afternoon, a demo that proves a concept to a stakeholder, these live on the safe side of the line and deserve the speed vibe coding offers. Anything that outside users depend on, that handles data you cannot afford to lose or leak, that will still be running next year, that other engineers must maintain, sits on the production side and earns the full hardening bar. The mistake is never vibe coding. The mistake is letting an artifact drift across that line without anyone noticing it crossed.

The honest complication is that artifacts move. The internal tool becomes load-bearing; the demo becomes the MVP; the spike quietly turns into the thing the company runs on. That drift is not a reason to over-engineer everything up front, which would forfeit the whole benefit. It is a reason to make the crossing an explicit, noticed decision, a moment where someone says "this is production now" and the hardening work is scheduled rather than skipped. The practice stays fast. The transition stops being an accident.

The organizational risk

What is a manageable individual habit becomes a structural liability at organizational scale. When every team can vibe-code, the volume of AI-built software an enterprise accumulates grows faster than anyone's ability to harden it by hand, and each un-hardened artifact that drifts into production adds to a stock of code that is untested, unobserved, unowned, and understood by no one currently employed. The risk is not any single prototype. It is the aggregate: a maintenance and security surface expanding faster than the organization can inspect it, one reasonable local shortcut at a time.

The failure mode is quiet and cumulative. No single decision looks wrong. A team ships a quick internal tool; it becomes load-bearing; the person who prompted it into existence moves teams; a dependency in it goes stale; a vulnerability class turns up in the model that wrote a hundred such tools, and now no one can even enumerate which systems are affected because provenance was never recorded. Multiply that across an enterprise and the exposure is not hypothetical, it is the ordinary arithmetic of scale applied to a practice that individually felt harmless.

   team A    team B    team C   ...   team N
       \        |         |          /
        \       |         |         /
         v      v         v        v
   +--------------------------------------+
   |  production quietly fills with       |
   |  vibe-built code: untested,          |
   |  unobserved, unowned, provenance     |
   |  never recorded                      |
   +--------------------------------------+
                     |
                     v
       surface grows faster than anyone
              can inspect it
            
The risk is aggregate, not any single prototype: un-hardened artifacts accumulate into a maintenance and security surface that no one can fully inspect.

The answer is not to ban the practice, which forfeits its genuine value and simply drives it underground. The answer is governance and paved roads: make the hardened path the path of least resistance, so that shipping something to production routes it through tests, scanning, observability, and provenance by default, and shipping a throwaway prototype stays frictionless because it never claimed to be production. This is the same platform move that governing AI code argues for at length: the controls belong in the machinery every change flows through, not in a policy asking already-fast teams to voluntarily slow down. When the paved road is easier than the dirt track, most traffic takes it, and the aggregate liability stops compounding.

The architect view

The architect's posture toward vibe coding should be enthusiastic and precise at once, and the two are not in tension. Embrace the practice for what it genuinely is: the fastest path from idea to running artifact that software has ever had, and a legitimate superpower for prototypes, spikes, internal tools, and exploration. An organization that suppresses it out of misplaced rigor is leaving real velocity on the table and teaching its best people to hide how they actually work. The goal is not less vibe coding. It is vibe coding that knows where the line is.

Drawing that line is the architect's actual job here, and it has three parts. Define the bar for production explicitly, tests, human comprehension, security scanning, error handling, observability, so that "production-grade" is a checklist a team can finish rather than a vibe a reviewer invokes. Make the crossing from prototype to production a noticed, deliberate decision rather than an accident of a deadline. And build the hardening path as the paved road, the default that a team gets by shipping on the platform, so that the transition from exploration to production is a well-lit ramp instead of a cliff teams fall off one incident at a time.

The synthesis: vibe coding and production discipline are not rivals; they are two ends of a single ramp, and the architect's contribution is the ramp itself. Let exploration be fast and rigor-free where blast radius and longevity say it can be. Make the bar for production explicit where they say it cannot. And put the hardening, tests, review, scanning, error handling, observability, on the paved road so that crossing the line is a decision with support, not a shortcut with a bill that comes due in an incident. You can see the trade-offs move in the Sprint Simulator in the Lab. Match rigor to stakes, and the superpower stays a superpower.
← Spec-Driven Development: Specs as the New Source Code ALL OF AI ENGINEERING The AI Architect’s Workflow: Designing an AI System →