Skip to content

Specs over Prompts

A prompt controls one agent for one session, then evaporates. A spec file controls every agent, every session, every tool, for the life of the feature. Once you delegate anything larger than a bounded change, the spec — not the prompt — is where your leverage lives. The prompt shrinks to a pointer: Implement specs/spending-alerts.md. Ask before deviating.

Prompts vs Specs covers the conceptual split. This page makes the operational and economic case, and tells you when to skip the spec entirely.

What a prompt structurally cannot do

PropertyPrompt in chatCommitted spec file
LifespanOne session; gone from context on /clearAs long as the feature exists
ReviewableNo — lives in your scrollback, invisible to the teamYes — it's a file in a PR; a teammate can veto the intent before code exists
ReusableRetyped from memory each session, drifting each timeimplement per specs/x.md — identical input to every session, agent, and tool
VersionedNo history; "what did I ask for in March?" is unanswerablegit log specs/x.md answers it
Cross-toolLocked to one tool's session formatClaude Code, Codex, Cursor, and a human contractor all read the same Markdown
Verifiable"Did it do what I meant?" is a vibe checkDiff the output against acceptance criteria — a checkable question

The last row is the one that changes your daily work. Without a spec, reviewing agent output means reconstructing your own intent from memory while reading 900 lines of diff. With a spec, review splits into two cheap questions: does the code satisfy the spec? (mechanical — and delegable to a second agent) and was the spec right? (the only part that needs your judgment). See Reviewing AI PRs.

The economics: 30 minutes vs 3 hours

The recurring anti-pattern: skipping the spec to "save time," then paying for it in review-and-redo. Concrete version — "add CSV export to the reports page" delegated as a one-line prompt to a React/Node dashboard:

Prompt-only pathSpec-first path
Up-front2 min prompt30 min spec (agent drafts, you harden)
Agent run25 min — makes ~8 silent decisions: columns, delimiter, encoding, row cap, streaming vs buffering, permissions, filename, timezone of dates25 min — decisions were already made
First review40 min — you discover it buffered 500k rows in memory and exported soft-deleted records20 min — checking against acceptance criteria, not reconstructing intent
Redo cycleRe-prompt from memory, 25 min run, 30 min re-review; the re-prompt introduces a new ambiguityRarely needed; deviations are visible as spec violations
Next session touches exportRe-explain everything; driftsee specs/csv-export.md
Total~3 hours, and the constraints still live only in your head~1.5 hours, and the spec is a permanent asset

The redo cycle is the killer. Every re-prompt is a new lossy compression of your intent, and agent runs are cheap enough that you'll be tempted to spin the wheel instead of thinking — three plausible-but-wrong implementations later, you've spent more time reviewing than a spec would have cost. This is the economics behind the stuck loops failure mode.

The multiplier: a prompt's cost is paid per session; a spec's cost is amortized over every future session, teammate, and tool that touches the feature — including the agent that debugs it in production six months from now.

The spec-driven loop

Two edges do most of the work. Plan → spec: run the agent in plan mode against the spec before any code is written; a wrong plan is the cheapest possible detector of a wrong spec (Idea to Spec covers this drafting loop). Verify → criteria: verification means checking acceptance criteria line by line, not skimming the diff — which only works if the criteria were written to be checkable (Verification Strategy). The final edge — spec updated and merged with the code — is what keeps the loop honest across iterations; skip it and you enter the drift cycle described in Keeping Specs Alive.

When a spec is overkill

Specs are a tax on small work. A one-line fix with a full spec is process theater; a billing change with no spec is negligence. Scale the artifact to size × risk:

Task profileExamplesCost of a wrong guessArtifact needed
Mechanical, one-line, self-evidently verifiableFix typo, bump a dependency, rename a variableSeconds — visible in the diff instantlyNothing. Just ask.
Bounded change, one surface, minor ambiguityAdd a CLI flag, extend an endpoint with a field, add a test for known behaviorMinutes of localized reworkStructured prompt — task, context, constraints, done-when. See Prompt Anatomy
Multi-file feature with real decisions embeddedCSV export, notifications, a new settings pageHours of review-and-redo; invented requirements shipLightweight spec — one page: intent, requirements, acceptance criteria, out of scope
Cross-cutting, hard to reverse, or architecturalAuth model change, billing logic, data migration, service extractionProduction incident, silent architecture erosionFull spec plus an ADR capturing the decision. See Decision Records and Writing Effective Specs

Two overrides that push a task up a row regardless of size: irreversibility (data migrations, published API contracts, anything customers integrate against) and repeat explanation — if you've explained the same constraints in chat twice, the third explanation should be a file, whatever the task size.

And one push down: if a lightweight spec is growing past two pages, you don't have a bigger spec problem — you have a decomposition problem. Split it. See spec granularity and Large Tasks.

A field manual for AI-native software engineering.