Spec-Driven Development Loop (SDDL)
오픈소스: https://github.com/xt-mahh/sddl (2026-08-06, MIT License) 전체 방법론 + 검사기 스크립트 + 예제 프로젝트는 GitHub 저장소 참조.
개요
SDDL은 AI 코딩을 "대화 중심"에서 "사양 중심"으로 업그레이드합니다. 핵심 약속: 무엇을 할지 먼저 명확히 정의한 후 코드를 작성 — 구조화된 Spec을 단일 진실 공급원으로 삼아 이중 루프 폐쇄 루프로 품질과 감사 가능성을 보장합니다.
형성 루프("무엇을 할지" 답변) 파생 루프("올바르게 하는 방법" 답변)
요구사항 ──▶ 인터뷰 ──▶ Spec 초안 ──▶ Spec 동결 ──▶ tests/code/docs ──▶ 수렴
└─▶ SQC 품질 검사 ──┘ └─▶ C1-C4 일관성 검사 ─┘
└─▶ 결정 포인트 확인 ──┘
SDDL을 사용해야 하는 이유: 대화형 프로그래밍의 문제점 — 컨텍스트 드리프트(50라운드 대화 후 3라운드 약속을 잊음), 여러 아티팩트 동기화 불일치(코드 변경 시 테스트/문서 미업데이트), 수용 주관화("올바른 느낌"이 "사양 준수"를 대체). SDDL은 안정적이고 전체를 로드할 수 있는 Spec + 계층적 일관성 검사로 세 가지를 해결합니다.
사용 시기
트리거:
- 사용자가 새 프로젝트 개발, 핵심 기능 작성, 시스템 아키텍처 설계를 시작하려 할 때
- 사용자가 "먼저 계획", "먼저 설계", "먼저 사양 작성", "이 기능 어떻게 만들지"라고 말할 때
- 여러 아티팩트(코드+테스트+문서)를 동시에 산출해야 하는 작업
- 프로젝트 인터페이스 ≥ 5개, 또는 must 수준 검수 항목 ≥ 5개, 예상 수명 주기 > 2주
부적합(직접 코드 작성, 이 스킬 사용 금지):
- 일회성 스크립트 / 프로토타입 / POC / 탐색적 연구 코드
- 단일 파일 소형 도구(인터페이스 < 5, 여러 아티팩트 필요 없음)
- 사용자가 명확히 "직접 작성", "빠르게 진행"이라고 말할 때
단계별 명령(이 스킬의 핵심 상호작용 방식):
| 명령 | 단계 | 수행 작업 | 산출물 |
|---|---|---|---|
/sddl:init | 초기화 | 디렉토리 구조 생성, 기존 코드/요구사항 읽기 | sddl/ 뼈대 + state.yaml |
/sddl:interview | 형성 | 계층적 요구사항 인터뷰(L0-L2 필수 응답) | 요구사항 진술 |
/sddl:spec | 형성 | L1-L5 spec 초안 생성 + 결정 포인트 표시 | specs/<domain>/spec.yaml |
/sddl:confirm | 형성 | 결정 포인트 요약 clarify 확인 | decisions/<domain>-confirmation.yaml |
/sddl:freeze | 형성 | SQC 검사 + 동결 | spec_status: frozen |
/sddl:derive | 파생 | spec에서 tests/code/docs 파생 | src/ tests/ docs/ |
/sddl:verify | 파생 | C1-C4 계층 검사 + 수렴 판정 | checks/*.json + 수렴/라우팅 |
/sddl:archive | 아카이브 | 변경 사항 아카이브, spec 병합 | specs/ 업데이트 + CHANGELOG |
핵심 원칙
- Spec은 신탁이지만, 이의 제기 가능: 파생 과정에서 발견된 spec 결함 → 해동 → 형성 루프로 돌아가 수정 → 재동결(전체 품질 게이트 통과, 우회 금지)
- 결정성 우선: 정적 분석/스키마/테스트 실행으로 해결 가능한 것은 절대 LLM 추측을 사용하지 않음
- 수렴은 엔지니어링 시스템: 하드 조건 게이트 + 소프트 조건 합의율 + 예산 제약 + 수동 백업
- 결정 포인트는 무음 처리 금지: 불명확한 부분은 AI가 기본값 제공 + 결정 포인트 표시, 사용자 확인 후 동결
- 진행 상황은 디렉토리: 단계 완료 = 파일 존재(Convention over Config), 중단 복구 무료
디렉토리 = 상태(Convention over Config)
상태 파일을 보지 않고 디렉토리만 봐도 진행 상황을 알 수 있음. 이것이 이 스킬의 진행 상황 가시성 메커니즘입니다(git commit을 체크포인트로 사용).
<project>/
├── sddl/
│ ├── specs/ # 존재 = 인터뷰 완료, spec 생성됨
│ │ └── <domain>/spec.yaml # status: frozen = 동결 완료
│ ├── changes/ # 변경 제안(증분 개발, 병렬 가능)
│ ├── decisions/ # 결정 포인트 확인 기록
│ │ └── <domain>-confirmation.yaml
│ ├── checks/ # 검사 보고서 아카이브(기계 판독 가능 JSON)
│ │ ├── sqc-<domain>-v1.json
│ │ └── c1-c4-<domain>-v1.json
│ └── state.yaml # 유일한 메타데이터: 단계 포인터 + 예산 + 최근 검사
├── src/ # 파생 루프 후 나타남
├── tests/ # 파생 루프 후 나타남
├── docs/ # 파생 루프 후 나타남(current/planned 파티션 포함)
└── (각 단계 완료 시 git commit)
state.yaml 최소화(포인터만 저장, 진행 상황 상세 정보는 저장하지 않음):
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 }
복구 규칙: 스킬 재로드 시 디렉토리 검색 — specs/ 없음 = interview부터 시작; specs/ 있지만 decisions/ 없음 = confirm부터 시작; decisions/ 있지만 spec이 frozen 아님 = freeze부터 시작; src/ 있지만 checks/ 없음 = derive부터 시작; checks/ 있음 = verify부터 시작.
단계 완료 = git commit(보조): 각 명령 성공 종료 후 commit(feat(sddl): interview complete), 되돌리기 가능 보장.
이중 루프 흐름 오케스트레이션
형성 루프(올바른 일 하기) — 5개 명령
/sddl:interview → /sddl:spec → /sddl:confirm → /sddl:freeze
│ │ │ │
└─ 수정 ───────┴──────┴──────┘
(SQC 통과 실패 / 사용자 결정 포인트 변경 → 이전 단계로, 최대 5회)
| 명령 | 주요 작업 | 체크포인트 |
|---|---|---|
| interview | 계층 질문 L0-L2(≤10개 필수 응답), 요구사항 진술 산출 | 요구사항 진술 완전성 |
| spec | L1-L5 spec 생성 + 결정 포인트 표시(불명확 부분 DP 등록) | SQC-def 뼈대 통과 |
| confirm | 결정 포인트 요약 → clarify 항목별 확인(사용자 정의 입력 포함) | 결정 포인트 미대기 상태 없음 |
| freeze | SQC 전체 검사 + 확인 기록 서명 | SQC blocker 없음 + frozen |
파생 루프(일을 올바르게 하기) — 3개 명령
/sddl:derive → /sddl:verify → (수렴) → 완료
│ │
└─ 라우팅 ─────┘
(위반 → code/tests/docs 재파생 또는 해동 후 형성 루프로 복귀)
| 명령 | 주요 작업 | 체크포인트 |
|---|---|---|
| derive | spec에서 tests/code/docs 파생 | artifacts 실행 가능 |
| verify | C1-C4 계층 검사 + 수렴 판정 | 하드 게이트 + 소프트 합의 + must 커버리지 |
| archive | 변경 사항 아카이브, spec 병합 | CHANGELOG + spec 업데이트 |
검사기 스크립트(scripts/) — 결정적 증거, 의미론적 판단 아님
스크립트는 결정적 증거만 담당(타입 검사/테스트 실행/심볼 테이블/YAML), 의미론적 검토는 agent의 LLM 능력이 수행:
# SQC 결정적 검사(형성 루프 게이트) — 스크립트가 사실 제공
python3 scripts/check_sqc.py sddl/specs/<domain>/spec.yaml --verbose
# C1-C4 결정적 검사(파생 루프 게이트) — 스크립트가 사실 제공
python3 scripts/check_c1_c4.py . --verbose
# 상태 복구(중단 후) — 디렉토리 스캔하여 현재 진행 상황 + 다음 명령 출력
python3 scripts/sddl_status.py .
- 종료 코드: 0 = 통과/수렴, 1 = 실패(CI 연결 가능)
--json출력 기계 판독 가능 증거(LLM 검토 참조용)
업무 분담 원칙(중요):
| 계층 | 담당자 |
|---|---|
| 결정적 증거(하드 조건): 스키마 유효성/인터페이스 존재/테스트 통과/심볼 테이블 | 스크립트 |
| 의미론적 검토(소프트 조건): 동작 커버리지/THEN 단정 가능/테스트 진정한 커버리지/문서 진실성 | agent의 LLM(references/llm-review.md 참조) |
스크립트 휴리스틱으로 의미론적 판단하지 말 것 — 문자열 매칭은 거짓 음성 폭발(T1 실측 C1-sem 0.48). 스크립트는 증거 수집기, agent는 심판.
언제 어떤 Reference를 읽을까
필요에 따라 로드, 한 번에 모두 읽지 않음(점진적 공개):
| 시나리오 | 읽을 문서 |
|---|---|
| interview 실행 | references/formation-loop.md(단계 1) |
| spec 생성 | references/spec-schema.md + templates/spec-template.yaml |
| SQC 검사 | references/sqc-checklist.md(def는 스크립트, sem은 LLM) |
| 결정 포인트 확인 | templates/decision-summary.md |
| artifacts 파생 | references/derivation-loop.md(단계 1-2) |
| C1-C4 검사 | references/checker-matrix.md(def는 스크립트, sem은 LLM) |
| 의미론적 검토 작업 | references/llm-review.md(핵심: LLM이 검토하는 방법) |
| 라우팅/재작성/예산 | references/derivation-loop.md(단계 3-5) |
| 변경 제안 | references/formation-loop.md(변경 관리) |
예산 및 다운그레이드
- 세 가지 예산: formation(2M 토큰 / 5회) / implementation(15M / 4 sessions) / revision(5M, L2 10% 차감, L3 25% 차감, 최초 L3 무료)
- 예산은 state.yaml에 기록, 각 명령마다 업데이트
- 예산 소진 → 수동 전환, 자동 다운그레이드 없음(spec 품질은 기초)
- 다운그레이드 경로: D1 의미론적 다운그레이드 → D2 should/could를 위험 목록으로 이동 → D3 변이 축소 → D4 spec 분할 → D5 최선의 노력 전달
경험 규칙(중요)
- 단계별 명령: 절대 한 번의 응답에 전체 이중 루프를 실행하지 않음 — 각 명령은 독립적인 상호작용 단위이며, 사이에 체크포인트가 있음
- 결정 포인트는 clarify 사용, 사용자 정의 입력은 명시적으로 표시: 각 결정 포인트당 하나의 clarify, 영향 설명 첨부; choices 비즈니스 옵션 ≤3개, 4번째는 고정으로 "사용자 정의 입력(Other)" 배치(실측 시 clarify에 자동 Other 없음, choices 상한 4개, 명시적 점유 필요); question 텍스트에 "다른 값은 사용자 정의 입력을 선택하세요" 안내; 사용자 정의 값은 캡처 프로토콜 사용(value+reason 기록 → spec 동기화 → 확인 레코드에 modified 표시); 개방형 결정 포인트는 choices 없는 clarify 직접 사용
- 진행 상황 가시성: 각 명령 시작/종료 시 현재 단계 + 다음 단계 보고
- 상태 쓰기: 각 명령 종료 시 state.yaml 작성 + git commit
- 검사 보고서: 각 검사(SQC/C1-C4)마다
checks/*.json작성, 가독 가능 요약 + 기계 판독 가능 상세 정보 보고
일반적인 실수
- 형성 루프 건너뛰고 직접 파생 — Spec이 동결되지 않은 상태에서 코드 작성 = 대화형 프로그래밍으로 회귀.
/sddl:freeze는 하드 경계이며, 동결되지 않으면 파생하지 않음. - 결정 포인트 무음 결정 — 불명확한 부분을 DP 표시 없이 기본값으로 직접 작성 = 사용자 의도 왜곡. "사용자를 대신한 선택"은 반드시 DP를 등록해야 함.
- 검사기 자기 증명 루프 — AI가 붙인 태그를 신뢰. C1-def는 반드시 구조 역추론(테스트 AST 파싱)을 수행해야 하며, 태그를 신뢰하지 않음.
- 의미론적 검사 절대 점수 — LLM이 0-100점을 매기는 것은 신뢰할 수 없음. Checklist 이분법 + 투표 합의율(객관적 집계)을 사용.
- 재작성 시 품질 게이트 우회 — spec_error를 직접 spec에 반영 = 자기 기준 완화. 반드시 해동 → 형성 루프로 복귀 → 재동결.
- 상태 파일 비대화 — 모든 진행 상황을 state.yaml에 기록 = 다시 "문서 거짓말". state.yaml은 포인터만 저장하며, 상세 정보는 파일 자체에 있음.
- 예산 미기록 — state.yaml 예산을 업데이트하지 않음 = 비용 통제 불능. 각 명령 종료 시 업데이트.
- 의미론적 검사에 거친 문자열 매칭 사용 — T1 실측: 키워드 매칭이 C1-sem을 0.48로 낮춤(거짓 음성 폭발). Checklist LLM 투표를 우선 사용; 휴리스틱은 fallback으로만 사용하며, 의미론화(AST로 단정 추출 + 구조화된 키워드)해야 하며, 첫 번째 결과는 신뢰할 수 없으므로 수동 재확인 필요.
- 테스트 간 공유 상태 누출 — T1 실측: 메모리 store가 테스트 간 공유되어 단정 실패 발생. 파생 시 반드시 격리 fixture(autouse 리셋) 추가; 테스트 단정은 공개 인터페이스를 통해 수행하며, 내부
_store에 직접 접근하지 않음. - 순수 조회 함수에 부작용 — T1 실측:
detectDiscrepancy내부에서 status 변경이 spec B006 위반(draft 유지해야 함). 순수 조회 인터페이스(보고서/조회 반환)는 상태를 수정해서는 안 되며, C2-sem에서 검사해야 함.
검증 체크리스트
-
sddl/디렉토리 구조 올바름(specs/changes/decisions/checks/state.yaml) - spec.yaml이 SQC-def 통과(schema 유효성/참조 완전성/단정 가능성/결정 포인트 커버리지)
- 모든 결정 포인트 confirmed/modified/delegated(대기 상태 없음)
- 확인 기록 서명(overall: approved)
- spec_status: frozen 후에만 파생 진행
- C1-def가 구조 역추론 수행(신뢰 태그 아님)
- 하드 조건(C1-def/C2-def/C3/C4b-def) 모두 통과
- 소프트 조건 합의율 목표 달성(c1_sem≥0.95 c2_sem≥0.95 c4a≥0.90 c4b_sem≥0.90)
- must 수준 검수 항목 100% 커버
- state.yaml 예산 업데이트됨
- 단계 완료 git commit 생성됨
원샷 레시피
신규 프로젝트 처음부터 시작
/sddl:init → /sddl:interview → /sddl:spec → /sddl:confirm → /sddl:freeze
→ /sddl:derive → /sddl:verify → /sddl:archive
기존 코드에 spec 역추적(리팩토링 프로젝트)
/sddl:init(기존 코드 읽기) → /sddl:spec(현재 상태 역추출 + 결정 포인트 표시)
→ /sddl:confirm → /sddl:freeze → /sddl:verify(spec↔code 일관성 검증)
증분 기능 개발(spec 이미 동결됨)
/sddl:init → changes/<name>/ 제안 작성 → /sddl:confirm(영향 받는 결정 포인트)
→ /sddl:freeze → /sddl:derive → /sddl:verify → /sddl:archive
관련 Skill
writing-plans: 구현 계획 작성(SDDL의 changes/tasks.md에 사용 가능)test-driven-development: TDD는 SDDL의 검증 수단(C3 테스트 실행)hermes-agent-skill-authoring: 본 스킬 자체의 창작 규칙