- 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.
- Tests: the prototype was verified by watching it work once; production needs an executable specification that catches regressions when the code changes.
- Error handling: the happy path is coded; the failure paths, timeouts, retries, malformed input, partial failure, are usually absent or naive.
- Security: injection, unvalidated input, secrets in source, and permissive defaults are common in code optimized for looking like it works.
- Observability: when it breaks in production, can anyone tell what happened? Logs, metrics, and traces are rarely part of the vibe.
- Performance: what is fine for one user and a toy dataset can fall over at real scale, and the prototype never met real scale.
- Maintainability: structure, naming, and boundaries that let a team change the system safely tend to be casualties of speed.
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 prototype | What goes wrong in production | Hardening step |
|---|---|---|
| No tests | A later change silently breaks behavior no one is watching | Add tests that encode expected behavior; treat them as the executable contract for future change |
| Code no one understands | Nobody can debug or safely modify it under pressure | Human review that reads and restructures the code until a person actually understands it |
| Insecure patterns | Injection, leaked secrets, unvalidated input reach real users | Security scanning as an automated gate: SAST, dependency, and secret scanning on every change |
| Happy-path only | Timeouts, bad input, and partial failure crash or corrupt state | Error handling for the failure paths: validation, retries, graceful degradation, sane defaults |
| No visibility | When it breaks, no one can tell what happened or why | Observability: 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.
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 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.