콘텐츠로 이동
Study NoteClaude Code · Codex

스펙 문서: 무엇을 왜 만드는가

결론부터
스펙은 요구와 완료 판정의 정본이다. 기능 단위로 ID를 붙여 한 곳에 두고, 요구가 바뀌면 계획이 아니라 스펙을 먼저 고친다

이 페이지는 스펙에 무엇을 적고, 언제 만들고, 어떻게 유지하는가에 답한다. 스펙이 docs/product-specs/에 놓이는 이유는 레포 구조에서 정했다.

이 장에서 처음 나오는 말2개
수용 기준Acceptance Criteria
기능이 완성됐다고 판정하는 관찰 가능한 조건. "파일이 생겼다"가 아니라 "권한 있는 25건이 다 들어 있다"처럼 쓴다.
FR · NFRFunctional · Non-Functional Requirement
기능 요구와 비기능 요구. 앞에 붙는 ID로 계획·테스트·설계가 같은 요구를 가리킨다.

스펙이 없으면 완료 조건이 조용히 낮아진다

섹션 제목: “스펙이 없으면 완료 조건이 조용히 낮아진다”

요구가 계획 파일 안에만 있으면 구현하다 막힐 때 “현재 페이지만 내보내기”처럼 완료 조건을 낮추기 쉽다. 계획을 고치는 사람이 요구도 함께 고치는 셈이라 아무도 눈치채지 못한다. 두 번째 계획이 같은 기능을 손댈 때는 첫 계획에서 요구를 찾아 다시 적게 된다.

요구를 계획 밖의 한 파일에 두면 계획은 그 파일을 ID로 가리키기만 한다. 완료 조건을 바꾸려면 스펙을 고쳐야 하고, 스펙의 diff는 눈에 띈다.

기능 하나에 파일 하나다. 한 파일이 답할 질문은 “이 기능은 무엇을 왜 하며 언제 완성인가”뿐이다.

절내용적지 않는 것
목적과 사용자누가 어떤 문제를 겪고 무엇을 얻는가구현 방식
기능 요구 FR-*사용자가 관찰할 수 있는 동작함수명·파일 경로
비기능 요구 NFR-*제한값·성능·보안 조건측정 방법의 세부
제외 범위이번에 하지 않기로 한 것과 이유언젠가 할 수도 있는 것의 나열
수용 기준요구별로 무엇을 보면 완료인가테스트 코드

가상 업무 서비스의 스펙이다. 이 파일을 계획 문서의 예시 계획이 ID로 가리킨다.

docs/product-specs/task-export.md
# 업무 목록 CSV 내보내기
## 목적과 사용자
업무 담당자가 현재 화면의 필터·정렬 결과를 스프레드시트로 옮겨 보고서를 만든다.
지금은 화면을 복사해 붙이느라 페이지마다 반복하고 권한 밖 항목이 섞인다.
## 기능 요구
- FR-EXP-01 현재 사용자의 조회 권한과 화면의 필터·정렬을 그대로 적용한다.
- FR-EXP-02 페이지 구분 없이 조건에 맞는 전체 항목을 포함한다.
- FR-EXP-03 열은 ID·제목·상태다. 제목의 쉼표·따옴표·줄바꿈을 보존한다.
- FR-EXP-04 0건이면 헤더만 있는 파일을 내려받는다.
- FR-EXP-05 제한을 넘으면 일부만 내려받지 않고 제한 안내를 보여 준다.
## 비기능 요구
- NFR-EXP-01 한 번에 최대 1,000건. 초과 처리는 제외 범위다.
- NFR-EXP-02 제목이 `=`·`+`·`-`·`@`로 시작해도 스프레드시트에서 수식으로 실행되지 않는다.
## 제외 범위
비동기 대량 내보내기, 예약 전송, 새 권한 체계. 1,000건 초과 요구가 실제로 생기면 별도 스펙으로 다룬다.
## 수용 기준
- FR-EXP-01·02: 필터 일치 25건과 다른 사용자의 업무를 준비하고 목록은 10건씩 표시할 때,
내려받은 파일에 권한 있는 25건이 모두 있고 다른 사용자 항목은 없다.
- FR-EXP-03: 쉼표·따옴표·줄바꿈이 있는 제목을 파싱하면 원래 값과 같다.
- FR-EXP-04·05: 0건은 헤더 한 줄, 1,001건은 파일 대신 안내 메시지.
- NFR-EXP-02: `=SUM(1)`로 시작하는 제목이 스프레드시트에서 문자열로 열린다.

수용 기준이 곧 작업 흐름에서 검증할 입력과 예상 관찰이다. 스펙 단계에서 “무엇을 보면 완료인가”를 정해 두면 구현 세션이 검증 방법을 새로 발명하지 않는다.

상황할 일
요구가 여러 계획·세션에 걸쳐 참조된다스펙 파일을 만든다
요구를 정하는 데 긴 대화가 필요하다대화로 요구를 확정해 스펙에 적고, 구현은 새 세션에서 스펙만 보고 시작한다
이슈에 요구와 수용 기준이 이미 있다이슈를 스펙으로 삼고 링크한다. 새로 쓰지 않는다
작은 수정이라 요구가 한 문장이다계획이나 요청에 적고 스펙은 만들지 않는다

Claude Code 공식 안내는 큰 기능이면 먼저 인터뷰로 스펙을 파일에 쓰고, 새 세션에서 그 파일만 보고 구현하도록 권한다(Let Claude interview you). 요구를 정하느라 길어진 대화를 구현 컨텍스트에서 떼어 내는 효과가 있다.

인터뷰로 스펙을 만들 때의 요청이다.

업무 목록 CSV 내보내기 기능의 스펙을 docs/product-specs/task-export.md에 쓰려고 해.
결정이 필요한 것을 하나씩 물어봐 줘. 권한·필터·건수 제한·열 구성·실패 처리부터.
답을 모아 FR·NFR ID가 붙은 요구와 요구별 수용 기준을 적어 줘. 구현은 시작하지 마.

스펙은 현재 요구를 말한다. 이력 문서가 아니다.

  • 요구가 바뀌면 스펙을 먼저 고치고, 진행 중 계획의 완료 조건을 그에 맞춘다. 반대 순서로 하지 않는다.
  • 구현하다 요구를 만족할 수 없음을 알게 되면 계획에서 조건을 낮추지 말고, 선택지를 제시해 스펙을 바꿀지 결정받는다.
  • 기능이 완성되면 스펙이 현재 동작과 같은지 본다. 구현 중 합의로 달라진 값이 있으면 스펙에 반영한다.
  • 기능을 없애면 스펙 파일도 지우거나 맨 위에 대체 스펙을 적는다. 낡은 스펙을 정본인 척 두지 않는다.
  • 구현 방식·파일 경로·결정 이유는 적지 않는다. 그것은 설계 문서의 몫이다.

구현 중 기존 조회 함수가 한 페이지만 반환하는 것을 알았다. “현재 페이지만 내보낸다”로 바꿔도 될까? 안 된다. FR-EXP-02가 전체 항목을 요구한다. 전체를 조회하는 경로로 구현을 바꾸거나, 정말 불가능하면 스펙 변경을 제안하고 결정을 받는다.

이슈 트래커에 요구가 다 있다. product-specs/를 만들어야 할까? 만들지 않는다. 계획에서 이슈를 링크하고, 이슈에 없는 수용 기준만 계획에 보완한다.