Writing · September 19, 2026 · 9 min read
Spec-driven development with coding agents: specs an agent can finish without me
AI agents · spec-driven development · Claude Code · Codex CLI · workflow
TL;DR: When I delegate work to a coding agent that will run without me, the spec is the whole interface. A spec an agent can finish has seven parts: where it is working, the product model it must respect, the problem, the goal in user-visible terms, hard constraints (no migrations applied, no merge, no deploy, design system only), a numbered list of tests, and a finish block with the exact checks to run and the report to write. A planning agent writes the spec, a second agent executes it in its own git worktree, and I review the result in about two minutes. Specs fail when they have no exit gate, when they rely on rules the agent read once and forgot, or when they quietly ask the agent to discover the problem instead of solving it.
What is spec-driven development with coding agents?
Spec-driven development is the practice of writing down what a change must do, what it must not touch and how it will be checked, before any code is written, and then handing that document to whoever implements it. With coding agents the implementer is a model running in a sandbox, and the spec becomes the only channel between my intent and its work. Nobody is there to answer questions.
The concrete problem I had: I run a job-matching product and an AI-visibility product on my own, with Claude Code as my main agent and OpenAI's Codex CLI as a second one (the setup is in Codex CLI next to Claude Code). I wanted to hand off whole features and come back to a pull request I could merge. I tried three ways of handing work over:
- A one-line prompt. Fast to write. Works for a rename. For anything bigger the agent fills the gaps with guesses, and I pay for the guesses in review.
- Interactive pairing. I stay in the session and answer questions. Good results, but I am the bottleneck, and the whole point of delegating was to be elsewhere.
- A written spec in a file. Slower to produce, and it forces me to decide things I would rather postpone. In return the agent can run to the end alone, and the spec doubles as the review checklist.
I use the third for anything that takes more than a few minutes of agent time. The rest of this post is what a spec in that format looks like, learned from real ones.
Anatomy of a spec an agent can finish
Three recent specs of mine had very different subjects: making an admin panel readable at a glance, changing where an outbound button sends a user for a subset of records, and fixing a bug in a data import where a record that arrived as several partial copies kept only one of them. They shared the same skeleton.
# illustrative shape only
# Task: <one line, the outcome>
Where you are: worktree on branch <x>, created from <base>.
Work only here; other sessions use the main checkout.
## Product model how this part works, where X happens
## The problem symptoms, a real case, a read-only repro
## Goal what the user sees when it is done
## Hard constraints what must not change or be done
## Tests numbered cases
## Finish checks, commit rules, PR, reportWhere you are. The first lines say which worktree and branch the agent is on and that other sessions use the main checkout. Agents running in parallel will otherwise wander into the same files.
Product model. This is the section I skipped at first and now consider the most important. It explains how the relevant part of the product works and names the single place where a cross-cutting concern lives. For the outbound-link change, the spec said that tracking parameters are added in exactly one function and that there must never be a second path. Without that sentence a capable agent adds tracking at the new call site, because that is locally reasonable.
Problem. Symptoms as reported, one real case with concrete values, and a read-only command to reproduce it where one exists. A real case anchors the agent. For the bug fix, the spec showed a source where a handful of real records turned into several times as many entries, which made the defect unmistakable.
Goal. Written from the user's side of the screen. The admin panel spec did not list components to change. It listed the questions each row must answer: is it running, how far along, how many new items need my review, how many were rejected, did anything fail.
Tests. A numbered list of cases. For a bug, the first instruction is to write a failing test that reproduces it and only then fix it. The list is also my review checklist.
Finish. The exact commands to install, run the tests, typecheck and lint the changed files. Commit rules. Push and open a pull request. Then a short report in my language: what changed, which files, which tests, and what the agent could not verify. The last item matters. An agent that cannot log in to an admin panel should say so, instead of implying it checked the screen.
Hard constraints: the lines that make delegation safe
Hard constraints are the part of the spec that lets me walk away. They fall into a few families.
- Irreversible actions stay with me. Push the branch and open a pull request; do not merge, do not deploy. A schema change is a new migration file in the usual folder, and the agent never applies it to any database.
- Invariants other systems depend on. A stored value that other jobs match on must not change, and the spec says which modules read it so the agent can check. If the design choice is open, the agent must explain where it applied the change in the pull request description.
- Design system only. No custom buttons, inputs, cards, colors or spacing; everything works in dark and light mode. If a component is missing, the agent says so in the report instead of building a local copy.
- Nothing internal leaks. When a change touches anything that reaches public output (structured data, metadata, feeds, API responses), the spec says only the final user-facing value may appear there.
- Version-specific docs. My framework version has breaking changes the model may not know, so the spec points to the docs that ship with the installed version and says to read them first.
- A reference to copy. When the same fix already exists elsewhere, the spec points at it and its test and says "same logic wanted here". That turns a design task into a port.
One rule looks redundant and is not. The commit conventions (English messages, sole author, no co-author trailer, no long dashes, stage files by path) are already in the instruction file every agent reads. I repeat them in every spec anyway. An agent reads its instructions once at the start and loses them over a long turn, and a stray co-author trailer is the most common slip I see from both CLIs.
Who writes the spec, and who executes it?
The planning agent writes it. In practice that is a Claude Code session on the top model, the one that has the product memory, has read the code and has talked the problem through with me. When that session reaches work that is fully specified, its instructions tell it to write the spec to a file and print a ready command for a second terminal. I read the spec, adjust it, and paste one line.
The executor is a different agent with a cleaner context. For mechanical work (tests from a list of cases, scaffolding, fixtures) that is the fast Codex tier at medium effort. For implementation of a finished plan it is the workhorse tier at high effort. As of September 2026 that means GPT-5.6 Luna and GPT-5.6 Sol. My rule for the workhorse tier is that it gets a full spec, never the job of figuring out what the problem is. The launcher appends a closing instruction to every task: nobody will answer questions, an unclear spec means stop and report, and the final message lists the files, the test results and the commit.
The split works because planning and execution need different things. Planning needs a long thread, memory and judgment. Execution needs a precise document and a context window that is not already full of the planning conversation. The same idea at the level of model choice is in choosing model and effort in Claude Code: the spec carries the quality, the model mostly sets the speed.
How much does reviewing a delegated task cost?
About two minutes per task, and that number barely moves with the size of the change. My review is a fixed routine: the diff stat of the branch against the base; a code review pass, either by eye or by the main agent; tests green in the main checkout after merging the branch locally; the commit message checked for a co-author trailer; the changed files checked for long dashes; scope equal to the spec. For a second opinion I also run the other agent's read-only review against the base branch, because a different model catches different bugs.
A fixed review cost has a direct consequence: delegation only pays off for tasks worth at least several minutes of agent work. For a two-minute change, I spend as long reviewing as the agent spent working, and the gain disappears. In my first measured run, a six-case test task took the agent 70 seconds and about 29.7K tokens, and all six tests passed on the first shot. The gain was parallelism and a clean main session. It saved very few tokens.
What makes a spec fail?
No exit gate. The worst result I got from a delegated task came from an open research brief: map a market, fill eleven fields per entry, draw conclusions. It came back as a status note about its own progress, with no data and one wrong fact. The test-writing task two days earlier had a single pass condition, green tests, and finished in one shot. Without a checkable end, the agent stops wherever its turn naturally closes. I wrote about that pair of runs in exit criteria for coding agents.
Rules the agent read once. Anything that must hold at the end of a long turn belongs in the spec itself, even if it is also in the global instructions. The finish block exists for that reason.
Hidden discovery. A spec that says "fix the panel" without the symptoms and the target questions asks the agent to do the product thinking. It will do some, confidently, and I will disagree with half of it in review.
No legitimate way to stop. If the spec does not say what to do when something is unclear or missing, the agent guesses. The "say so in the report" lines turn a guess into a question I can answer in the next spec.
Harness problems. Some failures had nothing to do with the wording. My first non-interactive run hung for a minute waiting on stdin, and the first commit failed because the sandbox could not write to the main repository's git directory, where a worktree keeps its metadata. The agent reported the second one instead of working around it. Both were launcher fixes. A spec cannot fix a harness that is broken.
There is also a limit I have not solved. Writing a good spec takes real time, often a planning session of its own, and for some changes that time is most of the work. Spec-driven development pays off when the thinking is done and only the typing remains.
What I would tell someone writing their first spec tomorrow
- Start with the product model. Name the one place a concern lives and forbid a second one.
- Write the goal as questions the user can answer by looking at the result.
- Number the tests. For a bug, the first test reproduces it.
- Keep irreversible steps for yourself: no merge, no deploy, migrations written but not applied.
- End with a finish block of exact commands and a report that includes what could not be verified.
- Repeat the commit rules in every spec, even when they are in the global instructions.
- Delegate only tasks worth more than your review time.
Questions this post answers
- What should a spec for a coding agent include?
- A spec an agent can finish alone has seven parts: where it is working, the product model it must respect, the problem with a real case, the goal in user-visible terms, hard constraints, a numbered list of tests, and a finish block with exact checks, commit rules and a report of what could not be verified.
- Who should write the spec for an AI coding agent?
- The planning agent, which has the product context and has talked the problem through with you, writes the spec to a file. A second agent with a clean context executes it in its own git worktree, and a human reviews the resulting pull request.
- Why do specs for coding agents fail?
- The most common causes are a missing exit gate, rules the agent read once at the start and lost during a long turn, and specs that quietly ask the agent to discover the problem. Giving the agent a legitimate way to stop and report also prevents it from guessing.