A Sufficiently Detailed Spec Is Already Code

articleaisoftware-engineeringllm-codingspecagent-loopsvibe-coding

mirrors the joelclaw workload rig reality — detailed stage plans are code by another name, and treating them as mere spec creates false confidence in the abstraction

Gabriella Simpson takes a sharp knife to OpenAI Symphony — the “write a spec, get working code” pitch — and the argument lands clean. The core: a specification detailed enough to generate correct working code IS code. You haven’t abstracted away the hard work; you’ve written it in prose instead of a programming language. The medium changed. The intellectual labor didn’t.

The proof is in the ratio. Symphony’s SPEC.md for the reference implementation is one-sixth the size of the actual Elixir implementation. That’s not a specification capturing the full complexity of the problem — it’s a sketch that leaves the AI to fill in gaps by making decisions the spec author never made. When it works, it’s because the AI guessed right on those unspecified decisions. When it doesn’t, you have an AI-generated implementation with emergent behavior nobody specified.

The “vibe coding from specs” narrative positions the spec as doing the intellectual work and the AI as doing the typing. Simpson’s point is that this is exactly backwards — the intellectual work IS the typing. Deciding what a function does in every edge case, what invariants hold, how errors propagate — that’s the code. Prose that doesn’t answer those questions isn’t a spec, it’s a wishlist with a .md extension.

This lands with real force in the context of agent loops and workload stage plans. Writing a detailed enough stages.json to reliably produce correct code is itself a coding act. Calling it a spec doesn’t compress the decision space out of existence — you can’t Kolmogorov-compress the decisions away by switching formats. The question isn’t “did I write a spec?” It’s “did I actually specify the decisions?”

Key Ideas

  • A spec that sufficiently constrains AI output to generate correct code must contain the same information density as the code itself — the format is irrelevant to the complexity
  • Symphony’s SPEC.md is 1/6 the size of the Elixir implementation — the ratio is the argument, not a detail
  • “Vibe coding from specs” transfers hard intellectual decisions to the AI, not away from them; someone still has to make the decisions
  • Underspecified behavior requires the AI to guess; when those guesses compound across an implementation, you get emergent behavior nobody intended
  • The abstraction only holds if the spec is as detailed as the code — at which point you’ve written the code
  • Sharp parallel to Simpson’s broader Haskell philosophy: precision isn’t a style choice, it’s the point