1일차 4교시: Specify 작성 워크숍
이 교시는 무엇을 만들 것인가와 왜 필요한가를 문서화하는 시간입니다. 설계서 기준으로 /speckit.specify는 constitution을 참조하여 spec을 만들고, 모호한 항목에는 [NEEDS CLARIFICATION]를 남깁니다.
교시 목표
- /speckit.specify에 넣어야 할 내용을 설명할 수 있다.
- constitution과 specify의 차이를 말할 수 있다.
- specify와 plan의 차이를 말할 수 있다.
- 좋은 기능 설명과 나쁜 기능 설명을 구분할 수 있다.
/speckit.specify의 역할
specify는 사용자 관점의 요구사항 문서를 만드는 단계입니다.
여기에는 보통 다음이 들어갑니다.
- 누가 쓰는가
- 어떤 문제를 해결하는가
- 사용자가 어떤 행동을 할 수 있어야 하는가
- 어떤 규칙과 제약이 있는가
- 성공을 어떻게 확인할 것인가
/speckit.constitution과 무엇이 다른가
- constitution은 프로젝트 전체의 원칙
- specify는 이번 기능의 요구사항
예를 들어 테스트 없는 기능은 완료로 보지 않는다는 constitution입니다.
반면 사용자는 태그를 추가, 삭제, 필터링할 수 있어야 한다는 specify입니다.
/speckit.plan과 무엇이 다른가
- specify는 무엇을 왜
- plan은 어떻게
예를 들어 태그는 한 Todo에 중복으로 붙을 수 없다는 specify입니다.
반면 TodoTag 조인 테이블을 두고 SQLite UNIQUE 제약을 건다는 plan입니다.
좋은 입력의 구조
아래 요소를 넣으면 초심자도 비교적 안정적으로 spec을 만들 수 있습니다.
- 사용자 또는 역할
- 해결하려는 문제
- 핵심 시나리오
- 비즈니스 규칙
- 수용 기준 힌트
다양한 입력 예시
예시 1: Todo 태그 기능
사용자가 Todo 항목에 태그를 붙여 분류할 수 있는 기능을 정의해줘.
- 대상 사용자: 개인 사용자
- 목적: 할 일을 맥락별로 분류하고 빠르게 찾기 위해
- 핵심 행동: 태그 추가, 태그 제거, 태그별 필터링, 태그 목록 보기
- 규칙: 같은 태그를 한 항목에 중복으로 붙일 수 없다
- 규칙: 태그 이름은 20자 이하
- 기대 결과: 태그를 사용해 Todo를 보기 쉽게 분류할 수 있어야 한다
예시 2: 사진 앨범 정리 앱
사용자가 사진을 앨범으로 정리할 수 있는 앱의 기능 명세를 작성해줘.
- 대상 사용자: 개인 사용자
- 목적: 많은 사진을 날짜와 주제별로 정리하기 위해
- 핵심 행동: 앨범 생성, 앨범 이름 변경, 사진 이동, 앨범 정렬 변경
- 규칙: 앨범 안에 다른 앨범을 넣을 수 없다
- 규칙: 사진은 업로드 시 원본 촬영일을 유지해야 한다
- 기대 결과: 사용자가 여러 장의 사진을 빠르게 찾아볼 수 있어야 한다
예시 3: 교육용 과제 제출 기능
학생이 과제를 제출하고 제출 이력을 확인할 수 있는 기능 명세를 작성해줘.
- 대상 사용자: 학생, 강사
- 목적: 마감 전 제출과 수정 이력을 명확히 관리하기 위해
- 핵심 행동: 과제 제출, 재제출, 제출 시간 확인, 제출 상태 확인
- 규칙: 마감 이후에는 제출할 수 없다
- 규칙: 학생은 자신의 제출만 볼 수 있다
- 기대 결과: 강사는 누가 언제 어떤 버전으로 제출했는지 확인할 수 있어야 한다
나쁜 입력과 이유
나쁜 예 1
React와 FastAPI로 태그 기능을 만들어줘.
문제점:
- 기술 스택이 먼저 나옵니다.
- 사용자 문제와 수용 기준이 없습니다.
- plan 단계와 뒤섞입니다.
나쁜 예 2
좋은 Todo 앱을 만들어줘.
문제점:
- 너무 추상적입니다.
- 사용자 행동과 규칙이 없습니다.
- clarify 질문이 과도하게 늘어날 수 있습니다.
생성 후 반드시 볼 것
- 사용자 시나리오가 있는가
- 수용 기준이 테스트 가능한 문장인가
- 기술 구현 디테일이 과하게 섞이지 않았는가
- [NEEDS CLARIFICATION] 마커가 어디에 붙었는가
[NEEDS CLARIFICATION]가 붙는 대표 사례
- 태그 최대 개수 미정
- 정렬 기준 미정
- 권한 범위 미정
- 삭제가 영구 삭제인지 숨김 처리인지 미정
이 마커는 문서가 잘못됐다는 뜻이 아니라, 아직 팀이 합의해야 할 질문이 남았다는 뜻입니다.
이 마커는 누가 언제 붙이는가
보통 처음 이 마커를 붙이는 주체는 /speckit.specify를 실행한 AI입니다. 사용자가 입력한 기능 설명 안에 빠진 조건, 모순되는 규칙, 해석이 둘 이상 가능한 표현이 있으면 AI가 여기는 아직 확정된 요구사항으로 쓰기 어렵다고 판단해서 spec 문장 안에 [NEEDS CLARIFICATION]를 남깁니다.
하지만 AI만 붙일 수 있는 것은 아닙니다. 사람이 spec.md를 검토하다가 아직 합의되지 않은 항목을 발견하면 직접 이 마커를 추가해도 됩니다. 중요한 것은 애매함을 숨기지 않고 드러내는 표시로 쓰는 것입니다.
즉, 붙는 시점은 대개 두 가지입니다.
- /speckit.specify가 초안을 만들 때
- 사람이 초안을 리뷰하면서 빠진 질문을 발견했을 때
이 마커는 왜 사용하는가
이 마커의 목적은 문서를 멈추게 하는 것이 아니라, 지금 바로 구현으로 내려가면 위험한 질문이 남아 있다는 사실을 팀이 보게 만드는 것입니다.
이 마커가 있으면 다음과 같은 효과가 있습니다.
- plan 단계에서 추측으로 설계를 고정하는 일을 줄일 수 있습니다.
- tasks 단계에서 잘못된 전제를 기준으로 작업을 쪼개는 일을 줄일 수 있습니다.
- 구현 단계에서 원래 이게 어떤 뜻이었지?라는 혼선을 줄일 수 있습니다.
- 나중에 requirement drift가 생겼을 때, 원래 미확정 항목이 무엇이었는지 추적할 수 있습니다.
한마디로 말하면, 이 마커는 문제 표시가 아니라 합의가 필요한 질문 목록의 시작점입니다.
어떤 경우에 반드시 남겨 두는 것이 좋은가
다음과 같은 경우에는 억지로 추측해서 채우기보다 마커를 남기는 편이 낫습니다.
- 숫자 제한이 필요한데 최대값이나 최소값이 없음
- 권한 규칙이 중요한데 사용자별 범위가 빠져 있음
- 삭제, 취소, 만료 같은 상태 변화의 의미가 불명확함
- 성공 기준은 있는데 실패 처리 규칙이 없음
- 동일 용어를 서로 다르게 해석할 수 있음
예를 들어 사용자는 파일을 업로드할 수 있다는 문장만 있으면 파일 크기 제한, 허용 형식, 실패 시 메시지, 재시도 여부 등이 빠져 있을 수 있습니다. 이런 경우는 plan으로 내려가서 기술적으로 메우기보다 먼저 clarify가 필요합니다.
이 마커가 붙은 뒤에는 무엇을 해야 하는가
[NEEDS CLARIFICATION]가 보이면 가장 먼저 해야 할 일은 누가 답해야 하는 질문인지를 분리하는 것입니다.
- 제품 요구사항 판단이면 사용자, 기획자, PO, 강사 같은 요구사항 결정권자가 답해야 합니다.
- 도메인 규칙 판단이면 업무 담당자나 도메인 지식 보유자가 답해야 합니다.
- 단순 표현 정리라면 작성자나 리뷰어가 즉시 문장을 고쳐도 됩니다.
실무 흐름으로 보면 보통 다음 순서가 자연스럽습니다.
- spec에서 [NEEDS CLARIFICATION] 위치를 표시한다.
- 질문을 문장으로 분리한다.
- 누가 답할지 정한다.
- 답을 받은 뒤 spec 문장을 확정형으로 고친다.
- 그때 plan과 tasks로 내려간다.
이 마커는 언제 누가 제거하는가
이 마커는 질문에 대한 합의가 끝났을 때 제거합니다. 제거 주체는 한 명으로 고정되지 않습니다.
- AI가 clarify 결과를 반영하며 제거할 수도 있습니다.
- 사람이 회의나 리뷰 결과를 반영하면서 제거할 수도 있습니다.
- 경우에 따라 /speckit.specify를 다시 실행해 확정된 요구사항으로 새 spec을 만들면서 사라질 수도 있습니다.
다만 제거 기준은 분명해야 합니다. 대충 이 정도면 되겠지가 아니라 아래 조건 중 하나를 만족해야 합니다.
- 요구사항 결정권자가 명확한 답을 줬다.
- 문서에 수치, 범위, 조건, 예외가 구체적으로 적혔다.
- 같은 질문이 다시 나오지 않을 정도로 문장이 검토 가능하게 바뀌었다.
즉, 이 마커를 지우는 사람보다 더 중요한 것은 지워도 되는 근거가 있는가입니다.
제거하면 안 되는 경우도 있다
초안 단계에서 답을 모르는 상태인데 보기 싫다는 이유로 마커를 지우면 안 됩니다. 그 경우 애매함이 사라지는 것이 아니라 숨겨질 뿐입니다.
특히 아래 상황에서는 제거를 미루는 편이 맞습니다.
- 아직 stakeholder 답변을 받지 못함
- 팀 내부 해석이 둘 이상으로 갈림
- 구현은 시작했지만 요구사항 자체는 확정되지 않음
이럴 때는 마커를 남긴 채 질문 목록을 관리하는 편이 더 안전합니다.
교육 관점에서 이해하면
이 과정에서 [NEEDS CLARIFICATION]는 AI가 못해서 남긴 흔적이 아닙니다. 오히려 AI가 멋대로 결정하지 않고, 사람이 답해야 할 요구사항 경계를 보존했다는 뜻에 가깝습니다. 따라서 학습자는 이 마커를 보면 문서가 실패했다고 보기보다 여기서부터는 팀 합의가 필요하다고 읽는 것이 맞습니다.
실습 단계
- /speckit.specify를 실행합니다. 이 저장소에서는 before_specify hook가 먼저 실행되어 feature 브랜치를 자동으로 만들고 그 브랜치로 이동한 뒤 spec 생성이 진행됩니다. 즉, /speckit.specify가 끝났을 때는 보통 이미 001-todo-tagging 같은 브랜치 위에 있습니다.
- specs/<번호>-<기능명>/spec.md: 이번 기능의 요구사항 본문입니다. 가장 중요하게 읽고 수정할 파일입니다.
- specs/<번호>-<기능명>/checklists/requirements.md: spec 품질 체크리스트입니다. 빠진 항목이나 모호함이 없는지 확인하는 용도입니다.
- .specify/feature.json: 현재 활성 feature 디렉터리를 가리키는 포인터 파일입니다.
- 이때 보통 다음 파일이 함께 생성됩니다.
- 생성된 spec.md를 읽으며 사용자 시나리오, acceptance scenario, 성공 기준, [NEEDS CLARIFICATION] 위치를 확인합니다.
- requirements.md를 함께 보면서 체크리스트가 실제 spec 내용과 맞는지 검토합니다.
- 기능 요구와 기술 선택이 섞인 문장, 모호한 표현, 테스트하기 어려운 문장이 있으면 spec.md에서 바로 정리합니다.
- .specify/feature.json은 보통 직접 수정하지 않고, 현재 작업 중인 feature 디렉터리를 올바르게 가리키는지만 확인합니다.
- 검토가 끝나면 현재 feature 브랜치에서 commit한 뒤 main에 merge합니다.
이 단계에서 실제로 무엇을 바꾸는가
사람이 가장 많이 손보는 파일은 spec.md입니다.
- spec.md: 적극적으로 읽고 고치고 질문을 남기고 문장을 다듬는 핵심 문서입니다.
- requirements.md: 직접 새로 쓰기보다 체크 결과가 spec과 맞는지 검토하는 보조 문서입니다.
- .specify/feature.json: 보통 수정 대상이 아니라 현재 feature 경로 확인용 파일입니다.
즉, /speckit.specify 실행 후 해야 할 핵심 작업은 생성된 spec을 검토해서 요구사항을 더 정확하고 테스트 가능하게 다듬는 것입니다.
specs/001-todo-tagging와 001-todo-tagging는 무엇이 다른가
- specs/001-todo-tagging: spec 결과물이 저장되는 feature 디렉터리입니다.
- 001-todo-tagging: 이 저장소에서 /speckit.specify 실행 전에 자동 생성되는 feature 브랜치 이름 예시입니다.
즉, 하나는 파일 경로이고 다른 하나는 Git 작업 공간 이름입니다. 둘은 꼭 같은 이름일 필요는 없지만, 지금 내가 어느 feature 디렉터리를 기준으로 작업 중인지와 어느 Git 브랜치에서 검토 중인지는 분명히 구분해야 합니다.
Git 반영 예시
git status
git add specs/001-todo-tagging .specify/feature.json
git commit -m "docs: define feature spec"
git checkout main
git merge --no-ff 001-todo-tagging -m "merge: feature spec"
git push origin main
이 블록은 생성된 spec을 검토하고 다듬은 뒤, 현재 feature 브랜치의 결과를 main에 합의된 상태로 반영하는 절차입니다.
순서를 짧게 읽으면 다음과 같습니다.
- git status 현재 브랜치와 변경 파일 상태를 확인한다.
- git add specs/001-todo-tagging .specify/feature.json 이번 spec 산출물과 feature 포인터만 커밋 대상으로 올린다.
- git commit -m "docs: define feature spec" 이번 기능 요구사항을 하나의 문서 이력으로 기록한다.
- git checkout main 기준 브랜치로 돌아와 merge를 준비한다.
- git merge --no-ff 001-todo-tagging -m "merge: feature spec" feature 브랜치 결과를 merge commit으로 main에 반영한다.
- git push origin main 로컬에서 확정한 spec 이력을 원격 저장소와 공유한다.
실행하면서 실제로 확인해야 하는 것
- /speckit.specify 직후 현재 브랜치가 001-todo-tagging 같은 feature 브랜치인지 확인합니다.
- git status에서는 specs/001-todo-tagging/와 .specify/feature.json 등 spec 생성과 직접 관련된 파일만 바뀌었는지 봅니다.
- git add specs/001-todo-tagging .specify/feature.json 후에는 staging 영역에 의도하지 않은 파일이 섞이지 않았는지 다시 확인합니다.
- git commit이 끝나면 docs: define feature spec 메시지로 커밋이 하나 생겼는지 확인합니다.
- git checkout main 후에는 정말 main 브랜치로 돌아왔는지 확인합니다.
- git merge --no-ff ... 후에는 merge commit이 남아 spec 초안이 main에 합의되어 들어왔다는 사실이 이력에 보이는지 확인합니다.
- git push origin main 후에는 원격 저장소에서도 spec 반영 결과를 볼 수 있어야 합니다.
왜 여기서는 git checkout -b ...를 다시 하지 않는가
이 저장소는 /speckit.specify 실행 전에 before_specify hook가 먼저 동작합니다. 그래서 명령을 실행하면 Git feature 브랜치가 자동 생성되고 그 브랜치에서 spec 작업이 진행됩니다. 이미 feature 브랜치 위에 올라와 있는 상태에서 다시 새 브랜치를 만들면 같은 작업을 한 번 더 분리하는 셈이어서 오히려 흐름이 복잡해집니다.
자주 헷갈리는 포인트
git add specs/001-todo-tagging .specify/feature.json만으로 충분한가
이 예시는 /speckit.specify가 실제로 만든 핵심 산출물만 올리는 가장 보수적인 예시입니다. 다만 실제 실습에서는 spec.md 설명을 보완한 학습 문서나 다른 관련 파일이 함께 바뀔 수도 있으므로, 그 경우에는 git status를 보고 필요한 파일을 선택적으로 추가해야 합니다. 핵심은 전체 add가 아니라 이번 spec 작업과 직접 관련된 파일만 올린다는 점입니다.
왜 --no-ff를 붙이는가
나중에 Git 로그를 볼 때 여기서 feature spec이 main에 합의되어 들어왔다는 시점을 명확히 남기기 위해서입니다. 단순 fast-forward보다 교육용 기록과 검토 흐름을 설명하기 좋습니다.
왜 바로 구현하지 않고 spec을 먼저 merge하는가
spec은 구현 전에 무엇을 만들 것인가를 먼저 합의하는 단계입니다. 이 문서가 먼저 안정되어야 이후 plan과 tasks가 흔들리지 않습니다. 그래서 spec 자체를 하나의 독립 산출물처럼 다루는 연습이 중요합니다.
스스로 점검
- 이 spec은 개발자가 아니라 사용자 관점에서도 읽을 수 있는가?
- 구현 방식이 아니라 기대 동작이 중심인가?
- clarifiy가 필요한 부분이 자연스럽게 드러나는가?
'AI Native > GitHub Spec Kit으로 구현하는 SDD v2' 카테고리의 다른 글
| d01/08. plan-tasks-workshop.md (0) | 2026.05.02 |
|---|---|
| d01/07. clarify-workshop.md (0) | 2026.05.02 |
| d01/05. constitution-workshop.md (0) | 2026.05.02 |
| d01/04. sdd-philosophy.md (0) | 2026.05.02 |
| d01/03. sdd-greenfield-workshop.md (0) | 2026.05.02 |