Spec-Driven Development: How I Enabled AI Agents to Independently Deliver Features

The author details a Spec-Driven Development (SDD) practice that structures a .specs repository with state-gated phases, four-file feature specs, evidence grading, and reusable skills to let AI agents independently investigate, design, implement, and verify features while reserving business decisions and external side effects for human approval.

inShocking
inShocking
inShocking
Spec-Driven Development: How I Enabled AI Agents to Independently Deliver Features

When handing full requirements to an AI agent, the author found they still spent most of their time in the chat window supplying business context, correcting state meanings, and pointing out cross-repository entry points. The agent wrote code quickly, but the human remained the navigator. This approach broke down for cross-repository, multi-day work: earlier conversations were compressed, verbal agreements lost, and solutions from unrelated tasks leaked in via similar keywords.

The Core Problem: Missing Durable Business Facts

The author worked on a multi-repo AI customer-service product. Product docs, source code, logs, and chat records each held partial knowledge, but none alone captured how a requirement should be implemented. Docs state desired behavior; code shows current behavior; logs prove a past event in one environment. A database field value of 0 might come from upstream or be a service default; a mock success does not guarantee the external platform accepts the real state. The root cause: the project lacked a durable source of business facts that an agent could rely on across sessions.

SDD: Treating Spec as the Business Fact Source

SDD (Spec-Driven Development) became the answer. The author did not adopt openspec or superpower wholesale. Instead, they created a dedicated .specs repository with a practical standard: a new session or a new agent must be able to learn from the Spec how the system should behave, what the conclusion is based on, how far execution may proceed, and which questions still require a human decision. The Spec must record approved versions, unknowns, verification results, and what happened when the real environment overturned a design assumption.

The Spec evolves with development: investigation notes, design approvals, tasks, test results, sandbox failures, and production observations are all persisted. Chat remains for discussion, but every decision that affects code behavior is ultimately committed to Git.

Three Boundaries for the Agent

Approved behavior: can complete independently.
New business judgment: must hand back to human.
Unauthorized external side effects: must not execute.

These boundaries define the division of labor. The agent handles document lookup, code reading, call-chain tracing, design, task breakdown, test writing, implementation, and evidence collection. The human participates in business semantics, design trade-offs, risk authorization, and final acceptance.

Evolution of the .specs Repository Structure

The structure grew from real pain points, not upfront design. First, an independent spec repository was created because requirements often span multiple code repos; placing specs in any single repo would miss context. Cross-repo intent is linked via a CHANGE-ID.

.specs/
├── project/      # long-term boundaries, roadmap, current status
├── codebase/     # architecture, repo responsibilities, integrations, test baselines, risks
├── features/     # one CHANGE-ID per requirement
├── incidents/    # one INC-ID per production incident
├── quick/        # low-risk quick changes
├── templates/    # Spec, Design, Tasks, Evidence templates
└── scripts/      # structure and consistency checks
project/

and codebase/ hold only long-lived, reusable information. A requirement's local design stays in its feature; an incident's transient observations do not become global rules.

Agents do not read the entire repo at once. They start with project status and relevant code maps, then enter the current feature. Only when execution requires it do they load Design, Tasks, and Evidence. This loading order reduces context contamination — reading too much can introduce irrelevant old designs.

Four-File Feature Structure

A complete feature gradually split into four files: spec.md — Approved business behaviors, boundaries, and open questions design.md — Code entry points, state flows, external contracts, idempotency, rollback tasks.md — Independently completable and verifiable implementation tasks evidence.md — Code, test, sandbox, acceptance, and production observation evidence

Initially everything went into one document, but as complexity grew maintenance became hard. Worse, design discoveries silently altered business rules. Separation enforces that Design may adjust implementation but cannot change Spec; Evidence may prove a design failed but cannot choose the next production path.

State Machine Governing Agent Permissions

INTAKE → CLARIFIED → SPEC_REVIEW → APPROVED
→ DESIGNED → IMPLEMENTING → VERIFIED → ACCEPTED

Each state directly limits what the agent may do: INTAKE: may investigate, may not modify business code. SPEC_REVIEW: may continue clarification, may not close business questions autonomously. Only after explicit Spec approval may Design and Tasks be written. IMPLEMENTING: executes only mapped tasks. VERIFIED: evidence is ready, but still awaits business acceptance and production observation.

