--- name: trd-generator description: docs/PRD.md를 받아 "어떤 기술로 만들 것인가"를 정의하는 TRD(docs/TRD.md)를 작성한다. 스택·데이터·API·인증·보안·테스트·배포를 결정 단위로 확정하고, 각 결정에 근거가 된 요구사항과 검증 방법·되돌리기 비용을 붙여 아키텍처와 하네스가 그대로 참조할 수 있게 만든다. 사용자가 "TRD 써줘", "기술 스택 정해줘", "어떤 기술로 만들지 정리해줘", "기술 명세서", "DB 뭐 쓸지 정해줘", "배포는 어떻게 할지 정리해줘"라고 하거나, PRD 작성을 마치고 다음 단계로 넘어갈 때 반드시 이 스킬을 사용한다. 요구사항은 정해졌는데 기술 선택이 문서로 없는 상태에서 아키텍처 설계나 개발을 시작하려 할 때도 이 스킬로 먼저 기술 결정을 고정한다. --- # TRD 작성 (Layer 1) ## 이 스킬의 목적 TRD는 **"어떤 기술로 만들 것인가"**에 대한 합의문이다. PRD가 사용자에게 한 약속이라면, TRD는 그 약속을 지키기 위해 고른 수단과 그 근거다. 여기서 내린 결정 하나하나가 뒤에서 이렇게 흘러간다. ``` TRD의 결정 TD-004 (관계형 DB를 쓴다) → 아키텍처에서 database.md 의 전제가 된다 (Layer 2) → 태스크의 Files·Acceptance Criteria가 이 위에 쓰인다 (Layer 3) → 테스트 도구·배포 형태 결정이 품질 게이트와 local-dev 스크립트의 재료가 된다 (Layer 4) ``` 그래서 이 문서의 품질은 "최신 기술을 잘 골랐는가"가 아니라 **"각 결정이 어느 요구사항 때문인지, 틀렸을 때 무엇을 되돌려야 하는지가 적혀 있는가"**로 판정된다. 근거 없이 적힌 기술 이름은 뒤 레이어에서 **검토 대상이 아니라 기정사실로 읽힌다.** 아무도 왜 그걸 쓰는지 모르는 채로 태스크 수십 개가 그 위에 쌓인다. ### 여기서 하는 일과 하지 않는 일 | 하지 않는 것 | 어디서 하는가 | |---|---| | 요구사항을 새로 만들거나 바꾸는 것 | PRD (`prd-generator`) — 사용자가 정하면 이 세션이 PRD 부터 고치고 이어 간다(7단계 "PRD 로 돌려놓기") | | 테이블 컬럼·인덱스 설계, API 엔드포인트 명세, 모듈·컴포넌트 구조 | Layer 2 아키텍처 (`architecture-generator`) | | 개발 순서, 태스크 분할, 일정 | Layer 3 마스터 플랜 | | 품질 게이트 4단계 구성, E2E가 덮을 흐름 목록, task validation 방식 | Layer 4 하네스 (`harness-setup`) | | lint 설정 파일, 테스트 코드, 실행 스크립트 작성 | Layer 4 하네스 | **테스트에서 TRD가 정하는 것은 도구와 범위까지다.** 하네스는 PRD를 직접 읽으므로, 어느 사용자 흐름이 핵심인지는 그쪽이 원본을 보고 판단하는 편이 정확하다. 여기서 흐름 목록까지 확정하면 TRD가 하네스 설계를 떠안게 되고, 요구사항이 바뀔 때 고쳐야 할 문서가 하나 늘어난다. **TRD와 아키텍처를 나누는 기준은 하나다** — 이 문장이 **후보 중 하나를 고르는가, 고른 것 안에서 모양을 정하는가?** | TRD (고른다) | 아키텍처 (모양을 정한다) | |---|---| | 관계형 DB를 쓴다. 후보 중 X를 고른다 | `invoices` 테이블에 status 컬럼과 부분 인덱스를 둔다 | | REST + JSON, 오류 응답은 한 가지 형식으로 통일한다 | `GET /invoices?status=overdue` 의 요청·응답 스키마 | | 세션 기반 인증, 권한은 소유자 단일 역할 | 미들웨어가 어느 계층에서 소유권을 검사하는가 | | 브라우저 자동화 도구로 X를 쓴다 | 그 도구로 어떤 흐름을 어떤 순서로 검증하는가 | 이 경계를 지키는 이유는 형식이 아니다. **기술 선택은 프로젝트당 몇 번 안 바뀌지만 구조는 매주 바뀐다.** 둘을 한 문서에 섞으면 화면 하나를 추가할 때마다 기술 결정 문서를 고치게 되고, 그러다 보면 무엇이 합의된 선택이고 무엇이 그날의 구현이었는지 아무도 구별하지 못한다. 그리고 **TRD는 요구사항을 만들지 않는다.** 기술을 고르다 보면 "그러면 관리자 화면이 필요하겠네" 같은 것이 나오는데, 그건 기능 요구사항이므로 TRD에 적지 말고 PRD로 돌아가 FR을 추가한다. TRD 본문에만 적힌 기능은 추적표에 없어서 뒤에서 조용히 사라진다. --- ## 1단계. 입력 확보와 PRD 점검 **`docs/TRD.md` 가 이미 있으면 작성(1~7단계)을 다시 돌지 않는다** — 남은 미결을 푸는 것이면 8단계(미결 해소 세션), 내용을 바꾸는 것이면 9단계(부분 갱신)만 한다. 8단계로 풀었는데 뒤 문서(아키텍처 이후)가 이미 있으면, 끝에 9단계의 버전·`변경 이력` 한 줄·뒤 문서 맞추기를 한다 — 버전이 그대로면 뒤 스킬이 알아채지 못한다. 처음부터 다시 쓰면 TD 번호와 확정도, 사용자와 푼 미결이 초기값으로 덮인다. 사용자가 처음부터 다시 쓰라고 명시하면 그때만 1단계부터 돈다 — 뒤 문서가 이미 있으면 번호가 흔들려 뒤 문서의 참조가 엉뚱한 항목을 가리킨다는 것을 먼저 알린다. `docs/PRD.md` 를 읽는다. **이것이 유일한 필수 입력이다.** PRD가 없으면 TRD를 쓰지 않는다. 요구사항 없이 고른 기술은 근거가 없고, 근거 없는 결정은 나중에 뒤집을 수도 지킬 수도 없다. 이때는 `prd-generator` 로 먼저 요구사항을 고정하자고 제안한다. 사용자가 "PRD는 됐고 기술만 정해달라"고 하면, 최소한 **어떤 기능이 있고 무엇이 지켜져야 하는지**를 구두로 받아 TRD 1절에 '입력 문서: 사용자 설명'으로 남기고 진행한다. 이 경우 추적표의 요구사항 ID를 만들어 낼 수 없으므로, 근거 열에는 사용자가 말한 문장을 그대로 인용한다. PRD를 읽을 때 세 가지를 먼저 추린다. **첫째, 차단 미결이 남아 있는지 본다.** PRD 8절의 미결 중 P0를 막는 것(굵게 표시된 것)이 남아 있으면 그 위에 기술 설계를 얹지 않는다. "전자서명이 필요한가"가 미정인 상태에서 인증·저장·외부 연동을 고르면, 답이 뒤집혔을 때 설계를 통째로 다시 한다. 차단 미결이 있으면 사용자에게 먼저 알리고 두 가지 중 하나를 고르게 한다. 1. 이 자리에서 그 미결을 사용자와 풀고 PRD 에 반영(7단계 "PRD 로 돌려놓기")한 뒤 이어 간다 (권장) 2. 기본값으로 진행하되, 영향받는 영역의 결정을 **'잠정'**으로 표시하고 되돌리기 비용을 명시한다 임의로 2번을 고르지 않는다. 되돌리기 비용을 치르는 건 사용자다. **둘째, 기술을 강제하는 요구사항을 뽑아낸다.** PRD의 NFR과 일부 FR은 선택지를 좁힌다. 이건 취향이 아니라 제약이므로 TRD 1절에 목록으로 옮긴다. | PRD에 이렇게 적혀 있으면 | TRD에서 이렇게 좁혀진다 | |---|---| | 개인정보를 국외로 이전하지 않는다 | 호스팅·백업·외부 서비스의 리전 선택지가 제한된다 | | 1만 건 기준 P95 500ms | 데이터 접근 방식과 인덱싱 전략이 검증 대상이 된다 | | 로그인 없이 링크로 열람 | 인증 모델에 비인증 경로가 반드시 존재해야 한다 | | 금액에 반올림 오차가 없다 | 부동소수점 금액 타입을 쓸 수 없다 | | 월간 가동률 99% | 단일 인스턴스 재시작 시간이 예산 안에 들어와야 한다 | **셋째, 요구사항이 요구하지 *않는* 것도 확인한다.** 이게 더 중요하다. PRD에 실시간 갱신 요구가 없으면 WebSocket을 넣지 않는다. 대용량 배치가 없으면 큐를 넣지 않는다. 팀이 1명이면 서비스를 쪼개지 않는다. **근거 없이 들어온 기술은 Layer 3에서 태스크가 되고, Layer 4에서 품질 게이트가 되고, 매 태스크마다 관리 비용을 받아 간다.** 지금 한 줄 지우는 것이 나중에 태스크 다섯 개를 지우는 것이다. ## 2단계. 프로젝트 여건 확인 PRD에 없지만 기술 결정을 실제로 가르는 정보가 있다. **이걸 묻지 않고 고른 스택은 대개 팀이 감당 못 하거나 예산을 넘는다.** 아래를 사용자에게 확인한다. 한 번에 3~4개씩 묶어 묻고, 답을 못 받은 항목은 합리적 값으로 정한 뒤 `(가정)` 표기를 남긴다. | 물을 것 | 무엇이 갈리는가 | |---|---| | 개발 인원과 기간 | 1인 3개월과 5인 1년은 고를 수 있는 것이 다르다 | | 팀이 이미 잘 다루는 언어·프레임워크 | 익숙한 스택이 대개 옳다. 학습 비용은 일정에서 그대로 빠져나간다 | | 운영 인력과 운영 경험 | 운영할 사람이 없으면 직접 관리하는 인프라를 고르지 않는다 | | 월 인프라 예산 | 관리형 서비스를 얼마나 쓸 수 있는지가 결정된다 | | 기존 자산 (코드베이스·계정·계약된 서비스) | 이미 있는 것을 버리는 결정은 근거가 필요하다 | | 배포 대상 (웹/모바일/사내망/온프레미스) | 배포·보안 결정의 출발점이다 | | 개발자의 OS | 로컬 개발 환경 스크립트가 갈린다 (Layer 4의 입력) | **기존 코드베이스가 있으면 추측하지 말고 확인한다.** 패키지 매니페스트, 설정 파일, 배포 설정을 직접 읽어 현재 스택을 파악한다. 기존 프로젝트의 TRD는 "무엇을 고를까"가 아니라 **"무엇이 이미 정해져 있고, 무엇을 바꿀 것인가"**를 적는 문서가 된다. ## 3단계. 기술 결정 각 결정은 **TD-001** 형태의 ID를 갖는다. 아키텍처와 태스크가 "어느 결정 때문에 이렇게 만들었는지"를 가리킬 곳이 여기다. ### 무엇을 TD 하나로 셀 것인가 **되돌리기 비용이 독립적으로 발생하는 것만 TD로 만든다.** 상위 결정을 고르면 자동으로 딸려 오는 것은 그 TD 본문의 한 줄로 흡수한다. 판단은 이렇게 한다 — **이것만 따로 뒤집을 수 있는가?** 뒤집을 수 있으면 TD, 상위 결정을 함께 뒤집어야만 바뀌면 흡수한다. | TD로 세운다 | 상위 TD에 흡수한다 | |---|---| | 저장소 종류 | 마이그레이션 도구, 시간대 저장 규칙 (저장소를 고르면 따라온다) | | 언어·런타임 | 패키지 매니저, 포매터 (런타임을 고르면 사실상 정해진다) | | 인증 방식 | 세션 수명, 쿠키 속성 | | 배포 형태 | 로그 형식, 정기 작업 실행 위치 | 굵은 결정과 잔가지를 같은 무게로 나열하면 **정작 검토받아야 할 결정이 묻힌다.** 사용자가 TRD 검토에 쓸 시간은 한정돼 있고, 그 시간은 나중에 못 되돌릴 것에 써야 한다. 결정이 20개를 넘어가면 대개 흡수할 것을 안 흡수한 것이다. 한 번 더 훑어 묶는다. ### 결정 하나의 형식 ```markdown #### TD-004. 데이터 저장소: 관계형 DB - **영역**: 데이터 - **근거 요구사항**: NFR-008(금액 정수 저장), NFR-001(1만 건 P95 500ms), FR-012(프로젝트–인보이스 연결) - **결정**: 단일 관계형 DB 하나를 쓴다. 금액은 정수 타입으로 저장한다. - **검토한 대안**: 문서형 DB — 프로젝트·계약·인보이스가 항상 함께 조회되어 조인이 핵심인데, 이 구조에서는 정합성을 애플리케이션이 떠안는다 - **확정도**: 확정 - **되돌리기 비용**: 데이터 접근 계층 전면 재작성. 이미 저장된 데이터가 있으면 이전 작업이 별도 태스크로 추가된다 - **검증 방법**: 저장된 금액을 조회했을 때 입력값과 정확히 일치한다. 프로젝트 200건·인보이스 1,000건 상태에서 목록 조회가 NFR-001의 기준 안에 든다 ``` 여섯 항목이 각각 하는 일이 있다. - **근거 요구사항** — 이게 비어 있으면 그 결정은 지운다. 요구사항이 요구하지 않는 기술이라는 뜻이다. 프로젝트 여건이 근거일 수도 있다(예: "팀 2명 전원이 이 언어만 다룬다"). 그것도 명시적으로 적는다. - **검토한 대안** — 탈락 이유가 진짜 이유여야 한다. "성능이 더 좋아서"는 근거가 아니다. 어느 요구사항의 어느 숫자를 못 맞추는지를 적는다. 대안을 적어 두면 나중에 되돌릴 때 처음부터 다시 조사하지 않는다. - **확정도** — `확정` / `잠정(OQ-0xx 대기)` / `스파이크 필요`. 잠정인 결정 위에 아키텍처를 세울 때 어디를 느슨하게 둘지 알려 준다. - **되돌리기 비용** — "이 선택이 틀렸다고 판명되면 무엇을 다시 해야 하는가". 비싼 결정부터 검토받아야 한다. - **검증 방법** — **이 항목이 TRD를 검증 가능한 문서로 만든다.** 아래를 보라. ### 검증 방법을 왜 각 결정에 붙이는가 Layer 4의 task validation은 **그 태스크를 구현한 세션과 분리된 세션에서** 돈다. 구현자의 머릿속 맥락이 검증에 새는 것을 막기 위해서다. 그 검증자에게는 문서에 적힌 문장이 정보의 전부다. "확장성 있게 설계한다"는 문장으로는 아무것도 판정할 수 없다. 그래서 PRD의 수용 기준과 같은 규칙을 따른다. - **관찰 가능한 것만 쓴다.** 무엇을 실행하면 무엇이 나오는가, 어떤 값이 저장되는가, 어떤 응답이 오는가 - **숫자가 필요한 곳에는 숫자를 쓴다.** "빠르게" 대신 PRD의 NFR 숫자를 그대로 가져온다 - **한 검증 방법은 한 가지만 검사한다** 검증할 수 없는 결정은 결정이 아니라 희망이다. 검증 방법을 못 쓰겠으면 그 결정이 실은 아무것도 정하지 않았다는 신호다. ### 영역별로 무엇을 정하는가 아래는 다뤄야 할 영역과, 각 영역에서 실제로 갈리는 것들이다. **해당 없는 영역은 비운다.** 형식적으로 채우면 뒤 레이어가 그것을 만족시키려고 불필요한 태스크를 만든다. 비울 때는 "왜 해당 없는지"를 한 줄 남긴다. | 영역 | 정하는 것 | 자주 틀리는 지점 | |---|---|---| | **스택** | 언어, 런타임, 프레임워크, 주요 라이브러리, 패키지 매니저 | 팀이 못 다루는 것을 고른다. 라이브러리를 지나치게 일찍 확정한다 | | **데이터** | 저장소 종류와 선택, 데이터 모델 방식, 마이그레이션 도구, 백업·보관 정책 | PRD의 보관·파기 기간(NFR)을 빠뜨린다 | | **API** | 통신 방식(REST/GraphQL/RPC), 데이터 형식, 오류 응답 규약, 버전 정책, 외부 연동 목록 | 개별 엔드포인트를 적기 시작한다(아키텍처의 몫) | | **인증·권한** | 인증 방식, 세션·토큰 수명, 역할 모델, 비인증 접근 경로 | PRD에 있는 비로그인 경로를 인증 모델에서 빠뜨린다 | | **보안** | 비밀값 관리, 전송·저장 암호화, 입력 검증 지점, 접근 통제 원칙, 감사 로그 | "업계 표준을 따른다"로 뭉갠다. 검증할 수 없다 | | **테스트** | 테스트 도구와 반드시 덮어야 할 영역 (5단계에서 자세히) | 게이트 구성·E2E 흐름까지 여기서 확정해 하네스 설계를 떠안는다 | | **배포·운영** | 실행 환경, 환경 구분(로컬/스테이징/운영), 배포 방식, 로컬 개발 환경, 로그·모니터링, 비용 추정 | 로컬 개발 환경을 안 적어 Layer 4의 local-dev 스크립트가 근거 없이 만들어진다 | ### 고를 때의 기본 자세 **가장 지루한 선택이 기본값이다.** 널리 쓰이고, 팀이 알고, 문제가 생겼을 때 답을 찾기 쉬운 것. 새롭거나 화제인 기술을 고르려면 **어느 요구사항이 그것을 요구하는지** 적을 수 있어야 한다. 못 적으면 지루한 쪽을 고른다. 이게 취향 문제가 아닌 이유가 있다. 이 문서 뒤에는 자동화된 루프가 붙는다. **모델이 잘 모르는 기술을 고르면 Layer 5의 태스크마다 조사가 붙고, 품질 게이트의 실패 원인이 요구사항이 아니라 도구 사용법이 된다.** 재수정 사이클 3회 제한에 걸려 멈추는 태스크가 늘어난다. 익숙한 스택의 이점은 개발자만의 것이 아니다. **결정을 미루는 것도 결정이다.** 지금 정하지 않아도 되는 것(예: 나중에 붙일 외부 서비스)은 미결로 넘기고, 언제 무엇을 보면 정할 수 있는지 적는다. 다만 **되돌리기 비용이 큰 것부터 지금 정한다** — 저장소, 인증 모델, 배포 형태가 여기 해당한다. ## 4단계. 비기능 요구사항의 실현 확인 PRD의 NFR은 전부 "이걸 어떻게 지킬 것인가"에 답을 받아야 한다. **하나라도 답이 없으면 그 NFR은 아무도 책임지지 않은 채로 출시된다.** 기능 요구사항은 없으면 눈에 보이지만, 비기능 요구사항은 사고가 나기 전까지 안 보인다. NFR 하나하나에 대해 표를 채운다. | NFR | 어떻게 지키는가 | 관련 결정 | 무엇으로 확인하는가 | |---|---|---|---| | NFR-004 (타인 데이터 접근 불가) | 모든 데이터 조회에 소유자 조건을 강제하고, 없는 경우 404 반환 | TD-008 | 다른 계정의 리소스 주소로 접근하는 테스트가 통과한다 | "어떻게 지키는가"가 안 써지는 NFR이 있으면 둘 중 하나다 — 실현 수단이 없거나(사용자에게 보고하고 NFR을 조정할지 묻는다), 그 NFR이 측정 불가능하게 쓰여 있거나(PRD로 돌아가 고친다). 조용히 넘기지 않는다. ## 5단계. 테스트 — 도구와 범위까지만 **TRD가 정하는 것은 "무엇으로 검증하는가"와 "어디는 반드시 덮는가" 둘뿐이다.** 품질 게이트를 어떻게 구성할지, E2E가 어느 흐름을 덮을지, task validation을 어떤 절차로 돌릴지는 Layer 4의 `harness-setup` 이 정한다. 하네스는 PRD를 직접 읽으므로 어느 흐름이 핵심인지는 그쪽이 원본을 보고 판단하는 편이 정확하고, 여기서 확정하면 요구사항이 바뀔 때 고쳐야 할 문서가 하나 늘어난다. **도구** — 단위 테스트 프레임워크와 브라우저 자동화 도구를 다른 결정과 같은 형식(TD)으로 고른다. 근거는 대개 PRD의 NFR에서 나온다. 예를 들어 지원 브라우저를 명시한 NFR이 있으면, 그 브라우저를 실행할 수 있는지가 도구 선택을 실제로 가르는 조건이다. **반드시 덮어야 할 영역** — 커버리지 총량 대신 영역을 지정하고, 각 영역에 근거 요구사항을 붙인다. | 영역 | 근거 | |---|---| | 금액·수량 계산 | NFR-008 (반올림 오차 없음) | | 권한·소유권 판정 | NFR-004 (타인 데이터 접근 불가) | | 상태 전이 | FR-018 (허용·금지 전이) | **왜 총량이 아니라 영역인가.** 총량 기준은 화면 코드에 얕은 테스트를 붙여 올리기 쉽고, 정작 틀리면 안 되는 것은 덮이지 않아도 숫자가 채워진다. 어느 영역이 "틀리면 안 되는 것"인지는 PRD의 NFR이 이미 말하고 있다. 그것을 그대로 옮기면 된다. 여기까지 적고 나머지는 넘긴다. 절 끝에 **"게이트 구성·E2E 흐름·task validation 방식은 Layer 4가 정한다"**를 한 줄로 남겨, 하네스가 이 문서를 읽을 때 "빠진 것"이 아니라 "일부러 넘긴 것"임을 알게 한다. ## 6단계. `docs/TRD.md` 작성 경로는 프로젝트 루트 기준 `docs/TRD.md`. 아래 구조를 그대로 사용한다. ```markdown # TRD: (제품 이름) - **버전**: 0.1 (초안) - **작성일**: YYYY-MM-DD - **입력 문서**: docs/PRD.md (버전 0.1) - **상태**: 사람 검토 대기 - **변경 이력**: (없음 — 고칠 때마다 `0.2 (YYYY-MM-DD, <고친 스킬>) — <무엇을 왜>. 영향: <뒤 문서의 ID·절>` 한 줄씩) ## 1. 개요 ### 1.1 이 문서의 범위 (무엇을 정하고 무엇을 정하지 않는가. 아키텍처·플랜과의 경계를 한 문단으로.) ### 1.2 PRD에서 넘어온 제약 | 출처 | 제약 | 무엇을 좁히는가 | |---|---|---| | NFR-015 | 개인정보 국외 이전 불가 | 호스팅·백업·외부 서비스의 리전 | ### 1.3 프로젝트 여건 | 항목 | 값 | 출처 | |---|---|---| | 개발 인원 / 기간 | | 사용자 확인 / (가정) | | 팀이 익숙한 스택 | | | | 운영 인력 | | | | 월 인프라 예산 | | | | 기존 자산 | | | | 배포 대상 | | | | 개발자 OS | | | ## 2. 기술 결정 요약 | ID | 영역 | 결정 | 근거 요구사항 | 확정도 | |---|---|---|---|---| | TD-001 | 스택 | | FR-00x, NFR-00x | 확정 | ## 3. 스택 (3단계의 결정 형식을 따른다. 이하 모든 영역 절이 같다.) ## 4. 데이터 ## 5. API ## 6. 인증·권한 ## 7. 보안 ## 8. 테스트 (도구 선택은 결정 형식으로. 그다음 아래 표.) ### 8.1 반드시 덮어야 할 영역 | 영역 | 근거 요구사항 | |---|---| > 품질 게이트 구성, E2E가 덮을 흐름, task validation 방식은 Layer 4(`harness-setup`)가 PRD를 직접 읽고 정한다. ## 9. 배포·운영 ### 9.1 실행 환경과 환경 구분 ### 9.2 배포 방식 ### 9.3 로컬 개발 환경 (개발할 때 함께 떠야 하는 구성 요소. Layer 4의 local-dev 스크립트가 이 표를 그대로 구현한다. 형태(컨테이너·호스트 실행)와 준비 판정 명령은 여기서 정하지 않는다 — 하네스가 채운다.) | 구성 요소 | 왜 필요한가 | 근거 결정 | |---|---|---| | (DB) | | TD-00x | ### 9.4 로그·모니터링 ### 9.5 비용 추정 ## 10. 비기능 요구사항 실현표 | NFR | 어떻게 지키는가 | 관련 결정 | 무엇으로 확인하는가 | |---|---|---|---| ## 11. 리스크와 가정 ### 확정된 가정 | 가정 | 근거 | 틀리면 영향받는 결정 | |---|---|---| ### 기술 리스크 | 리스크 | 영향 | 조기 발견 방법 | 대응 | |---|---|---|---| ## 12. 미결 사항 (PRD에서 이어지는 번호를 쓴다. PRD가 OQ-012에서 끝났으면 OQ-013부터. 부분 갱신이면 프로젝트 전체 — 아키텍처·`HARNESS.md`·`LOOP.md` 의 미결 표까지 — 의 마지막 번호 다음.) | ID | 결정할 것 | 종류 | 차단하는 결정 | 해소 방법 | 미해소 시 기본값 | 되돌리기 비용 | |---|---|---|---|---|---|---| | OQ-013 | | 질문(잠정)/확인/실험/유예 | TD-00x | | | | ## 13. 요구사항 → 기술 결정 추적표 | 요구사항 | 관련 결정 | |---|---| | FR-001 | TD-001, TD-006 | ``` **12절의 미결은 PRD와 같은 규칙을 따른다.** 종류를 `질문 / 확인 / 실험 / 유예` 넷으로 나누고, 각각에 ID·차단 대상·기본값·되돌리기 비용을 적는다. TRD의 미결은 PRD보다 **실험(스파이크)** 비중이 높다. "이 방식으로 그 성능이 나오는가"는 물어서 알 수 없고 해봐야 알기 때문이다. 실험으로 분류한 것은 무엇을 만들어 무엇을 보면 판정되는지 적는다. Layer 3에서 검증 태스크가 된다. **13절 추적표를 생략하지 않는다.** PRD의 모든 FR·NFR이 최소 하나의 결정에 걸려야 한다. 어디에도 안 걸린 요구사항은 "이걸 무엇으로 만들지 아무도 안 정했다"는 뜻이고, Layer 3에서 태스크가 만들어질 때 그 자리에서 즉흥적으로 정해진다. ### `CLAUDE.md` · `AGENTS.md` 갱신 `docs/TRD.md` 를 쓴 뒤 프로젝트 루트의 `CLAUDE.md` 와 `AGENTS.md` 를 **같은 내용으로** 갱신한다. 사용자가 직접 연 세션과 루프의 자식 세션은 이 스킬을 읽지 않고 시작하는데, 그때 자동으로 읽히는 파일은 Claude Code 는 `CLAUDE.md`, Codex 는 `AGENTS.md` 뿐이다. 그래서 **지금 어느 호스트에서 돌든 둘 다 쓴다** — 한쪽만 쓰면 다른 호스트의 세션이 규칙을 모른 채 시작한다. 내용은 **어느 세션에서든 반드시 지킬 것**만 두고 세부 규칙은 문서를 가리킨다 — 규칙을 옮겨 적으면 두 곳이 곧 어긋나고, 어긋나면 세션은 짧은 쪽을 믿는다. - 둘 다 없으면 아래 뼈대로 만든다. 있으면 **`## 기술 (docs/TRD.md)` 절과 `현재 단계` 줄만** 고친다. 다른 절과 사용자가 손으로 적은 내용은 건드리지 않는다 - 두 파일이 서로 다르면 지금 호스트의 파일을 기준으로 다른 쪽을 맞춘다. 손으로 적은 줄은 양쪽에 남긴다 - 파일은 있는데 `## 문서 지도`·`## 공통 규칙` 이 없으면(예: `/init` 이 만든 파일) 기존 내용 **아래에** 뼈대 두 절을 더한다. 기존 내용은 손대지 않는다 - 절이 없으면 `공통 규칙` 뒤에 제품·기술·구조·플랜·하네스·루프 순서의 자리에 더한다 - 전체 **100줄 안팎, 200줄을 넘기지 않는다.** 넘치면 규칙을 문서 쪽으로 돌려보내고 가리키는 줄만 남긴다 ```markdown # <프로젝트 이름> > harness-loop-fullstack 스킬이 만들고 갱신하는 파일이다. 각 절은 그 레이어의 스킬만 고친다. > `CLAUDE.md` 와 `AGENTS.md` 는 같은 내용이다. 한쪽을 손으로 고치면 다른 쪽도 같이 고친다. > 세부 규칙은 각 문서에 있다 — 여기에는 어느 세션에서든 반드시 지킬 것만 둔다. 200줄을 넘기지 않는다. ## 문서 지도 - `docs/IDEA.md` → `docs/PRD.md` → `docs/TRD.md` → `docs/ARCHITECTURE/` → `plan_setup/` → `harness_setup/` → `loop_setup/LOOP.md` - 뒤 문서는 앞 문서를 근거로 한다. 어긋나면 앞 문서가 이긴다 — 바꿔야 하면 사용자 확인 뒤 **가장 앞 문서부터** 고치고(버전·`변경 이력` 한 줄. 프로젝트 완료 뒤에는 `feature-add`·`refactor-plan` 의 후미 절로) 사이 문서를 맞춘 다음 이어 간다(변경 전파). 손으로 고칠 때도 같다. 루프 세션은 앞 문서를 고치지 않고 LOOP.md 대로 멈춘다 - 현재 단계: <마지막으로 끝낸 스킬> → 다음: <다음 스킬> ## 공통 규칙 - 앞 레이어의 **파일**만 입력이다. 대화 기억이나 추측으로 요구사항·기술 결정을 만들지 않는다 - ID(`FR-`·`NFR-`·`US-`·`OQ-`·`TD-`·`phase-NN-task-MM`)는 참조만 한다. 새 ID 는 마지막 번호 다음으로만 만든다 — OQ 는 프로젝트 전체(`HARNESS.md`·`LOOP.md` 의 미결 표까지)에서, 나머지는 그 문서에서 센다(변경 전파로 앞 문서에 더할 때도) - 사용자가 말하지 않은 값은 `(가정)` 으로 표시한다. 모호하면 추측하지 말고 묻는다 - 요청된 범위를 조용히 넓히거나 줄이지 않는다. 범위 판단은 보고한다 ``` `## 기술 (docs/TRD.md)` 절에는 이것만 적는다. ```markdown ## 기술 (docs/TRD.md) - 스택: <언어/프레임워크 · DB · 배포 — 한 줄> - 되돌리기 비용이 큰 결정: (2~3개) - TRD 에 없는 라이브러리·외부 서비스를 들이지 않는다. 필요하면 TD 를 더한 뒤 쓴다 ``` ## 7단계. 자체 점검 후 인계 파일을 쓴 뒤 처음부터 다시 읽으면서 아래를 확인한다. | 확인할 것 | 통과 조건 | 걸렸을 때 | |---|---|---| | 근거 없는 결정 | 근거 요구사항이나 여건이 비어 있는 TD가 0개 | 지운다. 요구사항이 요구하지 않는 기술이다 | | 검증 방법 | 모든 TD에 관찰 가능한 검증 방법이 있음 | 채운다. 못 쓰겠으면 그 결정이 무엇도 정하지 않은 것이므로 다시 쓴다 | | 대안과 되돌리기 비용 | 모든 TD에 있음 | 채운다 | | NFR 실현 | 10절에 PRD의 모든 NFR이 있고 실현 수단과 확인 방법이 채워짐 | 채운다. 실현 수단이 없으면 보고한다 | | 요구사항 누락 | 어떤 결정에도 안 걸린 FR·NFR이 0개 (PRD 9절 `상태` 가 `폐기` 인 것은 세지 않는다) | 채운다 | | 아키텍처 침범 | 테이블 컬럼 정의, 엔드포인트 목록, 컴포넌트 트리가 0건 | 지우고 Layer 2로 넘긴다 | | 요구사항 신설 | TRD에만 있고 PRD에 없는 기능이 0건 | TRD 에서는 지운다. 그 기능이 정말 필요하면 사용자에게 묻고, 넣기로 하면 PRD 부터 고친 뒤(아래 "PRD 로 돌려놓기") 그 FR 을 근거로 TD 를 둔다 | | 테스트 | 테스트 도구가 결정으로 있고, 반드시 덮어야 할 영역에 근거 요구사항이 붙음 | 채운다 | | 하네스 침범 | 품질 게이트 구성·E2E 흐름 목록·task validation 절차가 0건 | 지우고 Layer 4로 넘긴다 | | 결정 개수 | 되돌리기 비용이 독립적으로 발생하는 것만 남음. 대개 20개 이하 | 상위 결정에 흡수한다 | | 로컬 개발 환경 | 9.3절 표에 함께 떠야 할 구성 요소가 근거 TD와 함께 있음 | 채운다. 하네스가 이 표를 그대로 받는다 | | 팀 역량 | 팀이 다뤄 본 적 없는 기술의 수 | 임의로 바꾸지 말고 학습 비용과 함께 보고한다 | | 예산 | 비용 추정이 확인된 예산 안에 듦 | 초과하면 대안과 함께 보고한다 | | 차단 미결 | PRD의 차단 미결이 남은 채로 확정된 결정이 없음 | 해당 결정을 '잠정'으로 내리고 보고한다 | | `CLAUDE.md` · `AGENTS.md` | 두 파일이 같고 `## 기술` 절이 갱신됐고 각 200줄 이하 | 자기 절만 고친다. 넘치면 규칙을 문서로 돌려보내고 가리키는 줄만 남긴다 | **임의로 고쳐도 되는 것과 보고해야 하는 것이 다르다.** 형식 문제(검증 방법 누락, 아키텍처 침범 문장)는 고치면 된다. 범위와 비용 판단(팀 역량 밖의 스택, 예산 초과, 실현 수단 없는 NFR)은 사용자의 결정이므로 고치지 말고 보고한다. 여기서 조용히 만만한 기술로 바꾸면, 사용자는 자기 요구사항이 못 지켜지게 된 줄 모른 채 다음 레이어로 넘어간다. 그다음 사용자에게 보고한다. 1. `docs/TRD.md` 를 만들었다는 사실과 결정 개수(TD n개, 그중 잠정 n개, 스파이크 필요 n개) 2. **되돌리기 비용이 큰 결정 3개** — 이게 보고의 핵심이다. 사용자가 검토에 쓸 시간은 한정돼 있고, 그 시간은 나중에 못 되돌릴 결정에 써야 한다. 각각에 검토한 대안과 탈락 이유를 함께 보여 준다 3. 미결 사항 — 차단하는 결정과 함께. 실험으로 분류한 것은 무엇을 해보면 판정되는지도 적는다 4. 자체 점검에서 걸렸지만 임의로 고치지 않은 것 (팀 역량, 예산, 실현 수단 없는 NFR) 5. 다음 단계 안내: "검토하시고, 괜찮으면 아키텍처로 넘어갈까요? (`architecture-generator`)" 사용자 검토 전에 아키텍처로 넘어가지 않는다. 기술 결정이 틀린 채로 넘어가면 아키텍처 전체가 같이 틀린다. ### PRD 로 돌려놓기 — 보고하고 멈추지 않는다 기술을 고르다 보면 **PRD 를 바꿔야 풀리는 것**이 나온다 — 어떤 기술로도 NFR 수치를 못 맞춘다, 기술이 PRD 에 없는 기능(관리자 화면, 재시도 알림)을 요구한다, 사용자가 "이것도 넣자"고 말한다, 차단 미결의 답이 이 자리에서 나온다. 보고만 하고 넘어가면 PRD 와 TRD 가 다른 말을 한 채 아키텍처로 가고, 아키텍처가 같은 것을 충돌로 다시 올린다. 1. **결정은 사용자에게 묻는다** — 선택지 셋 이하(예: ① NFR 수치를 조정 ② 기술을 바꾸고 비용을 감수 ③ 그 FR 을 범위 밖으로). 여러 건이면 한 번에 묶는다. 답을 받기 전에는 반영하지 않는다 — 대화할 수 없는 세션(무인·평가)이면 결정이든 기록이든 다른 레이어 문서는 고치지 않고(그 스킬도 부르지 않고) 지금처럼 보고·CF·미결로 남긴다. 2. 고른 대로 **PRD 를 먼저 고친다** — `prd-generator` 8단계(부분 갱신)로. 부를 수 없으면 같은 규칙으로 직접: 바뀐 항목만, ID 유지·새 ID 는 끝번호, 9절 추적표, PRD 버전과 `변경 이력` 한 줄 3. TRD 머리의 `입력 문서` 를 새 PRD 버전으로 맞추고, 고친 FR·NFR 을 근거로 TD 를 쓰고 하던 일을 이어 간다 4. 7단계 보고에 **`앞 문서 반영`** 묶음을 둔다 — PRD 의 새 버전, 바뀐 ID, 누가 무엇을 골랐는가 사용자가 "PRD 는 나중에"라고 하면 그때만 해당 TD 를 `잠정` 으로 두고 미결로 남긴다. Layer 6(`feature-add`·`refactor-plan`)이 이 스킬을 부른 중이면 앞 문서는 본문이 아니라 **그 요청의 후미 절**(`## 추가 N`·`## 리팩토링 N`)에 적는다 — 원본 규칙이다. `refactor-plan` 이 부른 중에 PRD 를 바꿔야 하면 그것은 요구 변경이라 반영하지 않고 "`feature-add` 로 다룰 일"로 보고한다(리팩토링은 PRD 를 쓰지 않는다). ## 8단계. 미결 해소 세션 PRD와 같은 이유로, 여기서 최대한 태운다. **TRD의 미결 하나는 아키텍처에서 설계 분기가 되고, 플랜에서 blocked 태스크 여러 개가 된다.** ``` TRD에 미결 1건 (외부 서비스 A를 쓸 수 있는가) → 아키텍처: A를 쓰는 설계와 직접 만드는 설계 둘 다 감당하거나, 한쪽으로 정하고 나중에 갈아엎는다 → 플랜: 관련 태스크 5~8개가 전부 blocked 로 시작한다 → 루프: blocked 태스크에 의존하는 후속 태스크까지 밀린다 ``` **차단(되돌리기 비용이 큰 결정을 막는 것) 먼저, 그다음 비싼 순서**로 제시한다. TRD의 미결에는 PRD에 없던 처리 경로가 하나 더 있다 — **스파이크**다. "이 방식으로 그 숫자가 나오는가"는 사용자에게 물어도 답이 없다. 이런 것은 객관식으로 묻지 말고, **무엇을 만들어 무엇을 재면 판정되는지**를 적어 Layer 3에서 검증 태스크가 되게 한다. 예를 들면 이렇게 쓴다. > **OQ-015** (실험 · TD-007을 막음) — 선택한 PDF 생성 방식이 NFR-002의 10초 안에 드는가 > **스파이크**: 조항 30개짜리 문서 1건을 실제로 생성해 소요 시간을 5회 측정한다 > **판정**: 중앙값 10초 초과면 TD-007을 대안으로 교체하거나 NFR-002를 사용자와 조정한다 > **기본값**: 현재 선택으로 진행한다. Layer 3의 첫 phase에 이 스파이크를 넣는다 '질문' 종류만 선택지와 함께 묻는다. '확인'·'실험'·'유예'를 객관식으로 물으면 사용자는 모르는 것을 찍게 되고, 그 찍은 답이 확정된 합의로 문서에 박힌다. 모델이 혼자 가정한 것보다 나쁘다 — 그건 `(가정)` 표기라도 남는다. **분류가 틀렸으면 바꿔 달라고 사용자에게 명시적으로 요청하고, 선택지 대신 "알아봐야 안다"고 답할 길을 열어 둔다.** 바뀐 내용은 그 자리에서 TRD에 반영한다. 대화에서만 합의하고 문서를 안 고치면 다음 레이어는 옛날 문서를 읽는다. ### 언제 멈추는가 미결이 다 풀리지 않아도 아키텍처로 넘어갈 수 있다. **조건은 되돌리기 비용이 큰 결정(저장소, 인증 모델, 배포 형태)에 걸린 미결이 없는 것**이다. 이 셋은 아키텍처 전체가 그 위에 세워지므로, 나중에 뒤집히면 설계를 다시 하게 된다. 지금 당장 못 푸는 미결이 이 셋에 걸려 있다면 사용자에게 두 가지 중 하나를 고르게 한다. 1. 스파이크·확인을 먼저 하고 결과를 기다린다 2. 기본값으로 진행하되, 되돌리기 비용을 감수한다고 명시적으로 확인한다 ## 9단계. 이미 `docs/TRD.md` 가 있을 때 — 부분 갱신 PRD 가 바뀌었거나(머리의 `입력 문서` 버전보다 PRD 버전이 높다), 아키텍처·하네스가 TRD 에 없는 기술(Redis, 브라우저 도구)을 필요로 하거나("설계 유발"), CF 해소로 TD 를 교체하기로 했거나, 라이브러리를 바꾸기로 했을 때 이 단계가 받는다. **불린 자리에 따라 셋이다.** 다른 스킬(PRD 의 연쇄든 뒤 스킬의 변경 전파든)이 불렀으면 결정은 이미 내려졌으니 기록하고 돌아간다 — 뒤 문서는 부른 스킬이 맞춘다. 다만 바뀐 요구사항 때문에 **새 기술 결정**이 필요하면(어느 기술로 만들지가 새로 생긴다) 3단계 규칙대로 사용자에게 묻고, 답을 받은 뒤 적는다. 사용자가 직접 불렀으면 3단계 규칙대로 결정하고 끝에 뒤 문서까지 맞춘다(프로젝트가 완료됐으면(`STATE.md` 의 `Phase Overview` 가 전부 `completed`) 이 단계로 본문을 고치지 않고 `feature-add`(요구 변경)·`refactor-plan`(기술·구조 변경)으로 안내한다). Layer 6(`feature-add`·`refactor-plan`)이 후미 절 모드로 불렀으면 그 지시가 우선이다 — 본문 대신 후미 절(대체한 TD 제목 아래 `> 대체됨 — '## 추가 N'`·`'## 리팩토링 N'` 한 줄만 예외), 뒤 문서는 부른 스킬이 부른다. Layer 6 후미 절 모드면 `변경 이력` 줄은 쓰지 않고 버전만 올린다 — 후미 절 첫 줄(날짜·요청·ID)이 이력이다. - **PRD 가 바뀌었으면 PRD 의 `변경 이력` 에서 기록된 버전 뒤의 줄부터 읽는다.** 그 줄의 `영향` 과 바뀐 FR·NFR 을 13절 추적표에서 찾으면 다시 볼 TD 가 나온다. 거기만 다시 본다(이력이 없는 옛 PRD 면 13절 추적표 전체를 PRD 와 대조한다) - **바뀐 TD 만 고친다.** 파일을 통째로 다시 쓰지 않는다 - **TD 번호는 유지한다.** 새 TD 는 마지막 번호 다음, 교체된 TD 는 지우지 않고 `폐기 — 대체: TD-0xx` 로 표시한다. 아키텍처와 태스크가 그 번호를 가리킨다 - 새·바뀐 TD 에도 근거 요구사항·대안·검증 방법·되돌리기 비용·확정도를 3단계 형식 그대로 채운다 - 2절 요약표·10절 NFR 실현표·13절 추적표·9.3절 로컬 개발 환경 표의 해당 행을 맞춘다. 풀린 미결은 8단계처럼 결정으로 옮기고 `(OQ-0xx 해소)` 를 남긴다 - **버전을 올리고 `변경 이력` 에 한 줄** — `0.2 (YYYY-MM-DD, <부른 스킬>) — <무엇을 왜>. 영향: <설계 단위·태스크>`. `입력 문서` 의 PRD 버전도 맞춘다 - 결정 중 PRD 를 바꿔야 하는 것이 나오면 위 "PRD 로 돌려놓기"를 먼저 한다 - **다른 스킬이 이 단계를 불렀으면(앞 스킬이든 뒤 스킬이든) 뒤 문서 연쇄를 하지 않고 그 스킬로 돌아간다** — 뒤 문서 연쇄는 처음 시작한 스킬 하나가 순서대로 부른다. 둘이 각자 연쇄하면 같은 문서를 두 번 고친다. `CLAUDE.md` 의 `현재 단계` 줄은 건드리지 않는다 — 단계가 바뀐 것이 아니다. **뒤 문서 맞추기(사용자가 직접 불렀을 때).** 아키텍처(`architecture-generator` 9단계) → 플랜(`plan-generator` 10단계) → 하네스(`harness-update`) → 루프(`loop-update`) 중 이미 있는 것을 차례로 부른다. 루프가 도는 중이면 플랜부터는 부르지 않고 무엇이 낡았는지 보고한다. --- ## 에이전트별 참고 - Claude Code에서 실행 중이면: `references/claude-code.md` - Codex에서 실행 중이면: `references/codex.md`