What "vibe coding" actually skips

Vibe coding - describing what you want in loose natural language and accepting whatever an AI agent generates - is genuinely fast for a first pass. The part that gets skipped isn't code quality in the cosmetic sense; it's the architectural decisions the model makes implicitly on your behalf. Should this write be transactional? Should this endpoint be idempotent? Should this service own its own database, or share one? An AI agent answers all of these questions somehow, every time it generates code - it just doesn't tell you it answered them, or why.

This is the actual risk, not "AI writes buggy code." Modern models write syntactically correct, functional-looking code constantly. The risk is architectural decisions made silently, at a layer most teams don't review until the system is already under production load and something breaks in a way that traces back to an assumption nobody consciously made.

Prompt-driven development: the alternative, not the opposite

The fix isn't to abandon AI-assisted coding - it's to make the prompt itself carry the architectural intent, instead of leaving it implicit. A prompt that says "add an endpoint to send a notification" produces different code than one that specifies transactional boundaries, idempotency requirements, and error handling up front.

Vibe coding prompt

"Add an endpoint that sends a confirmation SMS when an order is placed." Leaves idempotency, retry behavior, and transaction boundaries entirely to the model's defaults - which vary and are rarely correct for production.

Prompt-driven development prompt

"Add an endpoint that sends a confirmation SMS when an order is placed. Persist the notification with an idempotency key derived from order ID before calling the provider. Wrap the DB write and outbox insert in one transaction. Return 202 immediately; send is async." Every architectural decision is explicit, in the prompt, reviewable before code is even generated.

The PRV Cycle: Prompt, Refactor, Verify

PRV is a three-step discipline for every unit of AI-assisted work, small or large - a loop, not a one-time gate.

1

Prompt with architecture specified. State the transactional boundary, the idempotency requirement, the error-handling contract, and the security constraint explicitly - don't let the model infer them.

2

Refactor into the existing codebase's patterns. Generated code rarely matches your team's existing conventions, error-handling style, or module boundaries on the first pass - a human refactor pass aligns it, rather than merging it as-is.

3

Verify with tests and review. The same code review bar as human-written code - unit tests for the new logic, and a reviewer checking the architectural decisions actually match what was specified in step 1.

The cycle repeats - verification often surfaces a gap the prompt didn't cover, which becomes the next prompt. PRV is not "prompt once, ship" - it's a loop that converges on production-ready code across a few iterations, the same way a human engineer iterates on a design.

Where teams actually get burned

Missing idempotency

An AI-generated payment or notification endpoint with no idempotency key, because the prompt never asked for one - the exact failure mode covered in our notification audit-trail piece.

Silent transaction boundary choices

Generated code that "looks transactional" but wraps the wrong set of operations, or none at all - invisible until a partial failure exposes it.

No compensating logic

A generated multi-step flow with no rollback path for a mid-sequence failure - the SAGA compensating-action gap, generated silently rather than designed deliberately.

Key takeaways

  • Vibe coding's real risk is implicit architectural decisions, not surface-level code quality - both look fine in a demo.
  • Prompt-driven development means stating transactional, idempotency, and error-handling requirements explicitly in the prompt, not leaving them to the model's defaults.
  • The PRV cycle - Prompt, Refactor, Verify - is a loop, not a single gate, and it applies the same review bar to AI-generated code as to human-written code.
  • Refactoring into existing codebase conventions is not optional polish - it's what keeps a codebase maintainable as AI-assisted contributions grow.
  • The specific failure modes to watch for - missing idempotency, unclear transaction boundaries, absent compensating logic - are the same ones covered across our other engineering pieces, because they're the same underlying gaps.
If your team has shipped several AI-assisted features quickly and nobody has audited the transactional and idempotency assumptions baked into them, that's usually a focused one-week review, not a rewrite.