CommunityWriting & Editinggithub.com

Spec-Driven Development Loop (SDDL)

Agent Skill for Spec-Driven Development: Uses a structured Spec as the single source of truth, with dual loops (Formation Loop + Derivation Loop) and C1-C4 consistency checks to upgrade AI programming from conversation-driven to spec-driven.

What is Spec-Driven Development Loop (SDDL)?

SDDL transforms AI-assisted software development from a conversation-driven process into a rigorous, spec-driven engineering discipline. The core idea is to define *what* to build before writing any code, using a structured Spec as the single source of truth. It operates through two interconnected loops: the Formation Loop (exploring requirements, drafting and freezing the spec) and the Derivation Loop (generating tests, code, and docs from the frozen spec, then verifying consistency). Key checkpoints (C1-C4) and automated scripts enforce adherence, preventing common issues like context drift or unsynchronized artifacts. This skill works with any AI agent platform and is especially useful for projects with multiple interfaces or acceptance criteria that require long-lived, auditable specifications.

Works with~Claude Code~Codex CLI~Cursor
npx skills add xt-mahh/sddl

Installed? Explore more Writing & Editing skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

What does Spec-Driven Development Loop (SDDL) do?

Open Source: https://github.com/xt-mahh/sddl (2026-08-06, MIT License) Full methodology + checker scripts + example projects available in the GitHub repository.

Overview

SDDL upgrades AI programming from 'conversation-driven' to 'spec-driven'. Core commitment: First define clearly what to do, then write code — using a structured Spec as the single source of truth, with a dual loop closure ensuring quality and auditability.

Formation Loop (answers 'what to do')       Derivation Loop (answers 'how to do it right')
Requirements ──▶ Interview ──▶ Spec Draft ──▶ Freeze Spec ──▶ tests/code/docs ──▶ Converge
              └─▶ SQC Quality Check ──┘                  └─▶ C1-C4 Consistency Checks ──┘
              └─▶ Decision Point Confirmation ──┘

Why SDDL: The pain points of conversational programming — context drift (forgetting agreements made 50 turns ago), multiple artifact desynchronization (code changes without test/doc updates), and subjective acceptance ('feels right' instead of 'meets spec'). SDDL solves these with a stable, fully loadable Spec + layered consistency checks.

When to Use

Triggers:

  • User wants to start a new project development, write core features, or design system architecture
  • User says 'let's plan', 'let's design', 'let's write a spec', 'how to implement this feature'
  • Tasks requiring multiple synchronized artifacts (code + tests + docs)
  • Project with ≥ 5 interfaces, or ≥ 5 must-level acceptance criteria, expected lifespan > 2 weeks

Not applicable (write code directly, do not use this skill):

  • One-off scripts / prototypes / proofs of concept / exploratory research code
  • Single-file utilities (< 5 interfaces, no multi-artifact requirement)
  • User explicitly says 'just code it' or 'do it quickly'

Phase Commands (core interaction method of this skill):

