추측을 드러내기 | Specify
/write-spec 4단계로 가정·모호함·미결정을 코드 전에 드러내고 WHAT만 담은 spec.md를 만듭니다
Overview
Lesson 2에서 SDD의 도구 매핑을 확인했습니다. 이번 레슨은 첫 단계인 Specify 차례입니다.
요구사항 한 줄을 보고 곧장 코드를 쓰면, 빈칸을 추측이 채우게 됩니다. 추측이 코드에 자리 잡으면 나중에 추적할 수 없습니다. /write-spec은 그 추측을 코드 전에 spec.md로 드러냅니다. 4단계로 가정·모호함·미결정 항목을 사용자 앞에 노출한 뒤, WHAT만 담은 spec.md를 만듭니다.
학습 목표
- 가정 검증·고비용 결정 답변·완성된 spec 검토라는 사용자 참여 지점을 구별합니다
- 변경 비용을 기준으로 어떤 질문에 답하고 어떤 결정은 기본값에 맡길지 가릅니다
- G/W/T 구조 · 관찰 가능 성공 기준 · 미결정 정직성 세 가지로 spec.md를 검토합니다
Step 1: 결정된 것 먼저 읽기
examples/requirements.md의 feedme.wiki 요구사항을 입력으로 시작합니다.
/write-spec @examples/requirements.md사전 탐색(Pre-exploration) 단계입니다. AI는 곧장 질문하지 않고, 입력 소스 4개를 차례로 읽으며 이미 결정된 것을 다시 묻지 않도록 맥락을 모읍니다.
| 입력 소스 | 무엇을 읽는가 |
|---|---|
idea.md | 이미 결정된 방향과 원칙 |
이전 spec.md | 이전 논의 기록 |
references/ 이미지 | 참조 자료의 구조·정보 계층 |
| 코드베이스 | 기존 구현·패턴 · 이번 feature가 얹힐 위치 |
AI는 requirements.md의 5줄을 읽고, 코드베이스를 훑어본 뒤 다음 단계로 갑니다.
Step 2: 가정과 모호함 먼저 드러내기
가정·재진술(Surface & Reframe) 단계입니다. AI는 질문하기 전에 자기 가정과 모호한 목표 재진술을 사용자에게 먼저 보여줍니다.
내가 지금 가정하고 있는 것:
1. 사용자는 URL을 직접 붙여넣는다 (북마크릿·확장 프로그램 X)
2. 변환 결과는 서버에 저장하지 않는다 (1회성)
3. 다크모드는 시스템 설정을 따른다
재진술 (모호 → 측정 가능):
- "Markdown 변환" → 페이지 본문(article)을 Markdown으로 추출,
네비게이션·푸터·광고는 제외
→ 이대로 진행할까요, 아니면 바로잡을까요?가정 블록으로 사용자는 AI가 무엇을 추측하는지 확인합니다. 사용자가 "아니, 결과를 저장해야 한다"고 정정하면 그 방향이 spec.md에 반영되고, "맞다"고 하면 spec.md의 전제 조건이 됩니다.
재진술 단계에서 AI가 모호한 목표를 측정 가능한 문장으로 바꿉니다. 요구사항이 이미 구체적이면 이 블록은 생략됩니다. 가정 블록은 "가정 없음"이라도 항상 표시합니다.
Step 3: 변경 비용 높은 결정부터 묻기
단계별 질문(Iterative Questioning) 단계입니다. 가정이 확인되면 AI는 사용자 흐름을 시뮬레이션하며 빈칸을 찾습니다. 모든 빈칸을 다 묻지 않습니다. 바꾸기 어려운 결정만 묻고, 나머지는 기본값을 제안합니다.
변경 비용 높음
묻기: 한 번에 한 질문, 2~4 선택지분류
- 권한 경계 (로그인 / 게스트 / 익명)
- 데이터 모델 (저장 / 일회성)
- 사용자 노출 범위
- 외부 시스템 연결 방식
feedme.wiki 예시
- 변환 실패 시 동작 (재시도 / 에러 / 부분)
- 외부 LLM 열기 (새 탭 / 같은 창)
- 프리셋과 직접 입력 결합 규칙
변경 비용 낮음
기본값: 사용자 수정 여지를 남김분류
- 카피 문구
- 기본 정렬 순서
- 에러 메시지 톤
- 입력 필드 placeholder
feedme.wiki 예시
- 프리셋 순서 (요약 / 번역 / 쉽게 설명)
- 다크모드 기본값 (시스템 설정 따름)
- 다운로드 파일명 패턴
| 분류 | 처리 | feedme.wiki 예시 |
|---|---|---|
| High cost | 한 번에 한 질문, 2~4 선택지 | 변환 실패 시 동작, 외부 LLM 열기 방식, 프롬프트 프리셋과 직접 입력 결합 규칙 |
| Low cost | 기본값 제안, 사용자 수정 여지 | 프리셋 순서, 다크모드 기본값, 다운로드 파일명 |
질문 예시:
변환에 실패했을 때 어떻게 보여주나요?
1. 에러 메시지 + 다시 시도 버튼
2. 에러 메시지만 (사용자가 URL을 수정해 다시 시도)
3. 부분 추출 결과를 표시 (불완전 표시)AI는 한 번에 하나씩 묻고, 답을 받기 전에는 다음으로 넘어가지 않습니다. 불확실성이 더 줄어들지 않으면 다음 단계로 넘어갑니다.
Step 4: WHAT만 담은 spec.md 생성하기
AI는 질문 답변과 가정을 종합해 artifacts/<feature>/spec.md를 생성합니다. 구조는 다음과 같습니다.
| 섹션 | 내용 |
|---|---|
| 개요 | 해결할 문제와 사용자에게 나타나는 변화 |
| 범위 (포함/제외) | 이번 사이클에서 다룰 것 + 의도적으로 제외하는 것의 이유 |
| 시나리오 (Given/When/Then) | happy path + high-cost error branch + 각 시나리오의 성공 기준 |
| 불변 규칙 (선택) | 모든 시나리오에 걸친 보안·성능·데이터 일관성 규칙 |
| 의존성 | 이 작업 시작 전에 존재해야 할 외부 시스템 |
| 미결정 항목 | 사용자가 실제로 결정하지 못한 항목 |
WHAT vs HOW 경계
spec.md에는 사용자가 외부에서 관찰할 수 있는 것(화면·메시지·파일 등 직접 확인 가능한 결과)만 담습니다.
| 문장 | spec.md? | 이유 |
|---|---|---|
| URL을 붙여넣고 변환 버튼을 누르면 페이지 본문이 Markdown으로 결과 영역에 표시된다 | ✅ | 관찰 가능한 입력 → 관찰 가능한 결과 |
defuddle 라이브러리로 본문을 추출한다 | ❌ | 라이브러리 = HOW. plan.md로 |
결과 영역의 <pre> 요소에 Markdown 텍스트가 채워진다 | ❌ | 내부 DOM 구현. plan.md로 |
| Markdown 결과는 5초 이내에 표시된다 | ✅ | 외부에서 관찰 가능한 성능 기준 |
examples/requirements.md에는 defuddle 라이브러리 필수라고 적혀 있지만, spec.md는 "본문을 Markdown으로 추출한다"라는 동작만 담습니다. 라이브러리 이름은 plan.md로 미룹니다. 그러면 더 나은 라이브러리가 나왔을 때 plan만 갈아끼우고 spec은 그대로 둘 수 있습니다.
성공 기준 작성
각 시나리오에 입력 → 관찰 가능한 출력 한 쌍씩 적습니다.
시나리오: 결과 복사
Given Markdown 변환이 완료된 상태
When "복사하기" 버튼 클릭
Then 클립보드에 Markdown 텍스트가 들어가고 "복사됨" 토스트가 표시된다
성공 기준:
- [ ] 변환 결과가 표시된 상태에서 "복사하기" 클릭
→ 클립보드에 Markdown 텍스트 (직접 붙여넣어 동일 내용 확인)
- [ ] 변환 결과가 표시된 상태에서 "복사하기" 클릭
→ "복사됨" 토스트 노출내부 mock 호출이나 state 변화는 성공 기준에 들어가지 않습니다. 관찰 가능한 결과만 담는다는 원칙을 지켜야 리팩터링해도 테스트가 깨지지 않습니다.
Spec 검토 기준
생성된 spec.md를 사용자가 한 번 검토합니다. 위 두 원칙(WHAT vs HOW, 외부 관찰)을 체크리스트 삼아 확인하는 단계입니다. 세 가지 기준만 봅니다.
- 시나리오마다 Given/When/Then 구조가 있는가? "변환이 잘 되어야 한다"처럼 구조가 빠진 항목이 있으면 해당 시나리오를 Given/When/Then 구조로 다시 써달라고 요청합니다.
- 성공 기준이 외부에서 관찰 가능한가? (WHAT vs HOW 경계 적용) "todos 배열이 업데이트된다"는 내부 상태이므로 거부합니다. "리스트에 카드 한 개가 추가되어 보인다"가 정답입니다.
- 미결정 항목이 비어 있지 않은가? AI가 추측으로 채운 항목이 가정이 아니라 미결정으로 분류됐을 수 있습니다. "프롬프트 프리셋이 우측에 표시된다"가 가정인지 결정인지 구분합니다.
핵심 포인트 정리
- 사전 탐색 먼저: 입력 소스 4개를 읽고 이미 결정된 것을 다시 묻지 않습니다.
- 가정·재진술로 추측 드러내기: AI의 가정과 모호한 목표 재진술을 코드 전에 사용자가 확인합니다.
- 변경 비용 기준으로 묻기: high cost는 한 번에 하나만 묻고 low cost는 기본값을 제안합니다.
- spec.md는 WHAT만: 라이브러리·파일 경로·내부 상태는 plan.md로 미루므로 구현이 바뀌어도 spec은 흔들리지 않습니다.
FAQ
-
Q: 요구사항이 이미 구체적이면 가정·재진술 단계를 건너뛰나요?
- A: 가정은 항상 노출합니다. "가정 없음"이라도 그렇게 적습니다. 모호한 목표가 없으면 재진술 블록만 생략됩니다.
-
Q: 변경 비용이 애매한 결정은 어떻게 분류하나요?
- A: "이 결정을 한 달 뒤에 바꾸려면 무엇을 다시 해야 하는가?" 를 떠올립니다. 데이터 마이그레이션·사용자 공지·재협의가 필요하면 high cost입니다. 카피 한 줄만 바꾸면 끝난다면 low cost입니다.
-
Q: spec.md에 라이브러리 이름이 절대 들어가면 안 되나요?
- A: 외부에서 관찰 가능한 것이라면 들어갈 수 있습니다 (예: 사용자에게 노출되는 OAuth provider 이름). 단순 구현 선택은 들어가지 않습니다.
이어서 배울 내용
spec.md가 확정되었습니다. 다음 레슨인 Sketch에서는 spec만으로는 결정할 수 없는 화면 구조를 HTML 와이어프레임으로 정의합니다.