feat: 가상화 문서들 추가

This commit is contained in:
DongHyeonka
2026-09-10 08:54:05 +09:00
parent e9f6a93327
commit 43e1aadef0
695 changed files with 153404 additions and 12754 deletions
@@ -46,16 +46,21 @@ Concept 에 담고 `관계`로 가리킨다. `references/record-kinds.md`
남겨 두고 나중에 걷어내는 순서가 아니다. **문체를 손보기 전에 문장을 고른다** — 설명이 끝난
뒤에 붙은 평가·예고·되풀이·독자 오해 가정을 먼저 뺀다(`ai-tells.md` 첫 절). 문체 규칙의
정본은 `ai-tells.md` 다.
**그림이 필요한지, 필요하면 무엇을 그릴지는 `references/choosing-a-diagram.md`.** 자리(Case·
Concept 만) · 표가 아닌지 · 옆 문단이 이미 말하지 않았는지 세 관문을 지나야 그린다.
순서·경계·상태 전이처럼 문장만으로 따라가기 어려운 관계가 있으면 **`final/assets/` 에 그
그림이 이미 있는지부터 본다.** SSOT 를 만들 때 그려 둔 것이 있고 계약의 `ssot-assets` 가 이
글감에 배정해 두었으면 그것을 쓴다 — `final/assets/tech-log-studio/` 로 복사하고 기록의
`assets` 가 그 사본을 가리킨다. **없을 때만** `technical-visualizer` 로 새로 만든다. 손으로
글감에 배정해 두었으면 기록의 `assets`**그 파일을 그대로** 가리킨다. 사본을 따로 만들지
않는다 — 사본에는 `.techviz/<이름>/` 이 없어 다시 만들 수 없다. **없을 때만**
`technical-visualizer` 로 새로 만든다. 손으로
SVG 를 그리지 않고, 모든 글에 그림을 만들지도 않는다.
인용할 측정도 같다. `final/evidence/` 에 있는 원문을 가리키고 같은 것을 다시 돌리지 않는다.
**그림과 측정을 그 자리에서 만들어 내기 전에 SSOT 가 이미 가진 것을 먼저 찾는다** — keycloak
에서는 그러지 않아 정본까지 갖춘 그림 13 장이 남고 이름이 다른 그림 5 장이 새로 만들어졌다.
4. **검사** — 셋 다 돌린다. 파서와 문장과 증빙은 각각 다른 것을 본다.
- `scripts/check_body.mjs` Case 본문이 Studio 파서를 통과하는지. 같은 파서를 그대로 부른다.
- `scripts/check_body.mjs` — 본문이 Studio 파서를 통과하는지. 같은 파서를 그대로 부른다.
저장소의 그림은 마크다운 이미지이므로 `python3 scripts/studio-body.py <기록> -o /tmp/x.md`
로 바꾼 파일에 돌린다. 저장소 파일에 그대로 돌리면 `unsafe image URL` 로 실패한다.
- `rewriting-technical-prose-naturally/scripts/check_prose.mjs` — 문장 규범. **error 0 이 될 때까지 고친다.**
칸 하나나 한 절만 고쳤으면 `--doc` 없이 부른다. 이어서 `style_profile.mjs` 로 문체 수치를 본다.
- `scripts/check_evidence.mjs <프로젝트> --repo`**인용한 것이 실재하는지.** 본문 코드블록의
@@ -77,7 +82,7 @@ Concept 에 담고 `관계`로 가리킨다. `references/record-kinds.md`
|---|---|---|
| `deriving-tech-log-root-tree` | 후보에 처분을 매기고 `PROMOTE` 를 글감으로 올린다 | 글을 쓰지 않는다 |
| `writing-tech-log-records` | 종류를 고르고 칸과 본문을 쓴다. `explaining.md`·`ai-tells.md` 를 처음부터 적용한다 | — |
| `technical-visualizer` | 문장으로 따라가기 어려운 관계를 그림으로 만든다 | 모든 글에 그림을 붙이지 않는다 |
| `technical-visualizer` | 문장으로 따라가기 어려운 관계를 그림으로 만든다 | 무엇을 그릴지 정하지 않는다 — `choosing-a-diagram.md` 가 정한다 |
| `rewriting-technical-prose-naturally` | 사실과 구조가 이미 맞는 초안의 번역투·반복 문형·과한 대구를 고친다 | 분류가 틀렸거나 근거가 모자란 것은 못 고친다 |
| `writing-as-the-person-who-did-it` | 자료에 남아 있는 선택·비교·어긋남·확인하지 못한 범위를 제자리에 놓는다 | 자료에 없는 「처음에는」·「고민 끝에」를 만들지 않는다 |
@@ -0,0 +1,82 @@
# 기록에 어떤 그림이 필요한지 정하는 기준
`code-tables-diagrams.md` 는 그림을 **어떻게** 그리는지를 말한다. 이 문서는 그 앞 단계 —
**이 기록에 그림이 필요한가, 필요하다면 무엇을 그리는가** 를 정한다.
## 세 관문
순서대로 통과해야 그림을 만든다. 하나라도 걸리면 그리지 않는다.
### 1. 자리가 있는가
`assets` 는 본문이 있는 두 종류만 갖는다 — **Case 와 Concept**. Reference·Question·Decision 의
칸은 평문으로 렌더링돼 그림이 들어갈 자리가 없다.
파생 기록에 그림이 필요해 보이면 그 그림은 **짝이 되는 Case 나 Concept 의 것**이다. 거기 담고
`관계`로 가리킨다. 담을 Case 나 Concept 이 없으면 그 그림은 아직 집이 없다 — 계약의
`assetLedger.unassigned` 에 그렇게 적고, 새 글감을 세울지는 따로 판단한다.
### 2. 표가 아닌가
> **관계선을 다 지워도 뜻이 남는가.** 남으면 표다.
표는 값을 비교하고, 그림은 **포함·순서·경계**처럼 자리로만 보이는 것을 맡는다. 항목을 같은
속성으로 늘어놓은 것은 마크다운 표로 쓴다. `verify-project-layout.py` 의 「표로 되는 그림」이
관계선 없이 항목마다 같은 수의 `details` 를 늘어놓은 spec 을 센다.
### 3. 옆 문단이 이미 말하지 않았는가
> **이 그림이 없으면 독자가 무엇을 못 보나.** 한 문장으로 답할 수 없으면 그리지 않는다.
기록에 이미 그 비교표가 있으면 그림은 중복이다. 실제로 그렇게 만든 그림 셋을 지웠다 —
`keyset-vs-offset` 을 넣은 기록에는 훑은 행·buffers·exec 까지 있는 플랜 비교표가 이미 있었다.
## 종류마다 무엇을 그리나
세 관문을 통과했을 때, 그 기록이 요구하는 그림은 종류마다 다르다.
| 종류 | 그림이 답하는 물음 | 흔한 profile |
|---|---|---|
| **Case** | 이 요청 한 번이 어떤 순서로 무엇을 지나갔나 | `sequence` · `component-flow` |
| **Case** (경계가 논지일 때) | 무엇이 어느 경계 안에 있고 무엇이 밖에 있나 | `two-zone-pipeline` |
| **Concept** | 남의 것이 어떤 순서·구조로 동작하나 | `sequence` · `component-flow` · `ports-adapters` |
Case 는 **내가 돌려서 본 것**이라 대개 순서가 논지다. Concept 은 **남의 것이 어떻게 동작하는지**라
구조나 변환 사슬이 논지다. 어느 쪽이든 「무엇이 무엇으로 바뀌는가」를 못 적으면 아직 그릴 것이
없다는 뜻이다.
**한 절에 그림 하나.** 같은 절에 구조 그림과 흐름 그림을 둘 다 넣으면 독자가 어느 쪽을 먼저
읽어야 하는지 알 수 없다. 둘 다 필요하면 절을 나눈다.
## 어디를 근거로 삼나 — 기록의 `source` 가 앵커다
`techviz prepare``final/document.md` 를 받는다. 기록은 `tech-log-studio/` 에 있지만 **그림의
근거는 기록이 아니라 기록이 가리키는 SSOT 절**이다. 기록의 `source` 앵커를 그대로 쓴다.
```bash
# 기록의 source: final/document.md#선택의-이유와-지킨-경계-ap1 이면
./scripts/techviz prepare docs/<프로젝트>/final/document.md \
--heading "AP1: OAuth와 JWT 계약을 가장 가까이서 관찰한다" \
-o docs/<프로젝트>/final/.techviz/<id>/context.json
```
`--line` 은 쓰지 않는다. context 는 관리 블록을 접은 좌표를 쓰므로 파일의 줄 번호와 어긋난다.
`--heading` 이나 `--marker` 로 절을 지목한다.
**그림이 주장하는 것을 기록 본문이 말해야 한다.** SSOT 에 근거가 있어도 기록이 그 단계를 적지
않았으면 그림만 넣지 않는다 — 설명 없는 주장이 남는다. 순서는 하나다.
> 본문을 먼저 보강한다 → 그다음 그림을 붙인다.
`ap1-browser-bearer-flow` 가 그랬다. 마지막 단계인 `/api/me` 응답 4필드를 기록이 말하지 않아
붙이지 못하고 있다가, SSOT §474 를 근거로 본문에 한 줄을 더한 뒤에 붙였다.
## 만든 뒤
`code-tables-diagrams.md` 의 규범과 아래 둘을 함께 돌린다. lint 는 라벨이 상자를 덮는 것을
못 잡는다.
```bash
python3 scripts/check-figure-text.py <프로젝트> # <text> 가 전부 이름인가
python3 scripts/preview-figure.py <프로젝트> -o /tmp/figs # PNG 로 떠서 눈으로 본다
```
@@ -160,6 +160,28 @@ SVG는 `image/svg+xml`로 올라가고 다른 이미지와 같게 다뤄진다.
`READY`가 아닌 Asset은 게시 시 거절된다.
### 저장소의 `.md` 에는 `:::evidence` 를 쓰지 않는다
`:::evidence`는 Studio 렌더러의 구문이다. 저장소의 `.md`를 그 형태로 쓰면 편집기에서 그림이
보이지 않고 구문이 글자로 남는다. **저장소는 읽는 형태로 쓴다.**
```markdown
![브라우저 SPA, Keycloak, Resource Server 사이에서 …](../../../final/assets/ap1-browser-bearer-flow/ap1-browser-bearer-flow.svg)
```
`alt`는 그림의 `alt`를 그대로 쓰고, 경로는 frontmatter `assets`의 `file`과 같아야 한다.
Studio 로 보낼 때만 `:::evidence` 로 바꾼다. 손으로 고치지 않는다.
```bash
python3 scripts/studio-body.py <기록.md> -o /tmp/x.md # check_body 는 이 파일에 돌린다
python3 scripts/studio-body.py <기록.md> --body-only # Studio 에 붙여넣을 본문
python3 scripts/studio-body.py <기록.md> --key a=a-1a2b3c4d # 서버가 준 키로
```
Studio 파서는 상대 경로 이미지를 `unsafe image URL`로 거절하므로 `check_body.mjs`는 **바꾼
파일**에 돌린다. 저장소 파일에 그대로 돌리면 그림 자리에서 실패한다.
## 일반 이미지
Asset이 아닌 그림은 Markdown으로 쓴다.
@@ -62,7 +62,7 @@ topicName: OAuth/OIDC 인증 경계
```yaml
assets:
- key: eager-lazy-query-sequence # 본문의 :::evidence key 와 같은 값
file: ../../../final/assets/tech-log-studio/eager-lazy-query-sequence.svg
file: ../../../final/assets/diagrams/eager-lazy-query-sequence/eager-lazy-query-sequence.svg
evidence:
- ../../../final/evidence/explain/highlights-child-plan-A.txt
```
@@ -90,6 +90,10 @@
- [ ] 그림이 있는 문단에 글을 섞지 않았다
- [ ] `alt`가 무엇이 보이는지 말한다
- [ ] 그림 안 `<text>`가 전부 이름이다. 문장도 숫자도 없다 (`<title>`·`<desc>`는 예외)
- [ ] 눈으로만 보지 않고 `python3 scripts/check-figure-text.py <프로젝트>` 를 돌렸다
- [ ] 관계선을 다 지워도 뜻이 남는 그림이 아니다 (남으면 표다 — 마크다운 표로 쓴다)
- [ ] `python3 scripts/preview-figure.py`로 PNG 를 떠서 눈으로 봤다 (lint 는 라벨이 상자를 덮는 것을 못 잡는다)
- [ ] 본문의 그림이 마크다운 이미지다 (`:::evidence` 는 Studio 로 보낼 때 `studio-body.py` 가 만든다)
- [ ] 코드에 자격증명·토큰·내부 호스트가 없다. 지운 자리가 보인다
- [ ] 제목 id와 표 id가 겹치지 않는다
@@ -46,6 +46,31 @@ analysis material in one file. Only the first is candidate material.
`excluded` names the parts that are evidence rather than candidates. A node may cite an
anchor from an excluded part in `source`; it may not exist because of one.
`excludedAnchorPattern` is optional and is the only field the verifier can act on. Without it
the rule above is a sentence nobody enforces — the check that a node did not come *only* from
outside the scope is switched off entirely.
```json
"candidateScope": {
"document": "final/document.md",
"sections": ["§3", "§4"],
"excluded": ["제2부 — 모듈 분석 전문"],
"excludedAnchorPattern": "#a[0-9]+$"
}
```
It is a regular expression matched against each `source` anchor. A node whose anchors *all*
match it is an error: it was promoted from evidence, not from the candidate scope.
## Anchors resolve to real sections
`source` and `sourceRefs` anchors are checked against the SSOT's own headings when the project
writes them as heading slugs (`#검토한-선택지와-막힌-지점-ap1` = the h2 slug plus a
discriminator). **Keep one anchor style per project.** A project that numbers its anchors
(`#§1.1`, `#10-2`, `#a18`) gets a warning instead — the verifier cannot tell whether the
section it names exists, and the diagram stage cannot translate the anchor into a
`techviz prepare --heading` value without a person reading it.
## Topics
Each Topic has `topic` (its key), `title`, **`readerQuestion`**, and `kinds` with the five
@@ -165,6 +165,8 @@ basisVersion: oauth2-proxy 7.15.2 · Nginx auth_request
## 본문이 있는 두 종류의 공통 규칙
- **그림이 필요한지와 무엇을 그릴지는 `choosing-a-diagram.md` 가 정한다** — 종류마다 그림이
답해야 할 물음이 다르다. Case 는 순서, Concept 은 구조나 변환 사슬이 대개 논지다
- 그림은 `technical-visualizer` 로 만든다. 손으로 SVG 를 그리지 않는다
- 그림 안에는 이름만 넣는다. 문장은 `<desc>` 와 옆 문단에 둔다
- 그림과 증거는 frontmatter 의 `assets` · `evidence` 로 잇는다. 같은 파일을 기록 옆에 복사하지 않는다