CASE FILE Vibe Coding Β§3/6
passage

Reading

The Spec-to-Ship Loop

Shipping a feature means turning words into code. Most junior devs think this happens in one direction: write spec β†’ AI generates code β†’ ship it. That's a fantasy. The real loop has three moves: specify, generate, correct β€” and the cycle often repeats.

Here's the hard truth: your spec is always incomplete. Not because you're bad at writing, but because software lives in contradictions. Every feature has unstated assumptions β€” edge cases, interaction details, performance tradeoffs, integration points with systems you haven't fully understood yet. The AI can fill some of these in. It will also invent things. Your job is to catch both.

Why specs fail

Take a real example: "Add a toggle to show/hide the leaderboard." Sounds simple. Here's what's unstated:

  • Where does the toggle live? (Top bar? Settings? Context menu?)
  • What's the default state? (Shown or hidden?)
  • When you hide the leaderboard, do score notifications still fire?
  • If a user has never seen the leaderboard, should the toggle text say "Show" or "Reveal"?
  • Does hiding it clear the live-update websocket subscription?

An AI will pick sensible defaults for every one. They might not be your defaults. The spec β†’ generation β†’ correction cycle is how you align them.

The three moves

Move 1: Specify. Write enough detail that an AI can start. Don't exhaustively document β€” you can't. Instead, pick the critical constraints: what data flows through this feature, what triggers it, what the success metric is. For the leaderboard toggle: "Add a toggle in the top-right nav bar, default hidden. When toggled, show/hide the leaderboard view. Keep the websocket alive." That's 20 seconds to write and it closes 80% of the ambiguity.

Move 2: Generate. Run the spec through an AI. Tell it your tech stack, your file structure, any libraries you're using. Ask it to generate the code and explain its assumptions β€” what defaults did it pick, why it put the toggle where it did, what it skipped. This is the critical move: read the assumptions, don't just paste the code.

Move 3: Correct. For every assumption that doesn't match your intent, tell the AI. "Actually, the toggle should default to shown, not hidden." "The notifications should pause when the leaderboard is hidden." Each correction spawns a new generation. You're not writing code β€” you're refining a spec, one correction at a time.

When to stop

You stop when either:

  1. The generated code matches your intent well enough to land it (ship it to staging, test it, merge it).
  2. The corrections have become so intricate that it's faster to hand-code the piece yourself.

Neither of these is failure. Both are victories β€” you've clarified what you want and you've shipped something.

The vibe check

All three moves depend on one thing: you have to read what the AI generated and compare it to what you meant. That comparison is the whole skill. The AI doesn't know your team's code style, your user's unspoken expectations, or the difference between a sensible default and a trap. You do. Generating code is the easy part. Vibe-coding is the reading-and-correcting part β€” and that's where the feature actually ships.