Files
document-haness/README.md
T

166 lines
9.4 KiB
Markdown

# Technical Document Flow
기술 문서를 “정보가 많은 글”이 아니라 “독자가 한 단계씩 납득하는 글”로 만드는 작성 하네스입니다.
참조 문서인 `executable-clean-architecture.md`에서 다음 논증 흐름을 추출해 일반화했습니다.
```text
실패 장면
→ 진짜 원인
→ 설계 요구사항
→ 필요한 원리
→ 선택과 구현
→ 종단 동작
→ 자동 검증과 실패 실험
→ 비용·한계
→ 처음 질문에 대한 답
```
이 순서를 모든 문서에 억지로 씌우지는 않습니다. 설명문, 의사결정 문서, 사용 절차, 참조 문서마다 다른 흐름을 선택하되, 모든 절이 독자의 질문에 답하고 다음 절이 필요한 이유를 남기게 합니다.
## 이 하네스가 막는 문제
- 해결책부터 제시해 독자가 “왜 필요한가”를 놓치는 글
- 용어를 설명하지 않은 채 타입명·약어·제품명을 한꺼번에 쏟는 글
- 주장과 근거 사이가 비어 있는 글
- 앞 절과 다음 절이 연결되지 않는 목차
- 코드·표가 본문의 논증과 따로 노는 글
- 결론에서 본문에 없던 주장을 새로 만드는 글
- 자세하지만 대상 독자가 따라갈 수 없는 글
핵심 용어 정책은 단순합니다.
> 먼저 익숙한 말로 현상과 역할을 설명하고, 다시 쓸 가치가 있을 때만 정식 용어를 붙입니다.
기술적으로 정확한 이름을 없애지는 않습니다. 코드 식별자, 표준명, 제품명은 보존하고 첫 등장 설명·사용 이유·일관된 이름을 관리합니다.
## 빠른 시작
### 에이전트에서 사용
설치 후 다음처럼 요청합니다.
```text
$technical-doc-flow
이 설계 메모를 중급 백엔드 개발자가 이해할 수 있는 기술 문서로 작성해 줘.
핵심 독자 질문은 “왜 이 경계가 필요한가?”야.
참고 자료: docs/design-notes.md, src/build.gradle
```
기존 문서를 고칠 때도 같은 스킬을 사용합니다.
```text
$technical-doc-flow
draft.md의 논리 흐름과 전문용어 부담을 검토하고 고쳐 줘.
독자는 이 기술을 처음 쓰는 애플리케이션 개발자야.
```
Claude Code에서는 같은 이름의 스킬을, Gemini CLI에서는 `/technical-doc` 또는 `/technical-doc-review`를 사용할 수 있습니다.
### 결정적 검사만 실행
LLM 없이도 구조와 용어 계약을 검사할 수 있습니다.
```bash
python3 scripts/lint_document.py \
--document _workspace/2026-07-23-001/final.md \
--reader-contract _workspace/2026-07-23-001/02_reader_contract.json \
--logic-map _workspace/2026-07-23-001/04_logic_map.json \
--term-ledger _workspace/2026-07-23-001/05_term_ledger.json \
--draft-baseline _workspace/2026-07-23-001/07_draft.md \
--output _workspace/2026-07-23-001/08_lint.json
```
실행 전체를 검증하려면 다음 명령을 사용합니다.
```bash
python3 scripts/verify_run.py --run-dir _workspace/2026-07-23-001
```
## 세 경로
| 경로 | 적합한 작업 | 흐름 |
|---|---|---|
| `light` | 짧고 이미 구조가 선 초안 | 독자·논리 계약 → 집필 → lint |
| `standard` | 일반적인 신규 문서나 구조 수정 | 근거 정리 → 논리 설계 → 집필 → 독립 리뷰 2종 → 마무리 → lint |
| `deep` | 장문, 근거가 많거나 검증 기록이 필요한 문서 | standard + 장문 분할 + 엄격 gate |
사용자가 경로를 지정하면 그 선택이 우선합니다. 지정하지 않으면 brief·기존 draft·모든 UTF-8 source를 합친 글자 수와 제목 수, source 수, 신규 작성 여부를 코드가 판정합니다. 계산값은 `00_run.json.route_metrics`에 남고 verifier가 원본으로 다시 계산합니다. 점수 산출에 실패하면 품질 단계를 생략하지 않고 `standard`로 내려갑니다.
## 실행 산출물
각 실행은 `_workspace/{YYYY-MM-DD-NNN}/`에 분리됩니다.
```text
00_run.json 실행 상태·경로 지표·입력/계약/규칙 해시
01_input.md 요청과 원문
01_sources.json 참고 자료 인벤토리
02_reader_contract.json 독자·목적·선수지식·비목표
03_evidence_map.json 주장과 근거, 관찰/추론/권고 구분
04_logic_map.json 절별 질문·답·연결·독자 상태
05_term_ledger.json 정식 용어·쉬운 설명·첫 등장·별칭
07_draft.md 초안
08_logic_review.json 논증 리뷰
08_reader_review.json 독자·용어 리뷰
08_lint.json 결정적 검사 결과
final.md 최종 문서
09_final_report.json 최종 판정과 남은 한계
```
`final.md`만 보아도 쓸 수 있지만, 나머지 파일은 왜 이런 구조와 표현을 택했는지 재현하는 감사 기록입니다.
경로상 생략 가능한 파일을 만들지 않았다면 `00_run.json.omissions`에 파일별 이유를 기록합니다. 최종 verifier는 필수 파일이나 이미 존재하는 파일을 생략했다고 선언하지 않았는지 확인하고, 검증된 목록을 `09_final_report.json`에 그대로 남깁니다.
최종 보고서의 `verdict`는 하네스 실행의 완전성, `document_verdict`는 문서 판정입니다. review 모드에서 결함을 정확히 찾아 `document_verdict: revise`가 나온 실행은 `verdict: pass`일 수 있으므로, 진단 성공을 문서 통과와 혼동하지 않습니다. 보고서에는 현재 문서·계약·규칙 SHA-256과 일치한 lint/review만 요약하며, lint의 error/warning 수·rule ID·fidelity·한계와 review별 finding 수·ID를 함께 남깁니다.
lint report는 입력 파일을 output으로 지정할 수 없고, 기존 파일은 같은 도구가 만든 report일 때만 다시 씁니다. verifier output은 run 안의 canonical `09_final_report.json`만 허용합니다. 상태 갱신과 검증은 crash-safe run lock을 공유하며, 일반 `update_run.py` 호출로 `verified`를 만들 수 없습니다. 각 상태 checkpoint도 단계별 파일/schema와 현재 review·lint hash를 직접 검사하므로 빈 파일이나 오래된 pass report로 진행 상태를 앞당길 수 없습니다. 실패 terminal 상태는 다른 상태로 다시 전이하지 않습니다.
write/revise의 `final.md`는 검토·확정한 `07_draft.md`의 byte-identical 게시 복사본입니다. 표현 하나라도 고칠 필요가 생기면 draft를 먼저 고치고 적용되는 두 리뷰를 다시 만든 뒤 복사합니다. 이 경계가 리뷰 뒤의 작은 부정어 변경 같은 의미 드리프트를 막습니다.
## 품질 원칙
1. **독자 먼저** — 대상 독자와 선수지식이 비어 있으면 집필을 시작하지 않습니다.
2. **한 문장 핵심 주장** — 문서가 끝까지 증명할 답을 앞부분에 둡니다.
3. **질문에서 답으로** — 각 절은 독자 질문, 답, 근거, 한계, 다음 연결을 가집니다.
4. **쉬운 설명 후 이름** — 현상·역할을 평이하게 설명한 뒤 필요한 정식 용어를 소개합니다.
5. **근거의 종류 공개** — 관찰한 사실, 거기서 도출한 추론, 저자의 권고를 섞지 않습니다.
6. **검증의 한계 공개** — 테스트가 증명하는 것과 증명하지 않는 것을 함께 적습니다.
7. **결론에서 새 주장 금지** — 처음 문제와 요구를 본문의 구현 또는 명시한 한계에 다시 연결합니다.
8. **코드는 객관적 gate** — 제목, 링크, 용어 첫 사용, 약어, 산출물 계약은 LLM의 자기평가를 믿지 않고 스크립트로 확인합니다.
## 디렉터리
```text
skills/technical-doc-flow/ 단일 오케스트레이터와 런타임 규칙
├─ config/ 품질 규칙 SSOT
├─ schemas/ 산출물 JSON Schema
└─ scripts/ 설치본에서도 동작하는 결정적 런타임
agents/ 좁은 역할의 작성·리뷰 에이전트
scripts/ 저장소 루트용 얇은 CLI 진입점
tests/ 단위·golden·offline E2E·선택적 live 평가
commands/ Gemini CLI 명령
.claude-plugin/ Claude 플러그인 메타데이터
```
구현 원리와 유지보수 규칙은 [CLAUDE.md](CLAUDE.md), 설치 방법은 [INSTALL.md](INSTALL.md), 테스트 철학은 [tests/README.md](tests/README.md)를 참고하세요.
## 지원 범위와 한계
- 현재 정본 출력은 Markdown입니다.
- 현재 하네스는 Markdown 텍스트 문서만 작성·검토합니다.
- 정적 검사는 논리의 의미를 완전히 판단하지 못합니다. 그래서 논리 리뷰와 독자 리뷰를 독립 단계로 둡니다.
- 새 용어의 첫 설명, 별칭 선행 사용, 문장·문단·절 예산, 미등록 영문·코드형 후보는 기본 gate로 막습니다. 소문자 영문은 설정에 열거한 기술어만 후보로 삼아 일반 영문 산문 전체를 오탐하지 않습니다. 다만 표준명이나 코드 식별자를 무작정 쉬운 말로 바꾸는 자동 치환기는 아닙니다.
- 외부 자료의 사실성은 제공된 근거 범위 안에서만 검증합니다. 운영 효과를 관찰하지 않았다면 그렇게 쓰지 않습니다.
## 개발
```bash
python3 -m pytest tests -q
python3 scripts/build_quick_rules.py --check
python3 scripts/check_release_sync.py
```
라이브 LLM 평가는 기본 CI에서 실행하지 않으며, 명시적으로 켰을 때만 실행합니다. 자세한 조건은 [tests/README.md](tests/README.md)에 있습니다.