Volume III · Chapter 3
Specs as Executable Artifacts
Spec-driven development: specifications become executable, directly generating implementations — positioned against unstructured vibe coding.2026-07-12 · 7 min read
Two engineers on the same team picked up nearly identical tickets in the same sprint: add rate limiting to a public API endpoint that had started drawing abuse traffic. The first opened a terminal, described the goal to an AI coding agent in one sentence, and spent the next forty minutes in a loop — generate, run, notice the burst-traffic case wasn’t handled, ask for a fix, notice the 429 response didn’t carry a Retry-After header, ask again. By the end the code worked, the pull request merged, and the chat window that produced it closed and was never reopened.
The second engineer spent fifteen minutes writing four short paragraphs before touching an agent at all: which endpoints, what limit, what a client sees on a 429, what happens to a request already in flight when the limit trips, and one explicit line reading “not in scope: per-user tiers, that’s a separate ticket.” Only then did they generate an implementation from it. The code that shipped was, by any diff-level comparison, unremarkable — similar in size and shape to the first engineer’s. What differed was what existed six weeks later, when a product manager asked why abusive traffic from a single IP wasn’t throttled more aggressively than well-behaved traffic. One engineer had a git blame and a hazy memory of a conversation. The other had a document that already answered the question, filed in the repository next to the code it described.
What “executable” actually means
Spec-driven development’s central, and on first hearing implausible, claim is that the specification is executable — that a written document, not source code, can directly generate a working implementation. Taken literally the claim is false: a markdown file does not compile, and no spec-driven tool skips a compiler or a test runner. Taken as intended, it is closer to a claim about division of labor. GitHub’s own framing of its spec-kit toolkit puts it plainly: specifications “become executable, directly generating working implementations rather than just guiding them.” The word directly is doing the real work. The gap between spec and running code narrows enough that generation is close to mechanical, with far less improvisation than an underspecified prompt requires.
This is the argument the opening chapter of this volume made about prompts as interfaces, carried to its logical conclusion. A prompt with explicit inputs, explicit constraints, and an explicit definition of done is not a request for the model to guess — it is an interface contract the model implements. A spec is what that contract looks like once it is written down before generation starts, reviewed as a document in its own right, and kept around after the code exists rather than discarded the moment the diff lands.
What vibe coding is actually good for
None of this makes the conversational, iterate-on-vibes style of AI coding a strictly worse practice. Andrej Karpathy coined the term in a single February 2025 post — “fully give in to the vibes, embrace exponentials, and forget that the code even exists” — and it spread fast enough to become the Collins English Dictionary’s word of the year within twelve months. Vibe coding is fast precisely because nothing gets written down before the first line of code does, and that is exactly the right trade when the cost of being wrong is low: a throwaway prototype, a weekend spike testing whether an approach is even feasible, a script three people will ever run. None of that makes it a lesser skill so much as a different one, tuned for situations where iterating in public, in real time, is cheaper than writing anything down first.
The vendors building spec-driven tooling concede this point rather than dispute it. AWS’s own positioning of Kiro, a competing spec-driven IDE that launched the same year as spec-kit, describes vibe coding as “great for rapid prototype iterations and the discovery phase” — the cost only accumulates “at scale,” once inconsistent code, architectural drift, and team-coordination problems compound across more than one person or more than one week. That is not a hedge added for balance; it is the same vendor whose product exists to sell teams out of vibe coding, conceding that its own comparison only favors them once a second person or a second week enters the picture.
The honest version of the claim, then, is not that vibe coding is always inferior. It is that vibe coding and spec-driven development resolve the same unavoidable ambiguity at different times and with different degrees of visibility, and the choice between them should track how expensive it would be to have resolved that ambiguity wrong. The risk profile that argues for a spec is not really about the size of the codebase — it is about who else, or what else, has to trust the result. A prototype nobody else touches can absorb an ambiguous edge case silently; a rate limiter guarding a public API, read by the next engineer on call at 2 a.m. during an incident, cannot.
Disambiguation, once or a dozen times
Every prompt, however brief, requires someone or something to resolve ambiguity: what counts as done, which edge cases matter, what happens outside the happy path. That work has to happen regardless of method. What differs is where it happens and whether it leaves a trace. In the conversational style, ambiguity gets resolved a little at a time, across a dozen or a hundred small back-and-forths, each one invisible outside the session that produced it and mostly forgotten by the time the branch merges — a version of the trust problem Stack Overflow’s 2025 survey put a number on: 84% of developers now use or plan to use AI tools, but the top complaint, at 66%, is output that is “almost right, but not quite,” which is exactly what a hundred small unreviewed decisions tend to produce.
In the spec-first style, the same disambiguation work is concentrated into one document that a human reads and approves before generation begins — which means it can be reviewed for what it actually is, a set of decisions about scope and behavior, rather than reconstructed after the fact from a diff nobody wrote down the reasoning for.
The document that outlives the chat
The mechanism spec-kit and its peers converge on is simple to state. A spec captures what to build and why, deliberately deferring how to a separate planning phase — spec-kit’s own instruction to the person writing one is to “be as explicit as possible about what you are trying to build and why” and, in the same breath, not to “focus on the tech stack at this point.” Kiro runs an automated pass over the requirements — checking for “contradictions and gaps” — before a single line of implementation code is generated, an explicit gate between intent and execution that a prompt typed into a chat box simply does not have.
Vibe coding excels at rapid prototype iterations and the discovery phase — and starts costing more than it saves the moment more than one person, or one week, is involved.
On Kiro’s own positioning against vibe coding
And because the spec is a file, not a conversation, it can be committed to source control next to the code it produced — reviewable in a pull request the way the code is, and still legible when someone later needs to know why a decision was made. That durability is the same property this Library has already named Decision Memory elsewhere: decisions persisted as first-class, queryable records rather than folklore. A spec is Decision Memory captured at the moment of intent, before a single line of the implementation exists, instead of reconstructed afterward from commit messages and institutional memory.
The same durability helps a machine, not only a person. A fresh AI session picking the ticket back up after a context reset, a compaction, or simply a new day has no memory of the forty-minute conversation that resolved the burst-traffic edge case the first time. It does have the spec, if one was written — which turns rebuilding forgotten context into reading an existing document instead.
Vibe coding vs. spec-driven, by property
The table below names properties, not a verdict. A spike branch that dies in code review tomorrow needs none of the right-hand column; a payments-adjacent change needs most of it. The judgment call is matching the practice to the row the work actually belongs in, rather than defaulting to whichever one is faster to start typing into.
| Property | Vibe coding | Spec-driven development |
|---|---|---|
| Speed to first output | Fast — nothing is written before code | Slower up front — a document precedes generation |
| Where ambiguity gets resolved | Scattered across many prompts, mostly undocumented | Concentrated once, in a document written and reviewed before generation |
| Artifact left after the code exists | A closed chat window, rarely reread | A spec, versioned alongside the code it produced |
| Review checkpoint | After the fact, on the diff only | Before generation, on the spec — and again after, on the diff |
| Handing off to a new session or teammate | Re-derive intent from the code and whoever remembers | Read the spec |
| Best fit | Disposable exploration, prototypes, low-stakes spikes | Work with a second reader, a lifespan, or a compliance or security boundary |
What this predicts, checked against real sessions
The claim this chapter makes is mechanical and therefore testable: a session that starts from a written spec should need meaningfully fewer disambiguating round-trips to reach a first passing result than a session that starts from a goal typed cold, on matched tasks. Operon does not yet have that controlled comparison — which is exactly the kind of measurement this chapter’s claims should be checked against as the platform’s session data accumulates. Stating the illustrative shape here, rather than staying silent until the data exists, is itself an application of this chapter’s own argument: write the claim down precisely enough to be checked before the evidence to check it has been collected.
The next chapter in this volume turns to the piece of an intent architecture spec-driven development treats as even more durable than any single spec: the constitution — the standing principles a spec is written against, rather than the goal-specific document itself.
For Discussion
- Pick your team’s five most recent AI-assisted merges. For how many could a teammate who wasn’t in the session explain, in under a minute, why a specific edge case was handled the way it was?
- If your team required a written spec before generation started tomorrow, which categories of work would it visibly slow down — and would that be the right trade for those categories specifically?
- How much of what your team calls “AI coding” is closer to the disposable-prototype end of the risk spectrum than the second-reader, production end — and does your process currently tell the two apart?
References
- establishedSpecifications “become executable, directly generating working implementations” — spec-kit’s own framing, positioned explicitly against vibe codingGitHub spec-kit · 2025-09
- establishedUnderstanding Spec-Driven Development: Kiro, spec-kit, and Tessl — spec-first vs. spec-anchored vs. spec-as-source, and the review burden of markdown-heavy workflowsmartinfowler.com (Birgitta Böckeler) · 2025-10-15
- established“Vibe coding” coined by Andrej Karpathy on X, February 2025; named Collins English Dictionary’s word of the year within the yearWikipedia — “Vibe coding” · 2025-02-02
- emergingKiro’s spec-driven workflow checks requirements for “contradictions and gaps” before generating implementation codeKiro (AWS) · 2026-03
- emergingBeyond Vibe Coding: Kiro positioned as a corrective once work moves past “rapid prototype iterations and the discovery phase”InfoQ · 2025-08-18
- established84% of developers using or planning to use AI tools; 66% cite “almost right, but not quite” as top frustrationStack Overflow Developer Survey 2025 · 2025-07