- name
- c4-archi-model
- description
- 설계 문서, 소스 코드, API 명세, 배포 설정과 런타임 자료에서 검증 가능한 근거를 추출해
C4 기반의 canonical architecture model, 다이어그램, 설명, 근거·Coverage·QA 산출물을 만들고,
마지막에는 브라우저에서 바로 열 수 있는 단일 HTML 보고서로 조립하는 에이전트 독립 스킬.
작업 시작 전에 사용자가 이미 명시하지 않았다면 반드시 "초보자용 / 전문가용" 작성 모드를 묻는다.
작성 모드와 별도로 guided / focus / full 분석 Profile을 관리하며, 같은 아키텍처 사실을
독자 수준에 맞는 서로 다른 설명 경로로 제공한다.
사용 트리거:
- 설계 문서를 C4로 그려 달라는 요청
- 시스템 구조를 Context / Container / Component / Dynamic / Deployment로 설명하는 요청
- 코드와 설계 문서를 비교해 아키텍처 문서를 만드는 요청
- C4 산출물을 HTML로 보기 쉽게 정리하는 요청
- 초보자용 또는 전문가용 소프트웨어 아키텍처 설명·검토 요청
특정 LLM, 코딩 에이전트, 운영체제 경로, 전용 메모리, 플러그인 또는 전용 도구 호출 문법에
종속되지 않는다. 사용할 수 없는 기능은 명시하고, 검증 가능한 텍스트 산출물로 낮춰서 제공한다.
# C4 Architecture Model
글로 흩어진 설계 의도와 실제 구현·배포 증거를 **근거가 추적되는 하나의 아키텍처 모델**로 바꾸고,
그 모델에서 C4 View와 독자 수준별 설명을 생성한 뒤 단일 HTML 보고서로 전달한다.
목표는 박스와 화살표를 늘리는 것이 아니다. 다음 질문에 검증 가능한 답을 주는 것이 목표다.
```text
무엇이 시스템 안과 밖에 있는가?
각 실행 단위는 무엇을 책임지는가?
누가 누구에게 어떤 목적으로 요청하거나 이벤트를 전달하는가?
중요한 흐름은 어떤 순서로 진행되는가?
이 설명은 어느 자료에서 확인되었는가?
무엇은 아직 확인하지 못했는가?
독자는 이 구조를 실제로 이해할 수 있는가?
```
---
## 1. 실행 계약
다음 규칙은 선택 사항이 아니다.
1. **독자 모드가 먼저다.** 사용자가 이미 명시하지 않았다면 분석 전에 `초보자용 / 전문가용`을 묻는다.
2. **분석 깊이는 별도 축이다.** 독자 모드와 `guided / focus / full` Profile을 혼동하지 않는다.
3. **Session이 먼저다.** 질문, 목적, 범위, 제외 범위, 종료 조건과 출력 형식을
`architecture-session.json`에 기록한다.
4. **근거가 모델보다 먼저다.** 읽은 자료를 Source Snapshot으로 고정하고 Claim을 추출한다.
5. **Canonical model이 그림보다 먼저다.** 그림과 설명은 모델의 파생 출력이다.
6. **아키텍처 사실과 표현을 분리한다.** 독자 모드, 비유, 카드 순서는 canonical model에 넣지 않는다.
7. **근거 없는 빈칸을 채우지 않는다.** 문서에 없는 Kubernetes, Cloud, 복제 수, 재시도,
멱등성, 보안 통제, 팀 소유권을 현재 시스템의 사실로 만들지 않는다.
8. **추상화 수준을 섞지 않는다.** System, Container, Component, Code, Deployment Node를
한 View에 무분별하게 섞지 않는다.
9. **Coverage를 숨기지 않는다.** 확인한 영역, 관련 미확인, 범위 밖 미확인과 다음 확인 지점을 기록한다.
10. **검증 규칙은 실제로 실행한다.** 체크리스트만 작성하고 `PASS`라고 부르지 않는다.
11. **사람이 여는 최종 진입점은 HTML이다.** 파일 작성이 가능하면 오프라인 단일 `index.html`을 만든다.
12. **오류가 있으면 strict build를 중단한다.** 잘못된 모델을 예쁜 HTML로 포장하지 않는다.
13. **실제 사용자 테스트와 simulation을 구분한다.** persona simulation을 사람 검토라고 표현하지 않는다.
14. **렌더링 실패를 숨기지 않는다.** source diagram만 만들었으면 그림을 완성했다고 말하지 않는다.
15. **특정 에이전트에 종속되지 않는다.** 일반적인 읽기·검색·파일 작성·렌더링·검증 능력만 전제로 한다.
---
## 2. Step 0 — 작성 모드와 분석 Profile 결정
### 2.1 필수 작성 모드 질문
같은 요청 안에 `초보자용`, `전문가용`, `둘 다`가 없다면 다른 본문 분석보다 먼저 다음을 묻는다.
```text
작성 모드를 선택해 주세요.
1. 초보자용 — 용어 풀이, 일상 비유, 단계별 흐름 중심
2. 전문가용 — 경계, 책임, 계약, 품질 속성, 트레이드오프와 위험 중심
```
규칙:
- 이미 모드를 명시했다면 다시 묻지 않는다.
- 사용자의 직업이나 문서 난이도를 보고 모드를 추측하지 않는다.
- `둘 다`면 canonical model과 다이어그램은 하나만 만들고 설명만 두 버전으로 만든다.
- 모드가 확정되기 전에는 파일 목록·경로 확인처럼 가역적인 준비만 한다.
### 2.2 분석 Profile
작성 모드는 **설명 방식**, Profile은 **조사 범위와 종료 조건**이다.
| Profile | 목적 | 기본 산출물 |
|---|---|---|
| `guided` | 전체 구조를 빠르게 이해 | Context, Container, 핵심 Dynamic 1개, 관련 미확인 |
| `focus` | 특정 Container·흐름·배포 환경 집중 | 선택 영역의 Component/Dynamic/Deployment와 근거 |
| `full` | 확인 가능한 전체 범위 조사 | Landscape, 주요 Context·Container·Component·Dynamic·Deployment, 전체 QA |
선택 규칙:
- 사용자가 `전체`, `전부`, `full`을 명시하면 `full`.
- 특정 Container·도메인·흐름만 지정하면 `focus`.
- 별도 지시가 없으면 `guided`.
- 모드를 묻는 상황에서는 Profile도 함께 보여 줄 수 있지만, Profile 미선택만으로 작업을 멈추지 않는다.
- `focus`는 target ID 또는 사람이 이해할 수 있는 명시적 대상이 필요하다.
자세한 기준은 `references/analysis-profiles.md`를 따른다.
---
## 3. 데이터 계약과 진실의 원본
각 파일은 서로 다른 책임을 가진다. 같은 사실을 여러 파일에서 제멋대로 다시 정의하지 않는다.
| 파일 | 책임 | 포함하지 않는 것 |
|---|---|---|
| `architecture-session.json` | 질문, 독자 모드, Profile, 범위, 종료 조건 | 아키텍처 요소·관계 |
| `evidence-ledger.json` | Source Snapshot, Claim, locator, 충돌, confidence | C4 View 레이아웃 |
| `architecture-model.json` | 요소, 관계, View, Dynamic step | 비유, 독자용 문장, Source Register 복제 |
| `coverage.json` | 확인 범위, 미확인, 다음 확인, 완료 판정 | 근거 없는 해결책 |
| `human-understanding.json` | 독자 이해도 Gate 결과 | 실제로 하지 않은 사용자 테스트 |
| `html/report-data.json` | canonical ID에 연결된 표현·탐색 데이터 | 이름·유형·기술·책임 재정의 |
| `manifest.json` | 출력 파일 목록, 역할, SHA-256, 크기 | 아키텍처 주장 |
### Derivation과 Confidence
두 축을 분리한다.
```text
Derivation: explicit / normalized / inferred / unresolved
Confidence: VERIFIED / PARTIAL / DOC_ONLY / UNVERIFIED / CONFLICT
```
예:
```text
설계 문서에 직접 명시됐지만 코드·배포 검증은 없음
→ explicit + DOC_ONLY
코드와 IaC에서 같은 실행 경계를 확인함
→ normalized + VERIFIED
두 자료가 서로 다른 DB 또는 프로토콜을 주장함
→ explicit + CONFLICT
```
확률 숫자는 산정 방법이 없으면 사용하지 않는다.
---
## 4. 전체 워크플로
### Step 1 — Architecture Session 작성
`assets/architecture-session.template.json`을 기반으로 다음을 기록한다.
```text
질문과 목적
작성 모드
분석 Profile
대상 ID 또는 대상 설명
기대 결과
포함 범위와 제외 범위
종료 조건
위험 Trigger
Source Snapshot ID
출력 폴더와 요청 형식
```
입력이 부족해도 아키텍처 사실을 추측하지 않는다. 현재 목적에 영향을 주는 누락은 Coverage에 남긴다.
### Step 2 — 자료 목록과 Source Snapshot 고정
지원 입력:
- Markdown, 텍스트, HTML, PDF, DOCX, Wiki export
- 소스 저장소 또는 일부 디렉터리
- OpenAPI, AsyncAPI, GraphQL schema
- Docker Compose, Kubernetes, Terraform, CloudFormation
- DDL, migration, ERD 설명
- 런북, 로그, trace, 장애 보고서
- 기존 C4, PlantUML, Mermaid, Structurizr, 이미지 다이어그램
각 Source에는 가능한 범위에서 다음을 기록한다.
```text
source ID
자료 이름·위치·종류
버전·날짜·commit SHA 또는 content hash
실제로 읽은 파일·섹션·줄·페이지
확인 가능한 내용
확인할 수 없는 내용
capture 시각
```
변경 가능한 원격 자료나 코드에는 immutable commit 또는 content hash를 우선 사용한다.
`main 브랜치`나 URL만 기록하고 재현 가능하다고 주장하지 않는다.
자세한 규칙은 `references/source-snapshot.md`를 따른다.
기존 Mermaid 다이어그램(`.mmd`)은 `scripts/convert_mermaid_input.py`로 원장 조각으로
변환한다 — 텍스트 파싱만(렌더러 비실행), 결과는 VERIFIED가 될 수 없는
"출처가 그림인 주장"이다. 계약과 지연 범위(draw.io·Excalidraw 미지원)는
`references/mermaid-import.md`를 따른다.
### Step 3 — Evidence Claim 추출
원문에서 바로 박스를 만들지 않는다. 먼저 다음 형태의 Claim을 만든다.
```json
{
"id": "CL-001",
"statement": "Order API는 PostgreSQL에 주문을 저장한다.",
"targetIds": ["order-api", "order-database", "api-to-db"],
"derivation": "explicit",
"confidence": "DOC_ONLY",
"supports": [
{
"sourceId": "S1",
"locator": "architecture.md > Persistence",
"excerpt": null
}
],
"contradictions": [],
"usedBy": [
{"kind": "relationship", "id": "api-to-db"}
],
"notes": []
}
```
- locator는 파일·제목·페이지·줄·심볼 중 실제로 확인 가능한 가장 구체적인 위치를 사용한다.
- 긴 원문을 복제하지 않는다.
- 자료 충돌은 조용히 하나로 합치지 않고 `CONFLICT`와 contradiction으로 남긴다.
- intended, implemented, deployed, observed 구조가 다르면 View 또는 설명에서 분리한다.
### Step 4 — Canonical Architecture Model 생성
`assets/architecture-model.template.json`과 `references/c4-model-guide.md`를 사용한다.
분류 기준:
```text
사람·역할 → Person
독립적인 사용자 가치를 제공하는 경계 → Software System
실행 애플리케이션·데이터 저장소 → Container
한 Container 내부의 책임 묶음 → Component
클래스·함수·인터페이스·테이블 → Code Element
실행 위치·서버·VM·Cluster·Pod → Deployment Node
DNS·방화벽·Load Balancer 등 → Infrastructure Node
```
부모 규칙:
```text
Container.parentId → Software System
Component.parentId → Container
Code Element.parentId → Component
Deployment Node.parentId → Deployment Node 또는 null
```
모호한 `service`, `API`, `server`, `engine`, `module`, `platform`, `database`는
이름만 보고 확정하지 않는다. 실행 경계, 저장 책임, 독립 배포, 소유 범위와 상위 경계를 확인한다.
모든 요소와 관계는 최소 한 개의 Claim ID를 가진다. 관계는 다음처럼 작성한다.
```text
나쁨: Web App → API : Uses
좋음: Web App → Order API : 주문 생성 요청을 전송한다 [HTTPS/JSON]
```
### Step 5 — 필요한 C4 View 선택
모든 View를 의무적으로 만들지 않는다. Session 질문에 답하는 View만 만든다.
| 질문 | View |
|---|---|
| 누가 시스템을 쓰고 어떤 외부 시스템과 연결되는가 | System Context |
| 조직 전체 시스템 지도가 필요한가 | System Landscape |
| 시스템 안 실행 단위와 저장소는 무엇인가 | Container |
| 특정 Container 내부 책임은 어떻게 나뉘는가 | Component |
| 요청·이벤트가 어떤 순서로 흐르는가 | Dynamic |
| 실제 환경 어디에서 실행되는가 | Deployment |
| 중요한 구현 세부가 필요한가 | Code, 요청 시만 |
각 View에는 다음을 기록한다.
```text
이 View가 답하는 질문
범위
포함 요소와 관계
의도적으로 보여주지 않는 것
다음 확대 View
근거 Claim
```
Dynamic View의 step ID와 order는 canonical model에 두며, order는 `1..N` 연속이어야 한다.
여러 시나리오는 `flows[]`로 각각 표현한다.
### Step 6 — Coverage 기록
`coverage.json`에 다음을 분리한다.
```text
explored 확인한 영역
unknownRelevant 현재 질문과 관련된 미확인
unknownOutOfScope 현재 범위 밖의 미확인
expansionPoints 다음 확대 후보
boundaries 자료·시간·도구·범위 경계
```
완료 결과:
- `PASS`: 현재 질문과 종료 조건을 충족했고 blocker가 없음.
- `PASS_BOUNDED`: 현재 질문은 답했지만 명시적인 경계가 남음. blocker는 없어야 함.
- `REQUEST_CHANGES`: 핵심 질문 또는 변경 판단을 막는 미확인이 남음.
- `NOT_RUN`: Coverage 검사를 수행하지 않음.
`PASS_BOUNDED`를 전체 아키텍처 검증 완료라고 표현하지 않는다.
### Step 7 — 독자 수준별 설명 작성
자세한 규칙은 `references/writing-modes.md`를 따른다.
#### 초보자용
- 시스템이 해결하는 문제부터 설명한다.
- Context → Container → 핵심 흐름 → 필요한 Component 순으로 확대한다.
- 전문 용어 첫 등장 시 영어 원문, 한국어 뜻, 구체적 예 또는 비유를 함께 준다.
- 비유를 쓸 때는 비유 개념이 실제 구성요소·관계 중 무엇에 대응하는지 밝히고,
비유가 맞지 않는 범위를 숨기지 않는다.
- 각 요소를 `무엇인지 / 왜 필요한지 / 누구와 대화하는지 / 없거나 실패하면 어떤 영향인지`로 설명한다.
- 실제 요청 하나를 번호 순서로 따라간다.
- 쉬운 설명을 위해 사실을 삭제하거나 바꾸지 않는다.
- 설명 구조는 장면 프레임형 독자 경험(한눈 요약, 독자 계약, 장면 목차·점프, 근거 인용 병렬,
증거 체인 종합, 상황별 시나리오)을 기본으로 제안한다.
최소 계약은 `references/scene-frame-reporting.md`를 따른다.
#### 전문가용
- 경계, ownership, 책임, public/consumed interface, 상태 소유권을 설명한다.
- 동기·비동기, 계약, 실패 전파, transaction boundary, security/trust boundary,
scaling unit, observability, deployment evidence를 자료 범위 안에서 분석한다.
- 장점만 쓰지 않고 전제, 비용, 결합도와 risk를 함께 적는다.
- 근거 없는 timeout, retry, idempotency, consistency 보장을 채우지 않는다.
### Step 8 — 다이어그램 Source와 렌더링
`references/renderer-adapters.md`, `references/archify-adapter.md`, `references/repo-flowmap-adapter.md`를 따른다.
우선순위:
1. 사용자가 지정한 형식
2. archify (기본 경로 — Node 18+와 archify 패키지가 가용하면 다이어그램 저작·렌더링에 archify를 쓴다)
3. repo-flowmap (번들 폴백 기본 — `assets/repo-flowmap/`으로 스킬에 포함되어 별도 설치가 필요 없다. Node 18+만 있으면 archify 미가용 시 이 경로를 쓴다)
4. C4-aware model-as-code (Structurizr DSL)
5. 현재 환경에서 검증 가능한 diagrams-as-code (Mermaid/PlantUML/D2)
6. 렌더러가 없으면 source diagram + 텍스트 미리보기
archify 경로에서는:
- canonical model에서 각 View별 archify JSON IR을 저작한다. IR은 canonical source가
아닌 파생 View source다.
- `validate` 영수증을 `qa/`에 저장하고, `deliver`로 View별 인터랙티브 HTML 아티팩트를
확정한다. deliver exit code가 0이 아니면 완료로 보고하지 않는다.
- 보고서 임베딩용 정적 SVG는 `scripts/extract_archify_svg.py`로 산출물에서 추출한다.
- Node나 archify가 없으면 이유를 밝히고 사용자에게 archify 설치를 제안한다. 동의를 받으면
사용 중인 에이전트의 skills 디렉터리(예: `~/.pi/agent/skills/archify`)에 archify 스킬 루트를
설치하고 `doctor`로 재판정한 뒤 기본 경로를 쓴다. 동의가 없거나 설치할 수 없으면
번들 폴백 경로(3)로 내려간다. Node 자체가 없을 때만 Structurizr 체인(4~6)으로 내려간다.
- 즉석에서 만든 커스텀 SVG·이미지 렌더러로 다이어그램을 대체하지 않는다. 렌더러는 archify,
번들 repo-flowmap, 또는 폴백 체인(4~6)뿐이다. 수제 레이아웃은 결정적 품질 보장이 없다.
이 위반은 Validation failure다 (2026-09-14 papercompany 산출물이 사례).
- 기존 PlantUML/Mermaid 원본이 입력에 있어도 archify IR로 통역하지 않고
canonical model에서 새로 저작한다.
repo-flowmap 경로에서는:
- `references/repo-flowmap-adapter.md`를 따른다. 스킬에 번들된 repo-flowmap
(`assets/repo-flowmap/`)을 쓰므로 별도 설치 없이 Node 18+만으로 동작한다.
- canonical model의 정확한 View를 `scripts/build_repo_flowmap.py --model ... --view ...`로 매핑한다.
어댑터는 데이터 매핑만 하고, 같은 repo-flowmap template 내부가 structure/class/sequence/deployment를 그린다.
기존 legacy View별 flowmap.json도 `scripts/build_repo_flowmap.py`로
번들 검증기·빌더를 실행해 HTML과 qa/ 영수증을 함께 만든다. 명령·경로 규칙은 어댑터 §3을 따른다.
입력/출력 SHA-256(파일 변경 확인값)은 해당 실행 중 기록하며, 기존 산출물의 사후 해시 보충은 금지한다.
- 보고서 임베딩은 mimeType `text/html` 다이어그램(assetPath 지정)으로 하며, 기본 템플릿이
iframe(sandbox allow-scripts allow-downloads — SVG 다운로드 단추 허용)으로 렌더링한다. 번들 래퍼는 인쇄 SVG를 만들지 않는다.
`scripts/export_repo_flowmap_svg.py`의 실제 native export 실행과 `repo-flowmap-svg-<view>.json` 영수증이 없으면 printAssetPath를 생략하고
인쇄 시 그림 누락 한계를 밝힌다. 수동 다운로드 파일만으로 인쇄 자산을 등록하지 않는다.
- 번들은 명시적 유지보수 포크다. `assets/repo-flowmap/VENDORED.md`의 출처/라이선스/변경 정책을 따른다.
개별 그림 생성 중 template을 임의 수정하지 않는다. 정식 포크 변경은 테스트·manifest와 함께 갱신한다.
- 기존 PlantUML/Mermaid 원본이 입력에 있어도 archify IR로 통역하지 않고
canonical model에서 새로 저작한다.
필수 보존:
- canonical JSON
- View source diagram (archify IR 또는 어댑터별 source)
- 사람이 읽는 설명
- 렌더링 성공 여부 (archify `validate`/`deliver` 또는 repo-flowmap `validate`/`build` 영수증 포함)
SVG를 HTML에 넣기 전 script, `foreignObject`, 외부 URL과 위험한 참조를 검사한다.
archify 산출물에서 추출한 SVG도 같은 검사를 통과해야 한다.
### Step 9 — Human Understanding Gate
`references/human-understanding-gates.md`를 따른다.
초보자용 기본 질문:
```text
B-01 누가 시스템을 사용하는가?
B-02 시스템은 어떤 문제를 해결하는가?
B-03 주요 실행 단위는 무엇인가?
B-04 핵심 요청은 어디서 시작해 어디서 끝나는가?
B-05 아직 확인되지 않은 것은 무엇인가?
```
전문가용 기본 질문:
```text
E-01 시스템·팀 소유 경계는 어디인가?
E-02 각 Container는 어떤 상태와 책임을 소유하는가?
E-03 동기·비동기 및 계약 경계는 어디인가?
E-04 실패 전파·격리·복구 근거는 무엇인가?
E-05 보안·신뢰·배포·관측성 근거는 무엇인가?
E-06 주요 trade-off와 다음 결정은 무엇인가?
```
실제 사람에게 검토받지 못하면 `persona-simulation`으로 표시한다.
수행하지 못하면 `NOT_RUN`으로 남긴다. 그럴듯한 답을 만들어 `PASS`로 바꾸지 않는다.
### Step 10 — HTML 표시 데이터 작성
`assets/html-report-data.template.json`을 사용한다.
`html/report-data.json`은 다음만 가진다.
```text
canonical model/view/step ID 참조
읽기 순서와 설명 카드
비유와 why-it-matters
View asset 경로
Claim·Coverage issue 연결
원본 파일 목록
```
다음 canonical 사실을 복제하지 않는다.
```text
name
type
technology
description
relationship endpoint
```
HTML 빌더가 canonical model에서 위 사실을 읽어 화면에 채운다.
이 구조가 이름만 같은 가짜 `Payment API`를 슬쩍 끼워 넣는 사소하고도 인간적인 재앙을 막는다.
비유 대응(mappings)은 canonical 모델 ID로만 쓴다.
- `analogy` 옆의 선택 필드 `mappings`는 `{ term, modelId, kind, note? }` 항목으로
비유 개념을 실제 구성요소·관계와 잇는다. `modelId`는 등록된 canonical ID여야 하고
`kind`(element·relationship)도 실제 대상과 일치해야 한다(HTML-DATA-023).
- `limits`에 비유가 맞지 않는 범위를 한국어 문장으로 적는다. 없어도 되지만
비유의 한계를 감추지 않는다.
- 화면에 찍히는 이름은 빌더가 canonical model에서 채운다. 비유가 모델 사실을
재정의하지 않는다.
- mappings가 없으면 기존과 동일하게 렌더링된다(선택 필드 — 기존 데이터 무변경).
### 변경 전후 비교(선택)
현재 문서의 변경 영향 분석을 실제 비교 화면으로 확장할 때만 사용한다. 기존 구성요소
책임 비교(같은 보고서 안 요소별 역할 비교)와 별개의, 두 모델 시점 간 변경 비교다.
1. **두 시점 모델 구하기**: 이전 리비전의 canonical model을 보존한다(예: 이전 패키지
아카이브, git 이력에서의 스냅샷 복원). 현 패키지에
`<system>.architecture-model.previous.json` 같은 이름으로 함께 보존할 수 있다.
이전 시점 모델도 같은 canonical 계약(스키마·시맨틱)을 통과해야 비교할 수 있다.
근거 주장 연결(MOD-006/011)은 경고로만 남는다 — 과거 스냅샷의 원래 근거장은
비교 입력에 없고 비교 필드에 claimIds가 없기 때문이다.
2. **비교 실행**:
```bash
python3 <skill>/scripts/compare_architecture_models.py \
--before <output-root>/model/architecture-model.previous.json \
--after <output-root>/model/architecture-model.json \
--output <output-root>/qa/architecture-comparison.json
```
비교는 canonical ID 기준이며 요소 추가·삭제·이동(parentId 변경)·속성 변경(이름
등 표시에 영향 주는 필드), 관계 추가·삭제·방향 변경(출발·도착 교체·재연결)을
분류한다. 원본 모델은 수정하지 않고 결과는 별도 산출물로 남는다.
3. **보고서 연결**: `html/report-data.json`의 `build.comparisonPath`에 비교 결과
경로를 적는다(선택 필드 — 없으면 보고서에 비교 섹션이 나타나지 않고 기존 데이터는
무변경). 빌더가 비교 산출물을 '변경 전후 아키텍처 비교' 섹션으로 표시한다.
4. **미확정 대응의 의미**: 같은 ID가 서로 다른 대상을 가리킬 가능성이 큰 변화(같은
ID의 type 불일치, 관계의 출발·도착이 모두 교체)는 미확정으로 표시되고 이동·변경으로
단정하지 않는다. 미확정 행은 사유와 함께 표에 남는다.
5. **그림 밖 변경**: 표가 완전한 목록이고 그림은 보조다 — 어느 뷰에도 속하지 않은
변경도 표에서 사라지지 않는다. 상태는 색과 기호, 한글 라벨을 함께 사용한다.
### Step 11 — Strict validation 실행
HTML 생성 전에 다음 순서로 검사한다.
```text
Session Schema·scope
→ Canonical Schema·C4 semantic
→ Evidence Schema·snapshot·claim
→ Coverage Schema·completion
→ Human Understanding Gate
→ HTML Report Data Schema·canonical reference
→ SVG와 asset
```
권장 명령:
```bash
python3 <skill>/scripts/validate_all.py \
--root <output-root> \
--data html/report-data.json \
--output-json qa/content-validation.json
```
오류가 하나라도 있으면 strict build를 중단한다.
`--lenient`는 진단용 FAIL HTML에만 사용하며 최종 납품으로 취급하지 않는다.
### Step 12 — 단일 HTML 보고서 생성
```bash
View on GitHub