| name | write-spec |
| description | 새 feature의 외부 관찰 가능한 동작(WHAT)을 사용자와 대화하며 spec.md로 확정한다. 요구사항이 모호하거나 여러 화면·경로에 걸친 다단계 feature를 정의하려는 신호가 보이면 트리거한다. 버그 수정, 한 줄 변경, 이미 구체적인 요구에는 쓰지 않는다. "/write-spec", "스펙 작성", "기능 정의"로도 호출한다. |
| argument-hint | feature description |
Write Spec
새 feature의 외부 관찰 가능한 동작(WHAT)을 사용자와 대화하며 확정한다.
spec은 시스템을 블랙박스로 놓고, 그 경계면에서 "완료"를 판정하는 기준에 사용자와 합의하는 문서다. spec의 판정 기준이 유일한 원본이 되고, plan과 테스트는 ID로 이를 참조한다.
Inputs / Outputs
| 입력 | 출력 |
|---|
$ARGUMENTS (feature 설명), 참조 이미지는 artifacts/<feature>/references/에 | artifacts/<feature>/spec.md (WHAT 전용 스펙) |
구현 선택(파일 배치, 스키마, 라이브러리, 테스트 유형)은 spec.md에 넣지 않는다. 그 결정은 plan.md의 몫이다. 경계를 지키지 않으면 구현을 바꿀 때마다 spec을 고치게 된다.
Workflow
Step 1. Pre-exploration
이미 내린 결정을 뒤집지 않기 위해, 질문을 시작하기 전에 존재하는 맥락을 읽는다.
순서:
artifacts/<feature>/idea.md: 이미 결정된 방향과 원칙
artifacts/<feature>/spec.md: 이전 논의 기록 (있다면)
artifacts/<feature>/references/: 참조 자료가 있다면 구조와 정보 계층 파악
- 코드베이스의 관련 기능: 기존 구현·패턴·데이터 모델을 보고 이번 feature가 어디에 얹힐지 감을 잡는다
완전히 새로운 feature라 1~3이 없으면 4부터 시작한다.
Step 2. Surface & Reframe
질문하기 전에 두 가지를 사용자에게 보여주고 확인받는다. 코드를 쓰기 전에 오해를 드러내기 위해서다.
- 내가 지금 가정하고 있는 것: 사용자가 말하지 않았지만 내가 채우고 있는 빈칸
- 모호한 목표의 측정 가능한 재진술: 해당하는 경우에만
출력 형식
내가 지금 가정하고 있는 것:
1. 로그인한 사용자만 대상 (게스트 지원 안 함)
2. 모바일·데스크톱 동시 지원
재진술 (모호 → 측정 가능):
- "대시보드를 빠르게" → 4G에서 LCP < 2.5s, 초기 데이터 < 500ms
→ 이대로 진행할까요, 아니면 바로잡을까요?
요구사항이 이미 구체적이면 재진술 블록은 생략한다. 가정은 항상 보여준다. "가정 없음"이라도 그렇게 적는다.
Step 3. Iterative Questioning
$ARGUMENTS에 대한 사용자 흐름을 시뮬레이션하며 빈칸을 찾는다.
시뮬레이션 순서:
- happy path 하나를 먼저 끝까지 그린다
- 그 위에 error paths, boundary conditions, 기존 feature와의 교차를 얹는다
- 각 지점에서 빠진 결정을 기록한다
질문 범위
사용자가 관찰할 수 있는 것(WHAT) 만 묻는다. 파일 경로, 레이어 배치, 테이블 설계, 테스트 전략은 plan.md에서 결정한다.
변경 비용 기반 우선순위
- High cost of change: 권한 경계, 데이터 모델, 사용자 노출 범위, 과금·결제 흐름. 나중에 바꾸면 마이그레이션·공지·재협의가 필요하므로 반드시 묻는다.
- Low cost of change: 카피 문구, 기본 정렬 순서, 에러 메시지 톤. 기본값을 제안하고 사용자가 수정할 여지를 남긴다.
질문 규칙
- 한 번에 한 질문: 2~4개 선택지를 제시하고, 답을 받기 전에는 다음으로 넘어가지 않는다 (사용자가 한 번에 답할 수 있는 분량)
- 이미 답이 있는지 먼저 확인한다: 코드베이스,
idea.md, 이전 spec.md에 있을 수 있다
- 기존 시나리오와 교차하면 명시적으로 언급한다: 사용자가 연결을 놓치지 않게
- 불확실성이 줄지 않으면 다음 단계로 넘어간다: 단, 미탐색 고비용 갈래는 넘어가기 전에 다룬다. 발견이 늦을수록 되돌리기 비용이 커진다.
Step 4. Generate spec.md
references/spec-template.md의 섹션 구조를 따른다. 형식, ID 규칙, 판정 기준 작성 가이드는 template에 있다.
작성 규칙
- WHAT만 쓴다: 파일 경로, 테이블·컬럼명, 라이브러리·프레임워크, 테스트 유형은 spec.md에 나타나지 않는다. 그 결정을 plan.md로 미뤄야 구현이 바뀔 때 spec이 흔들리지 않는다.
- 판정 기준은 외부에서 관찰 가능해야 한다: 사용자가 볼 수 있고 테스트 코드로 검증할 수 있는 것만 쓴다. 내부 state, 함수 호출, DB 행 모양은 허용하지 않는다. 이 경계를 지키면 테스트가 리팩터링에 깨지지 않는다.
- 하나의 판정 기준은 spec에 한 번만 쓴다: plan과 테스트는 ID(
S1, S1-1, INV-1)로 참조한다. 원본이 하나여야 수정할 곳도 하나다.
- ID 안정성 규칙을 지킨다: ID는 추가만 한다(append-only). 재배열·재사용을 금지하고, 삭제는 결번으로 남기고, 의미가 바뀌면 새 ID를 발급한다. 상세는 template의 ID 규칙 참조.
- End-to-end 검증 절차로 문서를 끝맺는다: feature 완료를 실행 증거로 판정하는 사용자 관점의 절차 하나를 쓴다.
- 제외 항목에는 이유를 단다: 미래의 독자가 왜 미뤘는지 알아야 한다.
- 미결정은 사용자가 실제로 결정하지 못한 것만 쓴다: 질문을 안 해서 비어 있는 건 미결정이 아니라 누락이다.
- 여러 시나리오에 동일하게 적용되는 규칙은 불변 규칙으로 묶는다: 단일 시나리오로 담을 수 없는 cross-cutting 규칙(보안·성능·데이터 일관성). 해당 없으면 섹션을 생략한다.
WHAT vs HOW 판정 예시
| 문장 | 판정 | 이유 |
|---|
| 사용자가 이메일로 로그인하면 대시보드로 이동한다 | OK | 관찰 가능한 입력 → 관찰 가능한 결과 |
/api/login 엔드포인트가 JWT를 반환한다 | NG | 구현 수단. plan.md 소관 |
| 완료된 할 일에는 취소선이 표시된다 | OK | 외부에서 보이는 상태 |
Zustand store의 todos가 업데이트된다 | NG | 내부 상태 |
파일명: artifacts/<feature>/spec.md
spec이 확정되면 다음 단계를 새 세션(/clear)에서 시작한다 (필요한 상태는 spec.md가 전부 들고 있다):
- 공간·시각 설계 결정이 필요한 UI feature (예: 새 화면, 새 레이아웃, 화면 간 흐름) →
/sketch-wireframe <feature>
- 그 외 →
/draft-plan <feature>