CommandPhaseActionOutput
/sddl:initInitializationCreate directory structure, read existing code/requirementssddl/ skeleton + state.yaml
/sddl:interviewFormationLayered requirements interview (L0-L2 required)Requirements statement
/sddl:specFormationGenerate L1-L5 spec draft + decision point markersspecs/<domain>/spec.yaml
/sddl:confirmFormationDecision point summary + clarify confirmationdecisions/<domain>-confirmation.yaml
/sddl:freezeFormationSQC check + freezespec_status: frozen
/sddl:deriveDerivationDerive tests/code/docs from specsrc/ tests/ docs/
/sddl:verifyDerivationC1-C4 consistency checks + convergence evaluationchecks/*.json + convergence/routing
/sddl:archiveArchiveChange archiving, spec mergespecs/ update + CHANGELOG

Core Principles

  1. Spec is the oracle, but can be challenged: Spec defects found during derivation → unfreeze → return to Formation Loop for revision → refreeze (full quality gate, no shortcuts)
  2. Determinism first: If static analysis/schema/test execution can solve it, never rely on LLM guessing
  3. Convergence is an engineering system: Hard condition gates + Soft condition consensus rate + Budget constraints + Human override
  4. Decision points are not silent: AI provides defaults for ambiguities + marks decision points, user confirms before freezing
  5. Progress is in the directory: Phase completion = file existence (Convention over Config), free interruption recovery

Directory as State (Convention over Config)

No need to read a state file; the directory shows progress. This is the progress visibility mechanism of this skill (with git commits as checkpoints).

<project>/
├── sddl/
│   ├── specs/                    # Exists = interview complete, spec generated
│   │   └── <domain>/spec.yaml    # status: frozen = freeze complete
│   ├── changes/                  # Change proposals (incremental development, can be parallel)
│   ├── decisions/                # Decision point confirmation records
│   │   └── <domain>-confirmation.yaml
│   ├── checks/                   # Check report archive (machine-readable JSON)
│   │   ├── sqc-<domain>-v1.json
│   │   └── c1-c4-<domain>-v1.json
│   └── state.yaml                # Single metadata file: phase pointer + budget + latest check
├── src/                          # Appears after Derivation Loop
├── tests/                        # Appears after Derivation Loop
├── docs/                         # Appears after Derivation Loop (includes current/planned sections)
└── (git commit after each phase completion)

Minimal state.yaml (stores only pointers, not detailed progress):

spec_status: frozen          # interviewing | drafting | reviewing | frozen | evolved
current_phase: derivation    # formation | derivation | complete
budget: { formation: 40%, implementation: 12%, revision: 100% }
last_check: { type: sqc, spec: auth-v0.1.0, result: pass, at: 2026-08-06T16:00 }

Recovery Rules: When the skill reloads, scan the directory — no specs/ = start from interview; specs/ exists but no decisions/ = start from confirm; decisions/ exists but spec not frozen = start from freeze; src/ exists but no checks/ = start from derive; checks/ exists = start from verify.

Phase completion = git commit (AI assistant helps): After each successful command execution, commit (feat(sddl): interview complete), ensuring traceability.

Dual Loop Process Orchestration

Formation Loop (do the right thing) — 5 commands

/sddl:interview → /sddl:spec → /sddl:confirm → /sddl:freeze
     │              │              │              │
     └─ Revision ──┴──────┴──────┘
       (SQC fails / user changes decision point → return to previous step, max 5 iterations)
CommandKey ActionCheckpoint
interviewLayered questioning L0-L2 (≤10 questions required), produce requirements statementComplete requirements statement
specGenerate L1-L5 spec + decision point markers (register DP for ambiguities)SQC-def skeleton passes
confirmDecision point summary → clarify item-by-item confirmation (including custom input)No pending decision points
freezeFull SQC check + confirmation record signingSQC no blocker + frozen

Derivation Loop (do things right) — 3 commands

/sddl:derive → /sddl:verify → (converge) → complete
     │              │
     └─ Route ─────┘
       (violation → regenerate code/tests/docs or unfreeze back to Formation Loop)
CommandKey ActionCheckpoint
deriveDerive tests/code/docs from specArtifacts runnable
verifyC1-C4 layered checks + convergence evaluationHard gates + Soft consensus + must coverage
archiveChange archiving, spec mergeCHANGELOG + spec update

Checker Scripts (scripts/) — Deterministic Evidence, Not Semantic Judgment

Scripts are only responsible for deterministic evidence (type checks/test execution/symbol tables/YAML), semantic review is performed by the agent's LLM capability:

# SQC deterministic check (Formation Loop gate) — script provides facts
python3 scripts/check_sqc.py sddl/specs/<domain>/spec.yaml --verbose

# C1-C4 deterministic check (Derivation Loop gate) — script provides facts
python3 scripts/check_c1_c4.py . --verbose

# State recovery (after interruption) — scan directory and output current progress + next command
python3 scripts/sddl_status.py .
  • Exit code: 0 = pass/converged, 1 = fail (can be used in CI)
  • --json outputs machine-readable evidence (for LLM review citation)

Division of Responsibilities (important):

LayerResponsible
Deterministic evidence (hard conditions): schema validity/interface existence/test passing/symbol tablesScripts
Semantic review (soft conditions): behavior coverage/THEN assertability/test true coverage/doc authenticityAgent's LLM (see references/llm-review.md)

Do not use heuristic scripts for semantic judgment — string matching will cause false negative explosions (T1 measured C1-sem at 0.48). Scripts are evidence collectors, the agent is the judge.

When to Read Which Reference

Load on demand, not all at once (progressive disclosure):

ScenarioRead
Executing interviewreferences/formation-loop.md (Phase 1)
Generating specreferences/spec-schema.md + templates/spec-template.yaml
SQC checkreferences/sqc-checklist.md (def via script, sem via LLM)
Decision point confirmationtemplates/decision-summary.md
Deriving artifactsreferences/derivation-loop.md (Phases 1-2)
C1-C4 checksreferences/checker-matrix.md (def via script, sem via LLM)
Semantic review operationsreferences/llm-review.md (core: how LLM does review)
Routing/revert/budgetreferences/derivation-loop.md (Phases 3-5)
Change proposalsreferences/formation-loop.md (Change management)

Budget and Degradation

  • Three budgets: formation (2M tokens / 5 iterations) / implementation (15M / 4 sessions) / revision (5M, L2 deducts 10%, L3 deducts 25%, first L3 free)
  • Budget recorded in state.yaml, updated after each command
  • Budget exhausted → switch to human-driven, no automatic degradation (spec quality is the foundation)
  • Degradation paths: D1 Semantic degradation → D2 Move should/could to risk list → D3 Reduce variation → D4 Split spec → D5 Best effort delivery

Experience Guidelines (Important)

  1. Phased commands: Never complete the entire dual loop in a single response — each command is an independent interaction unit with checkpoints between them
  2. Decision points use clarify, custom input explicitly visible: One clarify per decision point, with an explanation of impact; Business choice options ≤3, the 4th slot is fixed for 'Custom Input (Other)' (tested: clarify without auto-Other, choices max 4, must explicitly reserve a slot); question text hints 'For other values, please select Custom Input'; custom user values follow a capture protocol (record value+reason → sync spec → mark confirmation as modified); open-ended decision points use clarify directly without choices
  3. Progress visibility: Report current phase + next step at the beginning/end of each command
  4. State writing: Write state.yaml + git commit after each command ends
  5. Check reports: Write every check (SQC/C1-C4) to checks/*.json, report human-readable summary + machine-readable details

Common Pitfalls

  1. Skipping the Formation Loop and going directly to Derivation — Writing code without freezing the spec = returning to conversational programming. /sddl:freeze is a hard boundary; no derivation without freezing.
  2. Silent decision making on decision points — Not marking DP for ambiguities and directly writing default values = distorting user intent. Any 'choosing for the user' must register a DP.
  3. Checker self-confirmation loop — Trusting AI-applied labels. C1-def must perform structural reverse engineering (parsing test AST), not trust labels.
  4. Absolute semantic check scores — LLM ratings of 0-100 are not reliable. Use Checklist binary classification + voting consensus rate (objective counting).
  5. Revert bypassing quality gates — Directly modifying spec for spec_error = self-relaxing standards. Must unfreeze → return to Formation Loop → refreeze.
  6. State file bloat — Writing all progress into state.yaml = returning to 'document lies'. state.yaml stores only pointers; details are in the files themselves.
  7. No budget recording — Not updating state.yaml budget = cost runaway. Update after each command ends.
  8. Using crude string matching for semantic checks — T1 measured: keyword matching reduces C1-sem to 0.48 (false negative explosion). Prioritize Checklist LLM voting; heuristics only as fallback, and must be semantic (AST extraction of assertions + structured keywords). First iteration results are not trustworthy and require manual review.
  9. Shared state leaks between tests — T1 measured: in-memory store shared across tests causing assertion failures. During derivation, isolated fixtures must be added (autouse reset); test assertions should go through public interfaces, not directly access internal _store.
  10. Pure query functions with side effects — T1 measured: detectDiscrepancy internally modifies status, violating spec B006 (should remain draft). Pure query interfaces (returning reports/queries) must not modify state; C2-sem should check.

Verification Checklist

  • sddl/ directory structure correct (specs/changes/decisions/checks/state.yaml)
  • spec.yaml passes SQC-def (valid schema/complete references/assertability/decision point coverage)
  • All decision points confirmed/modified/delegated (no pending)
  • Confirmation record signed (overall: approved)
  • spec_status: frozen before entering derivation
  • C1-def has performed structural reverse engineering (not trust labels)
  • All hard conditions pass (C1-def/C2-def/C3/C4b-def)
  • Soft condition consensus rates met (c1_sem≥0.95 c2_sem≥0.95 c4a≥0.90 c4b_sem≥0.90)
  • Must-level acceptance criteria 100% covered
  • state.yaml budget updated
  • Phase completion git commit created

One-Shot Recipes

Starting a New Project from Scratch

/sddl:init → /sddl:interview → /sddl:spec → /sddl:confirm → /sddl:freeze
           → /sddl:derive → /sddl:verify → /sddl:archive

Backfilling Spec for Existing Code (Migration Project)

/sddl:init (read existing code) → /sddl:spec (reverse extract current state + mark decision points)
  → /sddl:confirm → /sddl:freeze → /sddl:verify (validate spec↔code consistency)

Incremental Feature Development (Spec Already Frozen)

/sddl:init → write changes/<name>/ proposal → /sddl:confirm (affected decision points)
  → /sddl:freeze → /sddl:derive → /sddl:verify → /sddl:archive

Related Skills

  • writing-plans: Writing implementation plans (SDDL's changes/tasks.md can use it)
  • test-driven-development: TDD is SDDL's verification method (C3 test execution)
  • hermes-agent-skill-authoring: This skill's own authoring guidelines

Related Skills