docs/PRD.md를 받아 "어떤 기술로 만들 것인가"를 정의하는 TRD(docs/TRD.md)를 작성한다. 스택·데이터·API·인증·보안·테스트·배포를 결정 단위로 확정하고, 각 결정에 근거가 된 요구사항과 검증 방법·되돌리기 비용을 붙여 아키텍처와 하네스가 그대로 참조할 수 있게 만든다. 사용자가 "TRD 써줘", "기술 스택 정해줘", "어떤 기술로 만들지 정리해줘", "기술 명세서", "DB 뭐 쓸지 정해줘", "배포는 어떻게 할지 정리해줘"라고 하거나, PRD 작성을 마치고 다음 단계로 넘어갈 때 반드시 이 스킬을 사용한다. 요구사항은 정해졌는데 기술 선택이 문서로 없는 상태에서 아키텍처 설계나 개발을 시작하려 할 때도 이 스킬로 먼저 기술 결정을 고정한다.
Installs into .claude/skills of the current project.
Are you the author of Trd Generator?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/gangjaeyu-trd-generator)
---
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`) — 돌아가서 고친다 |
| 테이블 컬럼·인덱스 설계, 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/PRD.md` 를 읽는다. **이것이 유일한 필수 입력이다.**
PRD가 없으면 TRD를 쓰지 않는다. 요구사항 없이 고른 기술은 근거가 없고, 근거 없는 결정은 나중에 뒤집을 수도 지킬 수도 없다.
이때는 `prd-generator` 로 먼저 요구사항을 고정하자고 제안한다. 사용자가 "PRD는 됐고 기술만 정해달라"고 하면,
최소한 **어떤 기능이 있고 무엇이 지켜져야 하는지**를 구두로 받아 TRD 1절에 '입력 문서: 사용자 설명'으로 남기고 진행한다.
이 경우 추적표의 요구사항 ID를 만들어 낼 수 없으므로, 근거 열에는 사용자가 말한 문장을 그대로 인용한다.
PRD를 읽을 때 세 가지를 먼저 추린다.
**첫째, 차단 미결이 남아 있는지 본다.** PRD 8절의 미결 중 P0를 막는 것(굵게 표시된 것)이 남아 있으면 그 위에 기술 설계를 얹지 않는다.
"전자서명이 필요한가"가 미정인 상태에서 인증·저장·외부 연동을 고르면, 답이 뒤집혔을 때 설계를 통째로 다시 한다.
차단 미결이 있으면 사용자에게 먼저 알리고 두 가지 중 하나를 고르게 한다.
1. 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)
- **상태**: 사람 검토 대기
## 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부터.)
| 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`
- 뒤 문서는 앞 문서를 근거로 한다. 충돌하면 앞 문서가 이기고, 앞 문서를 고치려면 그 레이어의 스킬을 다시 부른다
- 현재 단계: <마지막으로 끝낸 스킬> → 다음: <다음 스킬>
## 공통 규칙
- 앞 레이어의 **파일**만 입력이다. 대화 기억이나 추측으로 요구사항·기술 결정을 만들지 않는다
- ID(`FR-`·`NFR-`·`US-`·`OQ-`·`TD-`·`phase-NN-task-MM`)는 참조만 한다. 새 ID 는 그 레이어의 스킬만 만든다
- 사용자가 말하지 않은 값은 `(가정)` 으로 표시한다. 모호하면 추측하지 말고 묻는다
- 요청된 범위를 조용히 넓히거나 줄이지 않는다. 범위 판단은 보고한다
```
`## 기술 (docs/TRD.md)` 절에는 이것만 적는다.
```markdown
## 기술 (docs/TRD.md)
- 스택: <언어/프레임워크 · DB · 배포 — 한 줄>
- 되돌리기 비용이 큰 결정: <TD-xxx 한 줄> (2~3개)
- TRD 에 없는 라이브러리·외부 서비스를 들이지 않는다. 필요하면 TD 를 더한 뒤 쓴다
```
## 7단계. 자체 점검 후 인계
파일을 쓴 뒤 처음부터 다시 읽으면서 아래를 확인한다.
| 확인할 것 | 통과 조건 | 걸렸을 때 |
|---|---|---|
| 근거 없는 결정 | 근거 요구사항이나 여건이 비어 있는 TD가 0개 | 지운다. 요구사항이 요구하지 않는 기술이다 |
| 검증 방법 | 모든 TD에 관찰 가능한 검증 방법이 있음 | 채운다. 못 쓰겠으면 그 결정이 무엇도 정하지 않은 것이므로 다시 쓴다 |
| 대안과 되돌리기 비용 | 모든 TD에 있음 | 채운다 |
| NFR 실현 | 10절에 PRD의 모든 NFR이 있고 실현 수단과 확인 방법이 채워짐 | 채운다. 실현 수단이 없으면 보고한다 |
| 요구사항 누락 | 어떤 결정에도 안 걸린 FR·NFR이 0개 | 채운다 |
| 아키텍처 침범 | 테이블 컬럼 정의, 엔드포인트 목록, 컴포넌트 트리가 0건 | 지우고 Layer 2로 넘긴다 |
| 요구사항 신설 | TRD에만 있고 PRD에 없는 기능이 0건 | PRD로 돌려보낸다. 여기서 확정하지 않는다 |
| 테스트 | 테스트 도구가 결정으로 있고, 반드시 덮어야 할 영역에 근거 요구사항이 붙음 | 채운다 |
| 하네스 침범 | 품질 게이트 구성·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`)"
사용자 검토 전에 아키텍처로 넘어가지 않는다. 기술 결정이 틀린 채로 넘어가면 아키텍처 전체가 같이 틀린다.
## 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. 기본값으로 진행하되, 되돌리기 비용을 감수한다고 명시적으로 확인한다
---
## 에이전트별 참고
- Claude Code에서 실행 중이면: `references/claude-code.md`
- Codex에서 실행 중이면: `references/codex.md`