States can move backward. When the real environment invalidates a design premise, the feature returns to review. Without this escape hatch, agents tend to treat task completion as irreversible forward progress and guess alternative paths when blocked.

Evidence Grading: Four Fixed Labels

Agents often conflate code observations, log findings, stakeholder statements, and their own inferences into a single "fact" tier. The author fixed four labels: VERIFIED_CODE: cross-checked against source, config, or commit. VERIFIED_RUNTIME: proven by logs, queries, or real replay. BUSINESS_CONFIRMED: a decision-maker confirmed the rule. HYPOTHESIS: current investigation direction, not implementable.

Source code shows how code is written, not whether a production toggle is on; runtime logs prove one occurrence, not future behavior; business confirmation defines new rules but cannot prove the system already satisfies them.

End-to-End Traceability

Every Spec behavior carries a stable Requirement ID, chained as:

Requirement → Design → Task → Code/Test → Evidence → Acceptance

A Task without a matching Requirement likely exceeds scope. A Requirement without test and evidence cannot be considered done just because code was committed. Branches, commits, code reviews, and test records all reference the same CHANGE-ID@version, so a new agent never needs to reconstruct the requirement from chat and Git history.

Walk-Through: Ticket Auto-Reflow Feature

The author illustrates the flow with a real (sanitized) requirement: extend the existing auto-reflow rule from state Y to state X. The initial instruction to the agent:

Use sdd-feature-intake for CHANGE-ID.
Confirmed acceptance semantics:
WHEN target ticket is executed in state X by non-target-group member
THEN system SHALL reopen auto-reflow
AND rule SHALL stay consistent with existing state Y reflow.

Read original requirement doc and .specs historical evidence; locate entry points, state checks, operator identity checks, messages, scheduled jobs, DB/Redis fields in local code.
First confirm which repo and target branch to modify; do not guess from past requirements.
Prefer reusing state Y's existing path; explicitly address idempotency, concurrency, manual assignment, and non-target ticket boundaries.
Output Spec, unknowns, acceptance rules, test plan, and effort estimate.
Do not modify business code before I approve Spec.

The agent discovered message entry, delayed job, state enum, Redis record, and external ticket call. The legacy flow was complete: message registers task, scheduled job scans due records, checks ticket status, reopens, then reassigns.

Gaps emerged: the task only stored initial assignees, not the later operator who executed state X. External API docs promised reopen for state Y but not for state X. Duplicate reassignment messages could reset the wait timer.

The Spec therefore added boundary questions: whether target-group member executing state X keeps status quo; from which state to restart; whether to clear reason and history; how to handle duplicate messages, duplicate operations, concurrent reassignments; whether normal, already-closed, and manually-assigned tickets are affected; whether to wait or proceed when identity lookup fails.

Parts provable from old rules and source code the agent proposed directly; business-outcome-changing items stayed in a Q-table for human confirmation. The author only intervened on a few boundary choices.

Final approval recorded version, chosen design, and failure condition:

Approved [email protected], adopting Design B.
State X reuses existing reopen path and validates external contract in sandbox.
If external platform rejects, record deviation and stop; do not attempt alternative write operations.

After approval, the agent produced Design and Tasks. Tests were written before implementation: non-target member triggering state X must reflow; target member self-action stays unchanged; identity lookup failure must not default to non-target; duplicate messages must not reset wait time; state Y's old rule must not regress; reopen failure must not continue handover; delayed task must not overwrite concurrent manual reassignment.

Implementation, targeted regression, compilation, commit, and sandbox deployment followed. Each completed Task updated its status and Evidence together.

Sandbox verification used a test-marked ticket. Message recognition, operator identity judgment, and delayed task routing all worked.

When the real external ticket platform was called, it returned a business rejection: state X cannot execute reopen.

Internal code and tests matched the approved design, yet the real environment invalidated the design premise. The agent logged request, response, and unexecuted follow-up actions, marked SPEC_DEVIATION, returned the Spec to review, and stopped.

Static analysis passed, unit tests passed, build succeeded, sandbox consumer recognized real messages, but the external contract did not support the final action. These layers are not contradictory — each answers a different question.

The requirement did not ship. How far the code got, why it stopped, and who must decide the next round all remain under the same CHANGE-ID. A new session can continue without re-reading chat logs.

