Ask an agent for “an export button on the monthly view” and you will get an export button. It will probably run, and it may even look right. It may also ignore the filters on the screen, ignore who is allowed to see which rows, and quietly decide what the file should be called. You asked; it answered the question as written. The meaning you carried in your head never reached it.
A spec is how you move that meaning out of your head and into the repository. It earns its keep on features that touch several files, not on a one-line bug fix. One caveat up front: the case for spec files specifically rests on vendor practice and judgement, not on a controlled trial. The evidence for asking questions first is firmer, and that is where we start.
What the Evidence Says
01 · Evidence · ICLR 2026 · Vendor guides · Thoughtworks
Clarifying questions help; spec files are still a judgement call
A study accepted to ICLR 2026 looked at coding agents working on GitHub issues that were underspecified. The agents struggled to tell a well-specified instruction from an underspecified one. When they were pushed to ask clarifying questions, results improved by up to 74%.
By the numbers
- 74%best-case improvement when agents asked clarifying questionsICLR 2026 study, arXiv 2502.13069
- 5sections in a one-screen specProblem, Scope, Decisions, Acceptance criteria, Tasks
- 6steps from request to built featureThis guide
The practice side agrees. Both Anthropic and OpenAI publish best-practice guides for their coding agents, and both advise interviewing before coding rather than after. On the cautious side, the Thoughtworks Technology Radar placed spec-driven development at “Assess” in November 2025, meaning worth exploring but not yet proven. Birgitta Böckeler, writing on martinfowler.com, compared the spec tools and warned that reviewing the generated code still matters more than reviewing the markdown.
Hold both thoughts. A spec is cheap insurance against misunderstanding; it is not a substitute for reading what the agent built.
Step 1: Plan Before the Agent Writes Code
02 · Done when you have a plan you have read
Make the agent look before it leaps
Both major coding agents have a mode that keeps them from editing anything while they read the code and propose an approach. Use it per task, at the start, so the first thing you review is a plan rather than a diff.
Claude Code
or, for a single prompt:
/plan Add a filtered CSV export to the monthly view. Read the code first.
Codex
/plan Add a filtered CSV export to the monthly view. Read the code first.
Optional, in ~/.codex/config.toml:
plan_mode_reasoning_effort = "high"
One practical detail: Claude Code saves its plan files by default to ~/.claude/plans/, which sits outside your repository. A plan that lives only there will not travel with the code, which is the first reason to carry the useful parts into a spec file in Step 3.
Step 2: Settle the Open Decisions First
03 · Done when no unknown is left as a guess
An unmarked unknown becomes a silent guess
Before a larger feature, ask the agent to interview you. Let it put questions to you about the parts the request leaves open, and answer them in writing. The goal is not a long conversation; it is that every real fork in the road gets a decision from a person.
Whatever you cannot answer yet, mark it. Write [OPEN] next to the question rather than letting anyone assume. The same idea appears elsewhere: GitHub Spec Kit uses a [NEEDS CLARIFICATION] marker for exactly this. A spec that still contains an open marker is not ready to build, and that rule is easy for an agent to follow.
Step 3: Write the Spec as a File in the Repo
04 · Done when the spec is committed
Five sections, one screen
Keep the spec short enough to read in a single screen. Five sections are enough: the Problem you are solving, the Scope it covers and does not, the Decisions already made, the Acceptance criteria, and the Tasks. Commit it as specs/<feature>.md so it is reviewed, versioned and found by the next person, or the next agent.
This is where the wider tooling sits. GitHub Spec Kit and Kiro both build workflows around spec files; Thoughtworks, as noted, files the whole approach under “Assess.” You do not need any of them. A markdown template and a habit will do.
specs/_template.md
## Problem
Who has it, what hurts, how we will know it is fixed.
## Scope
In: ...
Not in: ...
Touches: files, services, data
## Decisions
- Decision, and why.
- [OPEN] A question nobody has answered yet.
## Acceptance criteria
- AC1: When <trigger>, the <system> shall <response>.
Check: how a test or a person proves it.
## Tasks
- [ ] T1: ...
depends on: none
done when: AC1 passes
- [ ] T2: ...
depends on: T1
done when: AC2 passes
Then tell the agent about the template and the rules around it, once, in the instruction file it reads on every run (CLAUDE.md for Claude Code, AGENTS.md for Codex).
Instruction file, section “Specs”
Features and multi-file changes start from a spec in specs/, using specs/_template.md. Bug fixes and one-sentence changes do not need one. A spec with an [OPEN] item is not ready to build; ask about it first.
Step 4: Write Acceptance Criteria a Test Can Check
05 · Done when every criterion has a check
If a test cannot fail it, it is not a criterion
“It should work properly” cannot be checked by anyone, human or machine. A criterion needs a trigger and an observable result. A well-worn format for this is EARS, the Easy Approach to Requirements Syntax, created at Rolls-Royce in 2009. Its event pattern reads in one line: When <trigger>, the <system> shall <response>.
The sentence is rigid on purpose. It forces you to name what sets the behaviour off and what must come out, and the second half is very nearly the assertion a test would make. Here are three illustrative rows, using the CSV export from earlier, moving from vague to checkable to the test behind it.
Notice that the third row replaced a fuzzy worry (“big months”) with a precise edge case the agent can actually handle. Rewriting a vague line into EARS often reveals that it was hiding a decision you had not made yet.
Step 5: Split the Work into Tasks the Agent Can Finish
06 · Done when each task has an end
Small enough to finish, ordered enough to follow
Break the feature into tasks, each small enough that one fresh session can complete it. A good task names what it depends on and states a done-when condition that points back at the criteria. Something like “done when AC1 passes” leaves no room for the agent to declare victory early.
- Size. One task, one coherent change, one pull request that a person can review without a headache.
- Dependencies. Write “depends on” next to any task that cannot start before another finishes, so the order is in the file, not in someone's memory.
- Done when. Tie every task to the criteria that prove it, so finishing is a check, not a feeling.
- One home. Keep the task list inside the spec file. The checklist then shows progress, and a new session can read where the work stands.
Step 6: Build from the Spec, and Check Against It
07 · Done when the diff matches the spec
The spec only works if the build keeps faith with it
Run each task in a fresh session so the agent starts from the spec instead of from a long, drifting conversation. Give it a rule for the moment the spec and the code disagree: stop and ask, then update the spec. And when the work comes back, review the diff against the spec, and tie each acceptance criterion to the “how it was checked” section of your pull-request template, so the evidence travels with the change.
Instruction file, section “Working from a spec”
Read the spec in full before you start. Work on one task at a time, in order. Change only what the task needs; anything under "Not in" stays untouched. A task is done when its criteria pass; tick it in the spec in the same pull request. If the spec and the code disagree, or a decision is missing, stop and ask — then update the spec; do not work around it.
The Playbook in Six Lines
- Plan first, in the agent's plan mode, before it touches any code.
- Let it interview you, and mark every unanswered question [OPEN].
- Commit a one-screen spec: Problem, Scope, Decisions, Acceptance criteria, Tasks.
- Write each criterion so a test can fail it.
- Cut the work into tasks with dependencies and a done-when condition.
- Build one task per fresh session, and review the diff against the spec.
An agent always fills the gaps you leave. The spec is simply where you decide which gaps it gets to fill.
Every gap gets filled. Decide which ones the agent may.
People set the intent. Agents build it.
A good spec is the cleanest handoff between the two: a person decides what and why, and the agent carries out the how. See where piMonk applies the same split, and read how the wider job changes.
Sources
- https://arxiv.org/abs/2502.13069,ICLR 2026 study on coding agents and underspecified issues
- https://code.claude.com/docs/en/best-practices,Anthropic, Claude Code best practices
- https://learn.chatgpt.com/guides/best-practices,OpenAI, Codex best practices
- https://www.thoughtworks.com/radar,Thoughtworks Technology Radar, spec-driven development, November 2025
- https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html,Birgitta Böckeler, comparing spec tools
- https://alistairmavin.com/ears/,EARS: Easy Approach to Requirements Syntax (Rolls-Royce, 2009)
- https://github.com/github/spec-kit,GitHub Spec Kit
- https://kiro.dev/docs/specs/feature-specs/,Kiro feature specs