pipeline: make tech-log-tree.json the one decomposition contract and enforce it
리뷰 두 건을 반영했다. 계약 - tech-log-tree.json 하나가 분해 계약이자 색인이다. 사람이 읽는 트리·Node Specification· 후보 대장은 없어졌고, 문서에 남아 있던 그 개념을 걷어냈다 - candidateScope — 후보를 찾는 SSOT 범위. 접어 넣은 제2부·제3부는 근거이지 후보가 아니다 - sourceRepository — 분석한 저장소의 경로·리비전·판단 근거. 리비전을 모르면 null 로 두고 지어내지 않는다. 갈래가 여럿이면 revisions - 검사기: 계약 미채택·PENDING·PROMOTE↔글감 양방향·candidateScope·sourceRepository 를 error/warn 으로 센다. 옛 스키마도 검사를 피하지 못한다. 테스트 22 → 31 기록 쓰기 - 템플릿 5종에 source·sourceRevision·topicName, Question 에 닫는 조건, 본문 없는 종류에서 assets 제거. 고정 절 개수 삭제 - check_evidence.mjs — 인용한 코드가 SSOT 에 있는지, 앵커가 SSOT 를 가리키는지, 제목이 계약과 같은지, 리비전이 저장소에 있는지. 게시된 기록에서 SSOT 와 다른 URL 을 잡았다 문체 - 문체 규칙의 정본을 ai-tells.md 로. explaining.md 의 질문체 제목·절 끝 대조 반복·그림 예고 규칙을 삭제해 충돌을 없앴다. 첫 절 「설명 뒤에 평가를 붙이지 않는다」에 지우는 사례 네 유형 - voice 스킬의 「독자 쪽을 본다」를 자료에 오독 기록이 있을 때로 좁히고, 평가만 더한 예시를 교체 - check_prose: 안내 문장을 요구하던 경고 제거, 문장이 끝나지 않은 채 문단이 끝나는 조각 검사 추가 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
73026cada6
commit
9d2a3725c5
@@ -9,6 +9,7 @@
|
||||
| SSOT에서 글감을 뽑아 트리를 만든다 | `deriving-tech-log-root-tree` |
|
||||
| 글감 하나를 기록으로 쓴다 | `writing-tech-log-records` |
|
||||
| 문장이 AI가 쓴 것처럼 읽히면 다시 쓴다 | `rewriting-technical-prose-naturally` |
|
||||
| 맞는 말인데 아무도 쓰지 않은 보고서처럼 읽히면 | `writing-as-the-person-who-did-it` |
|
||||
| 그림을 만든다 | `technical-visualizer` |
|
||||
| 분석에서 리팩터링 작업 항목을 뽑는다 | `refactoring-from-analysis` |
|
||||
|
||||
@@ -18,6 +19,10 @@
|
||||
|
||||
```text
|
||||
원자료
|
||||
→ SSOT final/document.md 하나. 여기서만 글감을 찾는다
|
||||
→ 후보 처분 PROMOTE · MERGE_INTO · KEEP_IN_SSOT · NEEDS_EVIDENCE · NEEDS_DECISION
|
||||
→ 분해 계약 tech-log-tree.json — PROMOTE 이고 CONFIRMED 인 것만 올린다. 주제마다 독자 질문 한 줄
|
||||
→ 색인 생성 build-tech-log-tree.py · verify-tech-log-tree.py (error 0)
|
||||
→ 종류 선택 Case · Concept · Reference · Question · Decision
|
||||
→ 칸 채우기 종류마다 칸이 다르다
|
||||
→ 본문 작성 Case · Concept. 코드·표·다이어그램·이미지
|
||||
@@ -66,35 +71,99 @@ SVG로 컴파일한다. 손으로 SVG를 그리지 않는다. **그림 안에는
|
||||
|
||||
프로젝트 하나가 폴더 하나다. 프로젝트 문서는 그 폴더 밖에 두지 않는다.
|
||||
|
||||
**끝난 프로젝트의 폴더는 둘이고, 각각 정본 파일이 하나다.**
|
||||
|
||||
```text
|
||||
docs/<프로젝트>/
|
||||
├── source/ 밖에서 가져온 원본. 고치지 않는다
|
||||
├── state.json 분석 상태 — 어디까지 봤나, 어느 리비전을 봤나
|
||||
├── source-index.md 분석한 코드의 목록
|
||||
├── analysis/ 모듈·서브시스템 단위 분석. 큰 저장소는 여기서 누적한다
|
||||
│ 한 모듈을 끝까지 읽은 결과를 한 편으로 둔다
|
||||
├── notes/ · checkpoints/ 분석 중에 남긴 메모와 중간 저장
|
||||
├── final/ SSOT — 이 프로젝트에 대해 아는 것 전부
|
||||
│ ├── document.md 상세한 글
|
||||
│ ├── assets/ svg, drawio, 그림
|
||||
│ ├── .techviz/ 그림의 정본 (context, spec, prompt)
|
||||
│ ├── assets/ 그림. 그림 하나가 폴더 하나다 — <이름>/<이름>.svg 와 편집 형식들
|
||||
│ │ └── tech-log-studio/ Studio 에 올릴 표현물. 기록의 assets: file: 이 가리키는 자리
|
||||
│ ├── .techviz/ 그림의 정본 (context, spec, prompt). <이름>/ 이 assets 와 짝이다
|
||||
│ └── evidence/ 증거. 원문이 정본이고 그림은 표현물이다
|
||||
│ ├── raw/ 명령 출력·csv·덤프 원문 — 정본
|
||||
│ ├── meta/ 그 실행의 command·cwd·executedAt·exitCode·revision
|
||||
│ ├── rendered/ raw 에서 만든 터미널 SVG (표현물)
|
||||
│ └── browser/ 브라우저 캡처 (Playwright MCP)
|
||||
└── tech-log-studio/ Studio 에 올릴 글만
|
||||
├── root-tree.md 사람이 쓴 분해 계약 — SSOT 의 sha256 을 물고 있다
|
||||
├── candidate-ledger.json · root-tree-source-manifest.json
|
||||
├── tech-log-tree.json 위에서 파생한 색인. 기록을 고치면 다시 만든다
|
||||
├── _meta/ 편집·검증 이력
|
||||
├── tech-log-tree.json 분해 계약이자 색인. 이 프로젝트의 글감 전부다
|
||||
└── <주제 slug>/
|
||||
├── case/ concept/ reference/ question/ decision/
|
||||
```
|
||||
|
||||
**분해 계약이 정본이고 `tech-log-tree.json` 은 색인이다.** `root-tree.md` 는 글감마다 readiness·
|
||||
source anchor·classification·missing-verification 을 사람이 적는 자리이고, json 은 기록 파일을
|
||||
읽어 지금 상태를 비추는 것이다. 둘이 어긋나면 `root-tree.md` 가 맞다.
|
||||
**분석하거나 반입하는 동안에만 있는 것이 따로 있다.**
|
||||
|
||||
```text
|
||||
├── source/ 밖에서 가져온 원본. 대조가 끝나면 지운다
|
||||
├── state.json 분석 상태 — 어디까지 봤나, 어느 리비전을 봤나
|
||||
├── source-index.md 분석한 코드의 목록
|
||||
├── analysis/ 모듈·서브시스템 단위 분석. 큰 저장소는 여기서 누적한다
|
||||
└── notes/ · checkpoints/ 분석 중에 남긴 메모와 중간 저장
|
||||
```
|
||||
|
||||
**이것들은 작업 재료다.** 틀도 프로젝트 폴더가 아니라
|
||||
`.agents/skills/analyzing-codebase-for-tech-log/templates/` 에 있다. 끝나면 두 번 합친다.
|
||||
|
||||
```bash
|
||||
python3 scripts/fold-analysis-into-final.py <프로젝트> # 분석 재료 → final/document.md
|
||||
python3 scripts/fold-studio-contract-into-index.py <프로젝트> # 분해 재료 → tech-log-tree.json
|
||||
```
|
||||
|
||||
모듈 분석은 `final/document.md` 제2부로, `source-index.md` 와 스코프 커버리지와 분석 과정
|
||||
노트는 제3부로 옮기고, `analysis/NN` 을 가리키던 앵커를 `final/document.md#aNN` 으로 고친
|
||||
뒤 폴더를 지운다. 분해 쪽도 같다 — 사람이 쓴 트리와 Node Specification, 후보 대장, 편집
|
||||
이력이 `tech-log-tree.json` 하나로 들어간다. **옮기는 것이지 요약하는 것이 아니다** — 요약만 하고 근거를 원래 자리에
|
||||
둔 채로 `COMPLETE` 를 찍으면 기록의 `source` 가 `analysis/` 를 가리켜 SSOT 가 둘이 된다.
|
||||
`verify-project-layout.py` 의 「작업 재료가 남아 있다」와 `verify-tech-log-tree.py` 의
|
||||
「근거가 SSOT 밖에만 있다」가 그 상태를 센다.
|
||||
|
||||
**배치의 정본은 `docs/_templates/` 다.** 폴더마다 `README.txt` 가 무엇을 담는지 한 줄로 적혀
|
||||
있고, `python3 scripts/verify-project-layout.py` 가 프로젝트들이 그 모양인지 대조한다.
|
||||
|
||||
**`tech-log-tree.json` 이 분해 계약이자 색인이고 정본이다.** 글감마다 readiness·source
|
||||
anchor·classification·missing-verification·relations 를 사람이 적고, 스크립트는 기록 파일에서
|
||||
읽을 수 있는 것(`file`·`publication`·`status`)만 다시 채운다. 디렉터리를 훑어 주제를 만들지
|
||||
않는다 — 폴더가 정본이면 계약에서 뺀 주제가 파일이 남아 있다는 이유만으로 되살아난다.
|
||||
계약에 없는 기록은 `unlisted` 에 적힌다.
|
||||
|
||||
정본은 층으로 나뉜다.
|
||||
|
||||
| 층 | 하는 일 |
|
||||
|---|---|
|
||||
| 코드·설정·실행 증거 | 사실의 근거 |
|
||||
| `final/document.md` | **글감 범위의 SSOT** — 후보를 발견하는 유일한 입력 |
|
||||
| `analysis/**/*.md` | final 이 이미 채택한 주장을 상세히 확인하는 보조 근거. 분석 중에만 있다 |
|
||||
| `tech-log-tree.json` | 사람이 고른 글감. 분해 계약이자 색인이고 이 파일이 정본이다 |
|
||||
|
||||
`analysis/**` 를 글감을 찾으려고 열지 않는다. 분석에만 있는 자료를 발견하면 트리에 바로 넣지 말고
|
||||
`final/document.md` 를 먼저 보강한다. 그러지 않으면 모듈 문서마다 정본 노릇을 하고 트리는 그 절
|
||||
수의 합만큼 자란다.
|
||||
|
||||
**접어 넣은 final 이 전부 후보 자리는 아니다.** 제1부(통합 분석)가 후보를 찾는 범위이고 제2부와
|
||||
제3부는 근거다. 범위는 `tech-log-tree.json` 의 `candidateScope` 에 적는다 — 적지 않으면 모듈 분석
|
||||
65편의 절 제목이 다시 글감이 된다.
|
||||
|
||||
```json
|
||||
"candidateScope": {
|
||||
"document": "final/document.md",
|
||||
"sections": ["§3", "§4", "§5", "§6", "§7", "§8", "§9", "§10", "§11"],
|
||||
"excluded": ["제2부 — 모듈 분석 전문", "제3부 — 분석 재료"]
|
||||
}
|
||||
```
|
||||
|
||||
**분석 후보 전부는 같은 파일의 `candidates` 에 처분과 함께 남고 `PROMOTE` 만 글감이 된다.**
|
||||
`KEEP_IN_SSOT` 은 버린 것이 아니라 분석에 남기고 독립 기록으로 만들지 않기로 한 것이고, 그것도
|
||||
정상적인 결과다. 제외가 0 건인 분해는 선별하지 않은 분해다.
|
||||
|
||||
계약을 아직 채택하지 않은 프로젝트도 error 다. 칸마다 error 를 내지는 않고 미채택 자체를 한 번
|
||||
센다 — 경고로 두면 옛 스키마로 남아 있는 한 검사를 피한다.
|
||||
|
||||
처분과 글감은 양쪽으로 맞아야 한다 — `PROMOTE` 인데 글감이 없는 것도, 글감인데 그것을 낳은
|
||||
`PROMOTE` 후보가 없는 것도 error 다. 사람이 다시 읽지 않은 후보(`dispositionReview: PENDING`)도
|
||||
error 다. 경고로 두면 재판정하지 않은 트리로 글을 쓰기 시작하게 된다.
|
||||
|
||||
**readiness 와 게시 여부는 다른 것이다.** readiness 는 증거가 갖춰진 정도이고, 글을 썼는지·Studio 에
|
||||
올렸는지는 색인의 `file` 과 `publication` 이 따로 말한다.
|
||||
|
||||
`final/` 이 정본이고 `tech-log-studio/` 는 거기서 뽑아낸 글이다. 증거는 `final/evidence/` 에만
|
||||
두고 기록에서는 그 파일을 가리킨다. 같은 파일을 양쪽에 두지 않는다.
|
||||
@@ -104,7 +173,8 @@ source anchor·classification·missing-verification 을 사람이 적는 자리
|
||||
`README.txt` 에 적는다 — 파일 이름만으로는 6개월 뒤에 못 읽는다.
|
||||
|
||||
**SVG 는 정본이 아니다.** 실행한 명령의 원문과 메타데이터가 정본이고 터미널 SVG 는 문서에 넣기
|
||||
위한 표현물이다. 원문 없이 SVG 만 남기지 않는다.
|
||||
위한 표현물이다. 원문 없이 SVG 만 남기지 않는다. 그림도 같다 — `.techviz/<이름>/` 없이 남은
|
||||
SVG 는 다시 만들 수 없고, `verify-project-layout.py` 가 그런 그림을 센다.
|
||||
|
||||
```bash
|
||||
python3 scripts/terminal-evidence/render_terminal.py \
|
||||
@@ -138,18 +208,35 @@ Redis 20편은 한 글을 나눠 쓴 것이라 `docs/clean-architecture-backend-
|
||||
|
||||
다른 프로젝트에서 쓴 문서를 이 저장소로 옮길 때 따르는 순서다.
|
||||
|
||||
1. 원본을 `docs/<프로젝트>/source/` 에 그대로 복사한다. 손대지 않는다 — 대조할 것이 필요하다
|
||||
1. 원본을 `docs/<프로젝트>/source/` 에 그대로 복사한다. 손대지 않는다 — 대조할 것이 필요하다.
|
||||
**`source/` 도 작업 재료다** — 대조가 끝나 `final/` 이 그 내용을 담으면 지운다
|
||||
2. 원본과 증거를 `final/` 로 옮긴다. 글은 `final/document.md`, 그림은 `assets/`,
|
||||
터미널 기록·스크린샷·실행계획은 `evidence/`. **여기까지가 SSOT 다**
|
||||
3. SSOT 를 읽고 글감을 뽑아 `tech-log-tree.json` 에 적는다. 종류(case·concept·reference·
|
||||
question·decision)와 주제를 먼저 정하고 제목만 적는다. 아직 글은 쓰지 않는다
|
||||
4. 트리의 글감 하나를 골라 `<주제>/<종류>/` 아래에 기록을 쓴다. 증거는 `final/evidence/` 의
|
||||
3. SSOT 를 읽고 후보마다 처분을 적는다. §3~§8 에서 Case, §9 에서 Reference, §10 에서 Decision,
|
||||
§11 에서 Question 을 고르고, 그 넷을 이해하는 데 필요한 Concept 만 거꾸로 더한다.
|
||||
사람이 다시 읽은 후보만 `dispositionReview: CONFIRMED` 로 둔다
|
||||
4. `PROMOTE` 를 주제로 묶어 `tech-log-tree.json` 에 적는다. 주제마다 독자 질문을 한 줄 적고,
|
||||
글감마다 종류가 요구하는 칸을 채운다. 아직 글은 쓰지 않는다
|
||||
5. 트리의 글감 하나를 골라 `<주제>/<종류>/` 아래에 기록을 쓴다. 증거는 `final/evidence/` 의
|
||||
파일을 가리킨다
|
||||
5. 기록을 쓰거나 지웠으면 트리를 다시 만든다 — `python3 scripts/build-tech-log-tree.py`
|
||||
6. Studio 에 넣고 저장한다
|
||||
6. 색인을 다시 만들고 검사한다 — `build-tech-log-tree.py` · `verify-tech-log-tree.py`
|
||||
7. Studio 에 넣고 저장한다
|
||||
|
||||
`tech-log-tree.json` 은 손으로 고쳐도 되고 스크립트로 다시 만들어도 된다. 스크립트는 기록
|
||||
파일에서 제목·slug·상태를 읽어 채우고, 파일이 아직 없는 글감은 지우지 않고 남긴다.
|
||||
글감의 칸은 손으로 적고, 스크립트는 기록 파일에서 읽는 칸만 다시 채운다. 계약에 없는 기록이
|
||||
디스크에 있으면 `unlisted` 에 적히고 검사기가 error 로 센다.
|
||||
|
||||
**분석한 저장소는 `tech-log-tree.json` 의 `sourceRepository` 가 가리킨다.** 경로·리비전·그렇게
|
||||
판단한 근거를 함께 적는다. 리비전을 모르면 `null` 로 두고 지어내지 않는다 — 검사기가 warn 으로 센다. 작업이 한 줄기가 아니라
|
||||
브랜치로 갈라져 있으면 `revisions` 에 이름과 커밋을 짝지어 적는다.
|
||||
|
||||
| 프로젝트 | 저장소 |
|
||||
|---|---|
|
||||
| `clean-architecture-backend-template` | `desktop-server-git/clean-architecture-backend-template` @ `21234e38` |
|
||||
| `n+1liner` | `github-project/ca-tmpl` @ `761384d` — 저장소 HEAD 는 다른 브랜치다 |
|
||||
| `ca-tmpl` | `github-project/ca-tmpl` — 같은 저장소의 아키텍처 경계 쪽 |
|
||||
| `keycloak` | `keycloak-pattern` — 패턴 넷이 `develop-keycloak-pattern1`~`4` 브랜치에 나뉘어 있어 `revisions` 로 tip 넷을 적는다 |
|
||||
| `keycloak-session-store` | `keycloak-pattern` @ `cdac9b8` — 같은 저장소의 실험 26건 |
|
||||
| `TechLog` | `desktop-server-git/tech-log-frontend` · `tech-log-backend` |
|
||||
|
||||
| 런 또는 파일 | 문서 |
|
||||
|---|---|
|
||||
@@ -158,11 +245,25 @@ Redis 20편은 한 글을 나눠 쓴 것이라 `docs/clean-architecture-backend-
|
||||
| `keycloak-session-store` | 세션은 어디에 있는가 — Keycloak 다중 노드 실험 26건의 기록. `keycloak` 이 남긴 열린 질문 네 개에 측정으로 답한다 |
|
||||
| `n+1liner` | 하이라이트 피드 조회 성능 — N+1 진단과 조회 전략의 진화 |
|
||||
| `TechLog` | 계약이 먼저인 시스템에서 값이 사라지는 자리들 — TechLog를 만들며 만난 결함의 전수 기록 |
|
||||
| `clean-architecture-backend-template` | 62개 leaf를 23편으로 읽은 통합 분석 · 기록 949건 |
|
||||
| `clean-architecture-backend-template` | 62개 leaf를 23편으로 읽은 통합 분석 · 모듈 분석 65편을 제2부에 합쳐 46,437줄 · 기록 949건 (선별 재판정 대기) |
|
||||
|
||||
## 검사
|
||||
|
||||
게시 전에 둘 다 돌린다. 하나는 파서를, 하나는 문장을 본다.
|
||||
**분해 계약이 스스로 맞는지.** `tech-log-tree.json` 의 주제·글감·후보와 디스크의 기록이 같은
|
||||
것을 말하는지 본다. `verify-pipeline.py` 는 스킬과 틀이 제자리에 있는지를 보고,
|
||||
프로젝트 트리 정합성은 이 검사기가 본다(`--skip-projects` 로 끌 수 있다).
|
||||
|
||||
```bash
|
||||
python3 scripts/verify-tech-log-tree.py <프로젝트> # 글감 계약. error 0 까지 고친다
|
||||
python3 scripts/verify-project-layout.py <프로젝트> # 폴더 배치. 그림의 정본이 있는지도 본다
|
||||
python3 scripts/fold-analysis-into-final.py <프로젝트> # 분석 재료 → final/document.md
|
||||
python3 scripts/fold-studio-contract-into-index.py <프로젝트> # 분해 재료 → tech-log-tree.json
|
||||
python3 scripts/build-tech-log-tree.py <프로젝트> # 파생 칸(file·publication·status)만 다시 채운다
|
||||
python3 scripts/verify-pipeline.py # 위 셋을 모든 프로젝트에 돌린다
|
||||
python3 -m unittest discover -s scripts/tests # 파서·검사기·생성기
|
||||
```
|
||||
|
||||
게시 전에는 아래 둘을 돌린다. 하나는 파서를, 하나는 문장을 본다.
|
||||
|
||||
**본문이 Studio 파서를 통과하는지.** Studio가 쓰는 파서를 그대로 부르므로 통과하면 저장도 통과한다.
|
||||
|
||||
@@ -171,6 +272,14 @@ node --experimental-transform-types \
|
||||
.agents/skills/writing-tech-log-records/scripts/check_body.mjs 초안.md
|
||||
```
|
||||
|
||||
**인용한 것이 실재하는지.** 본문 코드블록의 각 줄이 SSOT 안에 있는지, `source` 앵커가 SSOT 를
|
||||
가리키는지, 제목이 계약과 같은지, `sourceRepository` 의 리비전이 그 저장소에 있는지를 본다.
|
||||
옮겨 적은 것은 확인한 것이 아니다 — 게시된 기록에 SSOT 와 다른 redirect URI 가 네 곳 있었다.
|
||||
|
||||
```bash
|
||||
node .agents/skills/writing-tech-log-records/scripts/check_evidence.mjs <프로젝트> --repo
|
||||
```
|
||||
|
||||
`tech-log-frontend` 체크아웃 경로가 다르면 `--frontend` 또는 `TECH_LOG_FRONTEND`로 알려 준다.
|
||||
|
||||
**문장이 규범을 지키는지.** `error` 가 남아 있으면 덜 된 글이다. 칸 하나나 한 절만 고쳤으면
|
||||
|
||||
Reference in New Issue
Block a user