This confirmed SDD can support independent agent development. It does not guarantee every design succeeds, but it ensures failure stops where evidence permits.

Skills: The Execution Layer Added Later

After the knowledge structure and gates worked, the author codified repeated workflows into five Skills: sdd-feature-intake — Build reviewable Spec from raw request; forbid business code changes before approval sdd-feature-delivery — Execute Design, Tasks, implementation, tests, and Evidence per approved version; return to review on deviation sdd-incident-repair — Convert confirmed root cause into independent permanent-fix Feature sdd-quick-change — Lightweight path for single-repo, clear-rule, very-low-risk changes sdd-continue-work — Restore approved version, task state, blockers, and next steps from Git; never resume from chat memory alone

They fix document reading order, state gates, stop conditions, and maintenance patterns so the agent does not re-learn the author's habits each time. sdd-feature-intake preserves raw intent, separates fact from hypothesis, and surfaces only acceptance-changing questions to the human. sdd-feature-delivery verifies Spec approval before design/implementation and returns to review on deviation. sdd-continue-work rebuilds context from Git, not chat memory.

Incidents follow a separate track via sdd-incident-repair: first capture impact, timeline, facts, hypotheses, and mitigation; only after root cause confirmation spin up a Feature. This prevents transient incident phenomena from becoming permanent business rules. sdd-quick-change has a strict threshold: any touch to messaging, RPC, ticket state, Redis, database, config, permissions, PII, or cross-repo dependency upgrades it to a full Feature. A one-line code change can still carry high business risk.

These Skills emerged from recurring problems. Without them, a team can still manually execute the same SDD; Skills merely make the agent follow the process reliably.

Problems Solved

Context feeding (where to look next, which conclusion to distrust, what the other repo holds) is now largely self-service for the agent.

Human involvement narrowed to: confirming goals and non-goals, choosing outcome-changing designs, authorizing environment/production writes, and business acceptance.

Long tasks resume easily: given a CHANGE-ID, the agent reconstructs state from Spec, Design, Tasks, Evidence, and code repo status. Chat history remains but is no longer the sole memory.

Testing transparency improved: local unit tests, cross-repo contracts, async messages, sandbox, business acceptance, and production observation are recorded separately. Success at one layer closes only that layer's risk.

Remaining Gaps

STATE

and ROADMAP files occasionally lag behind individual features. Current convention: feature directory is authoritative; global files serve navigation.

Historical samples show version mismatches across spec.md, design.md, tasks.md, and evidence.md. Familiar humans can judge, but a fresh agent may read the wrong approved baseline.

Validation scripts only check basic file presence, Status, Version, and Requirement ID. They do not yet verify that every Requirement has a Task, test, and Evidence, nor that state transitions are legal.

Sanitization relies on Skill constraints, agent self-check, and pre-commit scans. Accounts, ticket numbers, IPs, internal links, and credentials need stricter automated gates.

The author plans to add cross-file version consistency, Requirement coverage checks, sensitive data scanning, and content hashes for approved Specs. If build artifacts and runtime logs carry the hash, production behavior can trace back to the exact approved specification.

If Starting Over

Do not build five Skills first; do not build a platform first.

Create a .specs directory with four templates: spec.md, design.md, tasks.md, evidence.md.

Team agrees on three rules: no business code changes before Spec approval; commits reference Spec version; any out-of-spec fact forces a stop and return to review.

Pick one medium-complexity real requirement — ideally with an existing rule to reference and one or two boundaries needing human confirmation. Too simple shows no difference; too many systems on the first try inflates process cost.

Run one requirement end-to-end, then add state validation and interrupt recovery. When an incident occurs, split Incident and permanent fix; when a genuine low-risk tweak appears, design Quick Change. Extract Skills from recurring pain.

The author's SDD is still evolving. One certainty: independent agent development cannot rely on longer prompts alone. The agent must know which spec version it works against, which facts are proven, which decisions it lacks authority to make, and how to preserve the scene when a deviation appears. Only when that information stabilizes can the human truly step away from the chat window.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

AI Agentssoftware engineeringstate machineRequirements EngineeringSpec-Driven DevelopmentSDDEvidence-Based DevelopmentAutonomous Development
inShocking
Written by

inShocking

Occasional sharing

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.