Spec Driven Development Part 4: From Spec to Code — The Practical Workflow
Parts 1 through 3 discussed why specs matter, how to write good specs for features, and how to write contracts for APIs and data. But even a perfect spec doesn’t automatically produce good code if the way it’s executed is wrong. Many teams already have solid specs, then still throw the entire spec at the agent at once with the instruction “implement this”, and are surprised when the result is still messy. This article discusses the practical mechanics of running the spec-driven loop day to day: how the spec is translated into small executable steps, effective prompting patterns, when to stop for review, and how to keep the spec an accurate source of truth as the code keeps changing.
From Spec to Plan: Breaking Down the Work
The spec defines what must be correct. The plan translates that into a work sequence — small tasks each executable, verifiable, and reviewable separately. Jumping directly from spec to “please implement all of this” is the most common mistake in SDD practice, even by teams already disciplined about writing specs.
The reason is simple: the larger the piece of work executed at once, the harder it is to verify the result, and the more expensive the cost when something goes wrong midway. If an agent is asked to implement the entire password reset feature from Part 2 and Part 3 in one step — endpoints, validation, email service, audit log, rate limiting — all at once, and the rate limiting approach turns out wrong, you must re-evaluate the entire result to make sure other parts aren’t affected too.
A good plan breaks the spec into tasks with the right granularity — not too large (hard to verify), not too small (coordination overhead becomes not worth it):
Plan: Self-Service Password Reset
Task Group 1: Schema and Migrations
1.1 Create the password_reset_tokens table (token_hash, email, expires_at, used_at)
1.2 Add indexes on email and expires_at
Task Group 2: Request Reset Endpoint
2.1 Create the POST /api/v1/password-reset/request endpoint
2.2 Implement rate limiting (3 requests/email/hour)
2.3 Generate a token, store the hash in the database
2.4 Send the email via SendGrid with the reset link
Task Group 3: Confirm Reset Endpoint
3.1 Create the POST /api/v1/password-reset/confirm endpoint
3.2 Validate the token (exists, not expired, not used)
3.3 Validate the new password per the policy
3.4 Update the password, invalidate the token
Task Group 4: Audit and Observability
4.1 Add an audit log for every reset attempt
4.2 Add metrics for monitoring rate limit hits
Each task group corresponds to a subset of the acceptance criteria already written in the spec, and can be verified independently before continuing to the next task group. Task Group 1 can be verified with a migration test before Task Group 2 starts. If there’s a problem, its location is clear — no need to trace the entire feature.
A practical rule for task granularity: one task group should ideally be verifiable in one review session without needing to re-understand the entire feature context from scratch. If reviewing one task group takes more than half an hour to understand, the task is probably too large.
Tools That Support the Spec-Driven Workflow
The spec-driven workflow doesn’t require special tools — plain markdown specs and process discipline are enough. But several tool categories are indeed designed to formalize this loop, and are worth knowing even if not used directly.
Spec kits / CLI scaffolding — tools providing a directory structure and standard commands for the spec, plan, and task phases. Usually working with sequential commands: one command to capture the initial requirements, one to translate into an architectural plan, one to break into tasks, and one to run the implementation per those tasks. The structure forces the four loop phases from Part 1 to truly be passed in sequence, not skipped.
Skills or custom commands on AI coding agents — instead of rewriting the same instructions every time, team conventions (file structure, error handling patterns, testing standards) are encapsulated into a skill callable repeatedly. This makes every task in the plan automatically follow project conventions without needing to be re-explained in every prompt.
Plan mode on coding agents — a mode where the agent is asked to compose an execution plan first and wait for approval before starting to change code. This directly implements the “review & refine” phase of the Part 1 loop at the tooling level, not just as a manual process.
Regardless of the specific tool used, the same principle applies: don’t let the agent jump from spec directly to code without an explicit, reviewable plan phase.
Prompting Patterns for Incremental Execution
Once a plan exists, how you ask the agent to execute tasks also greatly affects result quality. An effective pattern is explicitly referencing the spec and plan files, then asking for one task group at a time — not the entire plan at once.
ANTI-PATTERN:
"Implement the password reset feature according to the spec that was created."
CORRECT:
"Take Task Group 2 (Request Reset Endpoint) from plan.md. Use
spec.md as the reference for acceptance criteria and constraints. After
finishing, update the task status in plan.md and don't continue to Task Group
3 before I review."
This difference looks small but its impact is significant. The first instruction gives the agent freedom to interpret the work order itself, which often means the agent tries to complete everything at once in one long response — hard to review, and if there’s an error at the start, that error propagates through the entire result. The second instruction limits the execution scope to one task group, explicitly references the documents that are the source of truth, and inserts a review pause before continuing.
The “one task group, then stop for review” pattern is consistent with the Part 1 loop — implementation and verification run alternating, not a large implementation followed by one large verification at the end.
The biggest temptation when a deadline is tight is asking the agent to “finish everything at once” to save time. This is usually counterproductive — the time saved in the execution phase is often spent twice over in the debugging phase when errors are only discovered after everything is merged into one big change.
Review During Execution, Not Only at the End
One of the most important habit shifts in SDD compared to older workflows is when review happens. Conventional workflows usually go: the developer writes the entire feature, then opens a pull request for review. In a spec-driven workflow with agents, waiting until the end means waiting too long to catch deviations from the spec.
Mid-execution review checkpoints have two purposes:
Catching drift as early as possible. If Task Group 1 (database schema) already deviates from a constraint — for example a column that should be hashed is instead stored in plaintext — it’s cheaper to fix it before Task Groups 2 and 3 are built on top of the wrong schema, compared to discovering this problem after the entire feature is done.
Verifying the plan is still relevant. Sometimes implementing the first task reveals that an assumption in the plan was wrong — for example the planned index turns out insufficient for the needed query pattern. A checkpoint provides the opportunity to adjust the next tasks before continuing, rather than discovering this problem after all tasks are done based on a wrong assumption.
flowchart LR
A[Task Group 1] --> B[Review Checkpoint]
B -- OK --> C[Task Group 2]
B -- Problem Found --> D[Fix/Adjust the Plan]
D --> C
C --> E[Review Checkpoint]
E -- OK --> F[Task Group 3]
E -- Problem Found --> G[Fix/Adjust the Plan]
G --> FThe checkpoint frequency doesn’t have to be uniform for all types of work. Task groups touching data schemas or security deserve stricter verification than cosmetic task groups. Calibrate the review rigor level per risk, not applying one review standard to all types of changes.
Keeping the Spec in Sync with Code
A spec accurate when written can quickly go stale once implementation runs and finds details unanticipated at the start. This problem isn’t new — stale documentation has been a common complaint long before AI coding agents existed. But in SDD, this problem is more serious because the spec isn’t just passive documentation — the spec is repeatedly used as a reference by agents in subsequent sessions.
A stale spec is dangerous in a subtle way: an agent in a later session will read the spec, trust it as accurate, and make decisions based on information no longer matching the actual code. The result is hard-to-trace inconsistency, because the problem source isn’t in the newly written code, but in the old spec never updated.
The most effective strategy to prevent this is making spec updates part of the “done” definition for every task, not a separate step easily skipped:
Definition of Done per Task Group:
□ Related acceptance criteria are met and verified
□ Automated tests are added/updated
□ If the implementation deviates from the initial plan (e.g. the technical
approach changed), spec.md or plan.md is updated to reflect the final decision
□ If new requirements are found not covered by the initial spec,
they're added to the spec before the task is considered done
This practice changes the relationship between spec and code from one-way (spec determines code) to two-way (spec determines code, but findings during implementation also flow back to update the spec). A spec maintained this way stays useful as an accurate reference for later sessions — whether by the same agent or newly joining developers.
Treat changes to the spec with the same level of attention as changes to code — reviewed, not just freely edited. A spec anyone can change without review will lose its authority as the source of truth.
Handling Specs That Change Mid-Implementation
Requirements changing midway are an unavoidable reality, not a sign of a failed process. Stakeholders change their minds, competitors release new features shifting priorities, or the team discovers technical constraints invisible at the start. The question isn’t how to prevent changes, but how to handle them without damaging the consistency of work already in progress.
There are several handling patterns depending on how far the implementation has progressed when the change happens:
Changes before implementation starts — the cheapest. Update the spec, re-review, regenerate the plan if needed. No code needs to be torn down.
Changes after some task groups are done — needs an impact evaluation. Which task groups are still valid, which need revision, which must be discarded. The spec is updated by clearly marking which parts changed from the previous version, so the continuing agent knows which task groups need re-review.
Spec: Self-Service Password Reset (v2)
CHANGELOG:
- v2: Adding an optional MFA constraint for accounts with active 2FA
(see the new Task Group 5). Task Groups 1-4 are unaffected.
[full spec content...]
Task Group 5: 2FA Integration (NEW in v2)
5.1 If an account has active 2FA, the password reset must still require
2FA verification after the new password is stored
Changes after the entire feature is done and in production — this is no longer “mid-implementation changes”, but a new requirement needing its own spec-driven cycle, starting from the spec phase again, not patched directly into code without process.
What must be maintained in all these scenarios: change history stays recorded (a simple changelog suffices), and already-verified task groups don’t silently change meaning without explicit marking.
Anti-Patterns in Execution
Several habits often ruin the spec-driven workflow even when the spec itself is well written:
One-shot entire complex features. Already mentioned above, but common enough to re-emphasize: asking the agent to complete the entire plan in one big execution without review pauses removes the main advantage of breaking work into task groups.
Skipping the plan phase. Going directly from spec to “write the code”, without an explicit phase translating the spec into a task sequence. A good spec can still produce messy code if its execution isn’t structured.
Ignoring spec updates after implementation deviates. Teams often feel updating the spec is “administrative work” that can be postponed. In practice, this postponement almost always means the spec is never updated at all, and becomes a source of confusion in later sessions.
Review checkpoints too rare or too frequent. Reviewing every line of code removes the advantage of delegating to the agent; reviewing only at the end loses the advantage of catching drift as early as possible. Calibrate the frequency per task group risk, as discussed in the checkpoint section.
A plan written once then treated as immutable. A plan is a work plan, not a contract that can’t be touched. If implementation reveals that the task order needs adjusting, the plan should adjust too — not be forced to follow an order that’s no longer relevant.
The clearest sign a spec-driven workflow is running well isn’t “changes never happen”, but “changes are always reflected in the spec before or at the same time as the code changes” — not code silently deviating while the spec lags behind.
Summary
- The spec determines what must be correct; the plan translates it into a work sequence in task groups each independently verifiable
- Ideal task granularity: large enough to be meaningful, small enough to review without re-understanding the entire feature context
- Effective prompting patterns explicitly reference the spec and plan files, ask for one task group at a time, and insert review pauses — not asking for the entire feature at once
- Review happens mid-execution (checkpoints per task group), not only at the end — this catches drift from the spec as early as possible before it spreads to the next tasks
- Updating the spec is part of each task’s definition of done, not a separate administrative step easily skipped
- Requirements changing mid-implementation are handled by evaluating the impact on completed tasks, updating the spec with a clear changelog, and marking which tasks need re-review
- Avoid one-shot execution for complex features, skipping the plan phase, and letting the spec go stale after implementation deviates from the initial plan