사용자가 쓴 글을 컴포넌트로 바꿀 때 구조가 뭉개지는 것이 지금 품질 문제의 핵심이다.
Summary 를 Markdown 에서 구조화 형식으로 바꿔 슬롯을 보존하고, 컴포넌트 쪽에는 의미 태그를 붙여 대조한다.
2026-08-04 MORDOR 체크인 덱을 정리하고, 3주 뒤 SSoT 와 대조해 무엇이 바뀌었는지까지 붙였다.
2026-08-29 통합본(visual-summary-overview.pdf, 96쪽)으로 규약 개정 셋 · 강등의 나머지 절반 · PoC 구현물 로직을 반영했고,
2026-09-08 에 구현 폴더와 규약 폴더를 직접 읽어 여섯 구간의 관계(§11) ·
I.I.S. 와 대치의 연결(§12) · RLSC 가 만나는 자리(§13)를 더했다.
components[], type 은 대분류.중분류 문자열 하나, 생성은 LLM 이 YAML 을 직접 쓴다.entity.components[] 로 간다.type 이 필수가 되고 대분류 단독이 막혔다(0.5.1·0.5.2). 현행은 0.5.6 — 생성기 어휘가 45종에서 36종으로 좁혀졌다. §6
원본 덱도 파생물이고 이 페이지는 그 파생물의 파생물이다.
SSoT 는 mordor-wiki / projects/mordor/visual-summary/ 이고,
규약은 spec/schema-v0.5.md, 할 일은 TODO.md 가 갖는다.
숫자나 결정이 여기와 다르면 그쪽이 맞다.
Gauge·RadarChart 가 P0 인데 생성 불허다. 붉은 9종 중 나머지 7종은 단어장도 P1·P2 라 우선순위와 부딪히지 않는다.이것을 먼저 잡아야 나머지가 읽힌다. 불허는 생성기 한 층에서만 거른다 — 검색과 I.I.S. 태깅은 45종 전량을 그대로 쓴다.
단어장 v2 P0 가 사는 곳
45종 전량 어휘 유지 — Gauge·RadarChart 도 P0 그대로 유효하다.
손그림 게이지·레이더도 Gauge·RadarChart 로 태깅하는 것이 맞다.
노란 5종도 그대로다 — native 여부는 코드가 읽는 사실이지 태깅 기준이 아니다.
결론 — 단어장 P0 20종은 이 층에서 하나도 빠지지 않는다.
단어장(7/30)에는 generatable 열이 없어 이 구분이 아예 안 보인다.
B-36 불허가 걸리는 곳
P0 20종 중 생성기가 고를 수 있는 것은 18종이다. 빠진 둘은 이렇게 간다.
Gauge → BigNumber (P1 · fallback[0])
RadarChart → ComparisonTable (P0 · generatorRedirect 예외)
P0 요청이 Gauge 면 도착지가 P1 카테고리다 — 우선순위 역전 1건.
스마트 다이어그램 대응이 되면 재검토 없이 어휘로 복귀한다.
색은 생성 가능 여부, 행은 단어장 v2 우선순위다. 두 축은 서로를 참조하지 않으므로 교차해야 실제 범위가 나온다.
| 등급 | 허용 · Native 불필요 30종 · 어느 층에서도 안 거른다 |
주의 · 엔진 있음 6종 · 생성 허용, native Chart 풀 필요 |
불허 9종 · generatable:false |
45종 밖 4종 |
|---|---|---|---|---|
| P0 20종 |
13 — List ListingTable ComparisonTable Versus SWOT Transformation Steps Staircase Cycle Timeline HighlightedMessage LongFormTextLayout TableOfContents텍스트·위상 치환으로 대치되는 P0 본대. 충돌 여지가 없다 |
5 — BarChart PieChart DonutChart LineAreaChart ComboChart생성기는 허용. 단 손그림 후보에 새 값을 넣으면 정보가 틀린다 |
2 — Gauge RadarChart실제 충돌. 아래 ③ |
0 |
| P1 13종 |
12 — CombinedResult ProblemSolution BigNumber VennDiagram Pyramid NestedScope SectionDivider Ending QnACard Opening ProfileCard ResumeCVVennDiagram·Pyramid 는 단어장이 스마트기능 필요로 봤지만, B-36 은 원 2~3개·층이 적어 손그림도 신뢰 가능하다고 「둘 다 가능」으로 뒀다 |
0 | 1 — HierarchicalTree「지금 없음」 — 엔진은 있고 연결 코드(B-13)만 대기. 어댑터가 나오면 복귀한다. P1 이라 우선순위와 안 부딪힌다 |
0 |
| P2 16종 |
5 — DialogueChat QuoteTestimonial Funnel FlowChart Fishbone뒤 셋은 단어장이 스마트기능 필요로 봤으나 B-36 이 「둘 다 가능」으로 내렸다( Funnel 은 2026-09-04 정원석 재검토). 생성은 허용, 단어장 순위는 P2 그대로 |
1 — StackedBarChart노란 6종 중 유일한 비-P0. 엔진이 있어( isStacked) 규약 쪽 제약은 없고 순위만 낮다 |
6 — Quadrant GanttChart Calendar TreeMap PictogramChart BubbleChart「영구 없음」 — 원본 노드도 vizType 도 없다. 단어장이 이미 뒤로 미뤄 둔 것이라 B-36 불허와 정합한다 |
4 — Geo 4종Distribution Location Highlight Flow. 단어장에만 있고 capability 45종 밖이다 |
| 겹침 요약 | 내역 |
|---|---|
| 노란 6종 | P0 5 + P2 1 (StackedBarChart) |
| 붉은 9종 | P0 2 + P1 1 + P2 6 |
| 실제 충돌 | 붉은 ∩ P0 = 2종. 둘 다 2026-09-11 「공급 0」 신설 판정분이다 |
| 엔진 없음 7종 | 단어장도 P1·P2 — L4·스마트기능 필요 표기와 정합한다 |
단어장은 「쉽다」고 봤고, 규약은 「공급이 없다」로 막았다. 둘 다 스마트기능 불필요로 표기돼 있어서 예측하지 못한 불허다 — 나머지 7종처럼 「L4·스마트기능 필요」로 미리 걸러진 것이 아니다.
| 종 | 단어장 | 우선순위 이력 | 규약이 막은 이유와 도착지 |
|---|---|---|---|
Gauge | L2 (쉬움) | v1 P0 → v2 P0 유지 | 엔진 remap 은 있으나 운영 I.I.S. native Chart 풀이 0. 생성기가 고르면 대치 불능 질의가 된다. → BigNumber(P1) — 우선순위 역전 |
RadarChart | L1 (가장 쉬움) | v1 P2 → v2 P0 승격 | 같은 이유. → ComparisonTable(P0) — generatorRedirect 로 따로 적은 유일한 예외다. BarChart 로 내리면 축이 붕괴한다 |
RadarChart 의 P2 → P0 승격이 충돌을 하나에서 둘로 늘린 원인이다. 승격 전이었다면 Gauge 하나만 걸렸다.
생성기는 허용하고 엔진도 있다. 문제는 손그림 후보에 새 값을 넣으면 정보가 틀린다는 것이다. 막대 길이·각도가 값과 무관한 그림에 숫자만 갈아 끼우면 보이는 것과 뜻이 어긋난다.
그래서 native Chart 공급 확보가 P0 달성 조건이다. 노란 6종 중 5종이 P0(BarChart·PieChart·DonutChart·LineAreaChart·ComboChart)이므로, 공급이 안 붙으면 P0 범위를 선언해도 실질이 안 채워진다. 불허 2종과 달리 이쪽은 규약이 막은 것이 아니라 데이터가 비어 있는 것이다.
규약 폴더의 semantic-taxonomy-v7.md 는 2026-08-25 스냅샷(v1) 이라 P0=19 · P1=13 · P2=7 · P3=3 · P4=7 로 적혀 있다. 위 표의 v2 는 그 문서에 아직 반영되지 않았다 — 이 절은 공유된 그림을 기준으로 적었고, 저장소 값과 대조해 차이 셋을 확인했다.
| 종 | v1 | v2 | 무엇이 달라지나 |
|---|---|---|---|
RadarChart | P2 | P0 | 승격. 충돌 종수가 1 → 2 가 된 직접 원인 |
TableOfContents | P1 | P0 | 승격. 색 없음(허용)이라 범위에 그대로 들어온다 |
StackedBarChart | P0 | P2 | 강등. 노란 6종 중 유일한 비-P0 가 된 이유다 |
v2 등급 체계는 P0·P1·P2 셋뿐이고 합이 49종(45 + Geo 4)이다. v1 의 P2~P4 가 v2 P2 로 합쳐진 모양이지만, 그 합침 규칙 자체는 확인하지 않았다 — 그림이 제시한 것은 최종 배치다.
Gauge·RadarChart 를 P0 범위에서 빼는지를 명시해야 한다. 안 적으면 다음 사람이 P0 20종 전부로 읽는다. 허재영님 완료처리 예정.semantic-taxonomy-v7.md 3절이 아직 v1 이다. 반영 전까지는 저장소만 읽는 사람과 이 그림을 본 사람의 숫자가 갈린다.Gauge 의 우선순위 역전. P0 요청이 P1 카테고리로 떨어지는 유일한 자리다. 허용할지, 다른 도착지를 줄지 정한다.출처 범위 확정과 위 4색 × 3등급 배치는 사용자가 공유한 구현 범위 그림(2026-09-18)과 Slack 대화(miridih.slack.com · C091C6JFYH0)다. Slack 링크를 따로 조회하지 않고 공유된 본문과 그림만 사용했다.
generatable 9종·generatorRedirect·불허 사유는 mordor-wiki bbabab9(2026-09-16)의 spec/schema/capability.json 과 spec/capability-table.md 10.1절에서 직접 확인했고 그림과 일치한다.
v1↔v2 우선순위 차이 셋은 그림과 저장소 semantic-taxonomy-v7.md 3절을 대조해 이 문서에서 계산한 것이다.
「사용자 입력이 RLSC 로 변환된다」는 사실이 아니다. 경로가 둘이고 서로 별개로 진행된다. 이 그림을 잘못 들고 있으면 뒤의 결정이 전부 이상하게 들린다.
structure 에서 RLSC 로 가는 화살표는 변환이 아니라 capability 대조다.
그 규약이 spec/capability-table.md 다.
2026-07-26 BAD 원인 분석. judge 채점 16,819행 집계 + BAD 200건 직접 분류.
→ 85% 가 컴포넌트와 내용이 안 맞는 문제
검색이 컴포넌트를 잘 골라도 그 다음이 정의돼 있지 않아 결과가 나빠지고 있다.
2026-08-03 방향 1.5개월 이내에 구조 불일치를 해결한다. 체감 BAD 50% → 20% 이하가 기대치다.
같은 입력인데 결과가 둘이다. 차이는 슬롯이 남느냐 하나다.
단계마다 Summary 형식 · 검색 방식 · 태그 범위 셋이 동시에 바뀐다. 아래는 덱 시점(2026-08-04)의 계획이고, 실제로 어떻게 됐는지는 §15 에 있다.
| 단계 | Summary | 검색 | 태그 범위 | 태그가 가리키는 것 |
|---|---|---|---|---|
| 1 현행 | Markdown | 임베딩 유사도 | 안 단다 | — |
| 2 목표 8-18 | Markdown | semantic tag | 컴포넌트 하나 | 이 컴포넌트 어딘가에 그 타입이 있다 |
| 3 | YAML | tag + structure | 컴포넌트 하나 | 2단계와 같음 |
| 4 | YAML | tag + node 태그 | 컴포넌트 안 node 마다 | 어느 node 인지 특정된다 |
| 5 미정 | YAML | 4단계와 같음 | node 마다 | 4단계 + 카테고리별 property |
3단계에서 만들 대치 로직이 4단계에서 버려질 수 있다. 정보가 확실한 4단계로 바로 간다 7/24 회의
2026-08-03 에 제품 배포가 연기됐다. 2단계 마감 8/18 이 그 연기에 포함되는지 티켓 반영이 없다.
설계를 정한 것은 취향이 아니라 이 분포다. 색인에 있는 것은 거의 List 하나인데, 사용자가 원하는 것은 흩어져 있다.
이 분포가 설계를 정했다. VennDiagram · Tree · NestedScope · Pyramid 는 각 164건 이하, 데이터 차트는 각 51건 이하다. 성립 조건을 엄격하게 걸면 후보가 0이 되어 전부 List 로 강등된다. 그래서 §7 의 capability 는 성립 조건을 최소로 줄이는 방향으로 설계됐다.
| 항목 | 결정 |
|---|---|
| 최상위 형태 | 항상 components[]. 하나면 길이 1 배열 |
| type | 문자열 하나로 대분류.중분류. 덱 시점 v7 단어장 49종 중 41종 — 지금은 결합값 45종이고 대분류 단독은 막혔다(0.5.2·0.5.3). 생성기가 고를 수 있는 것은 그중 36종(0.5.6, 아래) |
| confidence | 제거. 생성기가 채우지 않는다 |
| alternatives[] | 신설. fallback 순서보다 먼저 본다 |
| entity.id | 생성물에서 뺐다. 파싱 뒤 배열 순서로 매긴다 |
| dataset | measure 와 matrix 두 모양. 표 계열도 matrix |
| relation.type | intersects 와 compares 둘 |
| 생성 방식 | LLM 이 YAML 을 직접 쓴다. JSON 변환 후 스키마 검증 |
| 원소 수 상한 | 두지 않는다. 원소 간 관계는 자리만 예약 |
검증 실측 스키마 Draft 2020-12 유효성 통과 · 본문 예시 18종 전량 통과 · 부정 사례 12종 의도대로 거부
위 표는 덱이 아홉 줄로 줄인 것이다. 규약 원문 0절이 적어 둔 변경은 열두 건이다.
| # | v0.4 | v0.5 |
|---|---|---|
| 1 | LLM 이 JSON 을 생성하고 YAML 로 직렬화 | LLM 이 YAML 을 직접 생성한다. 이유는 추론 속도다 |
| 2 | 최상위가 structure(단일) 또는 components[](다중) | 항상 components[] 배열이다. 하나면 길이 1이다 |
| 3 | component.type enum 11종 | type 문자열 하나, 대분류.중분류 결합값 45종. 종전에는 대분류 21값을 더해 62값이었으나 2026-08-29 에 뺐다 (6절 상자). v7 단어장 49종에서 지도 전용 4종을 뺀 45종이다 — 지도는 지원하지 않는다(capability-table.md 범위 절) |
| 4 | component.confidence optional | 제거했다 |
| 5 | 없음 | alternatives[] 를 열었다. 못 쓸 때 대신 쓸 카테고리를 선호 순서로 적는다 |
| 6 | 4-1절이 traits(계층, 장식) 도입을 제안 | traits 묶음은 두지 않고 꾸밈은 decoration, 계층은 entity.components[] 로 나눠 갔다. 2026-08-04 에 2절에 반영했다 |
| 7 | dataset.type 3종(gauge, stacked_bar, combo) | dataset.shape 2종(measure, matrix) |
| 8 | relation.type 1종(intersects) | 2종(intersects, compares) |
| 9 | entity.id 필수 | 생성물에서 뺐다. 파싱 뒤 기계가 매긴다 (3.2절) |
| 10 | 없음 | page 수준 relations 를 예약했다. Summary 생성기는 채우지 않는다 |
| 11 | 3절에 capability 테이블 11행 | 별도 문서 41행으로 분리했다 |
| 12 | 11절에 열린 결정 15건 | TODO.md B절이 SSoT 다 |
↻ v0.4 → v0.5 변경 12건 · schema-v0.5.md — 원본에서 자동 동기화
type — 단어장 49종에서 왜 8종이 빠졌나version: "0.5" title: 효과적인 회의를 위한 3가지 원칙 components: - type: Enumeration.List structure: entities: - { label: 명확한 아젠다, items: [회의 전 안건 공유, 목표 한 문장 정의] } - { label: 시간 관리, items: [시작과 종료 시간 엄수, 항목별 타임박스] } - { label: 액션 아이템, items: [담당자 지정, 마감일 명시] }
v0.5 는 확정 뒤에도 자리에서 네 번 고쳐졌고, 그동안 판번호가 그대로였다. 그래서 「지금 규약이 무엇인가」를 버전으로 가리킬 수 없었다. 2026-08-29 에 세 건을 한꺼번에 고치면서 판번호 규칙을 함께 신설했다.
| 판 | 무엇을 고쳤나 | 왜 |
|---|---|---|
| 0.5.1 | component.type 필수화. 종전에는 optional 이었다 |
설계 원칙 첫째가 「생성 단계에서 최적 semantic category 를 정한다」인데, type 을 비우는 것은 그 판단을 검색으로 미루는 시각화 책임 회피다. 원칙 1과 optional 은 처음부터 어긋나 있었다 |
| 0.5.2 | 대분류 단독 금지. type 과 alternatives 는 결합값(대분류.중분류)만 받는다 |
같은 성격의 회피다. 대분류는 그릴 수 있는 표현형이 아니다 — Hierarchy 로는 아무것도 못 그리고 그릴 수 있는 것은 Hierarchy.Pyramid 다 |
| 0.5.3 | enum 을 결합값 45종으로 반영. 종전 62값(대분류 21 + 결합 41)에서 대분류를 뺐다 | PageNavigation 4종이 스키마와 capability.json 에 빠져 있던 격차도 같이 닫혔다 |
| 0.5.4 | ScopeCoverage.NestedScope 가 children 필수 조건을 버리고 direction(inward/outward) 속성을 신설 |
필드 하나가 빠지고 하나가 선택 속성으로 늘었을 뿐이라 기존 산출물을 무효로 만들지 않는다 (B-34) |
| 0.5.5 | 5절에 남아 있던 type “optional” 잔존 문구를 정정하고, 2.5.1 의 어휘 수 41 을 45 로 갱신 |
규범 내용 변경 없는 문구 정정이라 무효 산출물 0건 |
| 0.5.6 | 생성기 type 어휘에서 9종 제외(첫 출시) — capability.json 에 generatable·generatorRedirect 반영. 함께 생성 시점 쓰기 의무 명문화(B-33) |
enum 을 줄이지 않는다. 생성기만 부분집합을 쓰고, 쓰기 의무도 생성기 스코프 한정이라 기존 산출물이 소급 무효가 되지 않는다 |
필수가 된다고 type 이 지시가 되지는 않는다. 적을 의무만 바뀌고 따를 의무는 그대로다 —
검색은 여전히 성립 조건과 색인 공급을 보고 fallback 으로 벗어난다.
못 고르겠으면 종단 셋 중 하나를 고른다. 셋 다 개수 조건만 보므로 고를 수 없는 입력은 없다.
깨지는 산출물도 없다. 골든셋 v1 의 컴포넌트 470개가 전부 이미 type 을 갖고 있었고
(0.5.1), 결합값 검사에서도 type 454개가 전부 결합값이었다(0.5.2).
생성기 프롬프트도 결합값 45종만 준다. 실제로 지켜지던 것을 규약에 올린 개정이다.
| 자리 | 언제 올리나 | 예 |
|---|---|---|
| MAJOR | 기존 산출물이 실제로 무효가 된다 | v0.4 → v0.5 의 「최상위가 항상 components[]」 |
| MINOR | 기존 산출물은 유효하고 새로 쓸 수 있는 것이 는다 | entities + columns 대안 경로 추가 |
| PATCH | 유효성이 안 바뀐다. 실제로 지켜지던 것의 명문화 | 위 세 개정 전부 |
type 필수화는 원리적으로는 required 를 좁히는 변경이지만, 무효가 되는 산출물이 실제로 0건이라 PATCH 다.
실측 없이 좁히는 변경은 MINOR 이상으로 본다.
검증기는 MAJOR·MINOR 만 대조하고 PATCH 는 보지 않는다 — PATCH 가 유효성을 안 바꾼다고 정의해 놓고
patch 차이로 옛 산출물을 떨어뜨리면 자기모순이기 때문이다. 그래서 파일 이름(schema-v0.5.md)은 그대로다.
규약 enum 은 45종 그대로다. 줄인 것은 생성기 어휘뿐이고,
그 부분집합을 capability.json 의 generatable 이 정한다(첫 출시 기준 36종).
I.I.S. 추출·검색 인식 어휘는 45종 전량이다.
I.I.S.(색인 쪽) 는 이미 있는 컴포넌트를 알아보는 일이다. 네이티브 엔진이 없어도 「이 도형 배치가 Quadrant 처럼 생겼다」는 인식은 유효하고 검색에 필요하다 — 뺄 이유가 없다.
생성기(질의 쪽) 는 없는 것을 만들어 달라고 쓰는 일이다. 그릴 수단이 없는 카테고리를 고르면 대치가 원천적으로 불가능한 요청이 된다 — 그래서 아예 못 고르게 막는다.
판정 기준은 RLSC 태그 유무가 아니다. I.I.S. 는 RLSC 어휘와 무관하게 구조를 추론할 수 있다.
진짜 기준은 그 카테고리를 뒷받침할 엔진이 어디에든 있는가(RLSC Chart/Table 이든 Smart Diagram vizType 이든)다.
| 빠진 9종 | 왜 | 생성 재지정 |
|---|---|---|
| RelationalComparison.Quadrant | 엔진 자체가 없다 (2026-09-04 확정) 원본 노드도 Smart Diagram vizType 도 없어 지금 수단으로는 못 그린다 | — |
| TimelineSchedule.GanttChart | — | |
| TimelineSchedule.Calendar | — | |
| ProportionComposition.TreeMap | — | |
| ProportionComposition.PictogramChart | — | |
| RelationalComparison.BubbleChart | — | |
| Hierarchy.HierarchicalTree | 대치가 안 된다 | — |
| AttributeComparison.RadarChart | 첫 출시 공급 제외 (2026-09-11 추가) | ComparisonTable — 다축 보존 |
| KPIKeyMetric.Gauge | BigNumber — 3.2절과 같다 |
RadarChart 만 재지정이 따로 있는 이유
RadarChart 의 fallback 첫 후속은 BarChart 인데,
생성기가 그리로 가면 축이 붕괴한다 — 다축 프로파일이 막대 하나로 뭉개진다.
그래서 생성 재지정만 ComparisonTable 로 따로 뒀다(generatorRedirect).
Gauge 는 fallback 순서와 같은 BigNumber 라 예외가 필요 없다.
즉 fallback 순서(검색용)와 생성 재지정(쓰기용)이 갈리는 자리가 생겼고, 그 예외를 데이터로 적어 둔 것이 generatorRedirect 한 줄이다.
규약 1절의 「선언되지 않은 것은 무시한다」는 읽는 쪽 규칙이다.
이것을 쓰는 쪽까지 확대해 「어차피 무시되니 적어도 된다」로 읽으면 안 된다는 것이
2026-09-05 확정, 0.5.6 에 정본 반영됐다.
생성기는 그 카테고리가 읽는다고 선언하지 않은 내용 필드에 값을 담지 않는다.
담을 것이 있으면 그 entity 의 items 로 적는다.
projection P3(안 읽는 내용 필드를 items 뒤로 보존)은
fallback 엣지 한정 규칙이다 — 출발→도착으로 카테고리를 바꿀 때 옮길 것을 정한다.
생성기가 처음부터 그 카테고리로 쓰면 옮겨 줄 주체가 없어 내용이 그대로 소멸한다.
실측이 있다 — HierarchicalTree 를 Pyramid 로 재지정한 실행에서
하위 9개가 사라졌다(iui #1023).
B-33 결정문의 「안 읽는 내용 필드는 P3 으로 보존돼 소멸하지 않는다」는 대치 경로 한정이다. 이 의무는 생성기 스코프에만 적용하고, 색인 검색·대치 경로는 그대로 두며(「빈 결과보다 낫다」), 이미 만들어진 산출물을 소급해 무효로 보지 않는다. 생성 단계 검증이 이것을 재시도 사유로 볼지는 구현(I-16·I-17)에서 정한다.
version 은 LLM 이 쓰지 않는다. 프롬프트가 「쓰지 말라」고 지시하고 후처리(generator/postprocess.ts)가 상수를 붙인다.
2026-08-20 100회 실행에서 모델도 100/100 정확히 적었으므로 품질 개선이 아니라 책임 분리다 — 모델이 판단할 것이 아닌 값은 모델에게 맡기지 않는다.
카테고리마다 셋을 선언한다. 요구 등급을 필수·선호·무시로 나누는 대신, 성립 조건은 최소로 줄이고 나머지는 기본값을 가진 선택 값으로 옮겼다.
| 선언 | 무엇인가 | 못 채우면 |
|---|---|---|
| 성립 조건 | 이게 없으면 그 종류로 배치가 불가능한 것 | 그 종류가 후보에서 빠진다 |
| 선택 속성 | 안 적어도 되는 것. 규약이 기본값을 정해 둔다 | 기본값으로 그린다 |
| fallback 순서 | 그 종류가 색인에 없을 때 물러날 곳 | 순서를 따라 내려가고 마지막은 항상 List |
내용을 요구하는 것은 넷뿐이다 — BigNumber·Gauge 의 수치, HierarchicalTree 의 children, ComboChart 의 혼합 조건, 그리고 페이지 역할 쪽 3행.
NestedScope 는 0.5.4 에서 children 요구가 빠져 다섯에서 넷으로 줄었다 — 동심원은 가변 깊이 트리가 아니라 배열 순서만 있으면 되는 구조라서다.
나머지는 개수와 matrix 유무만 본다.
기본값은 표현 선택에만 준다. 내용에는 주지 않는다.
apex(어느 쪽이 꼭대기인가) → 기본값 OK
value(숫자가 얼마인가) → 없는 데이터를 지어내는 것이므로 성립 조건
「선택 속성」열이 내용 필드(period, speaker)와 표현 선택(orientation, apex)을 섞어 담고 있었다.
그대로 계산하면 Timeline → Steps 에서 시각(period)을 버리게 된다.
갈라서 내용은 옮기고 표현만 버리도록 고쳤다.
앞 절이 어디로 내려가나였다면 이 절은 내려갈 때 내용이 어떻게 되나다. 덱에는 이 절반이 없었다. 그 사이에 규칙 이름이 붙고(P1~P8), 질의가 얼마나 복잡해질 수 있는지가 레벨로 묶였고(L1~L3), 노드가 여럿일 때 어느 것부터 포기하는지가 2026-08-28 에 확정됐다(N1~N5).
fallback 은 카테고리를 바꾸는 일이라 출발 카테고리가 쓰던 필드를 도착이 못 읽는 경우가 생긴다. 이때 어디로 옮기는지를 정하는 것이 규칙 여덟이다. 버리는 규칙은 P2 하나뿐이고 나머지 일곱은 전부 옮기는 규칙이다.
| 규칙 | 무엇을 하나 |
|---|---|
| P1 | entities 는 그대로 간다. 순서와 label·items·children 은 어느 엣지에서도 손대지 않는다 |
| P2 | 도착이 선언하지 않은 params 는 버린다. 표현 선택이지 내용이 아니기 때문이다 |
| P3 | 도착이 안 읽는 내용 필드는 그 entity 의 items 맨 뒤에 이름: 값 으로 붙인다 |
| P4 | matrix 를 못 읽는 곳으로 가면 entities 로 편다. 첫 열이 label, 나머지가 items |
| P5 | measure 를 못 읽는 곳으로 가면 value·unit 을 entity 로 옮긴다. 나머지는 P3 |
| P6 | entities 만 있는데 matrix 가 필요하면 행으로 편다 |
| P7 | 도착이 관계를 못 그리면 relation.desc 를 of 첫 항목의 items 맨 뒤로 보낸다 |
| P8 | 도착의 개수 상한을 넘으면 초과분을 마지막 항목의 items 로 접는다 |
| P9 제안 | measure → matrix 필수인 곳. value 를 1행짜리 matrix 로 접는다 (Gauge → PictogramChart 근거) |
| P10 제안 | matrix → measure 필수인 곳. 대표값 1행을 value 로 쓴다. 대표값 고르는 기준(첫 행·합계·최대값)이 아직 없다 |
| 출발 → 도착 | 걸리는 규칙 | 무엇이 옮겨지나 |
|---|---|---|
| BarChart → List | P1 P2 P3 P4 | matrix 행이 entities 가 되고 unit·value 가 items 로 간다. orientation·sort 는 표현 선택이라 버린다 |
| BigNumber → HighlightedMessage | P1 P2 P3 P5 P8 | value·unit 이 entity 로 옮겨지고 delta·emphasis 도 함께 간다. 1개를 넘으면 나머지는 마지막 항목으로 접는다 |
| ComparisonTable → Versus | P1 P2 P4 P8 | matrix 행이 entities 가 되고, Versus 는 정확히 2가 조건이므로 초과분을 마지막 항목에 접는다 |
레벨은 산출물 한 건을 분류하는 이름이 아니다. 누적이고(L1 ⊂ L2 ⊂ L3), 그래서 L3 를 켠 생성기가 컴포넌트 하나짜리를 내는 것은 정상이다. 「질의」라고 부르지 않는다 — 검색용 질의로 바뀌는 것은 질의 변환기를 거친 뒤다.
| 레벨 | 이름 | 최상위 components[] | entity.components[] | 그 레벨을 켜려면 |
|---|---|---|---|---|
| L1 | 단일 컴포넌트 | 길이 1 | 안 쓴다 | 없음 지금 도는 것이 이것이다 |
| L2 | 병치 위상 | 여럿 허용 | 안 쓴다 | 조각마다 검색을 호출하고 결과를 한 페이지로 조립하는 오케스트레이션(I-11) |
| L3 | 전체 위상 | 여럿 허용 | 쓴다 | 위의 것 전부 + 중첩 후보의 대치 로직(D-7) + N3·N4 반복 시 최상위 원소 수 상한(B-32) |
레벨을 가르는 축은 하나다 — 컴포넌트 경계를 넘는 계층(entity.components[])을 쓰느냐.
같은 컴포넌트 안 계층(entity.children[])은 어느 레벨에서나 쓴다. 그것은 내용 구조이지 위상이 아니다.
실서비스 Summary 생성기(허재영·황현진)는 L2 까지다 — 규약 1절이 「entity.components[] 를 채우지 않는다」고 정한 그 생성기다.
PoC 생성기(정원석)는 이미 L3 를 낸다. 프롬프트에 ## 이종 컴포넌트 절이 있고 골든셋에 중첩 산출물이 들어 있다.
그래서 「L3 는 자리만 열려 있다」는 말은 생성 쪽에는 더 이상 맞지 않는다. 비어 있는 것은 그다음 두 칸이다 — 조각을 조립하는 오케스트레이션(I-11)과 중첩 후보의 대치 로직(D-7). 4단계 실서비스에서 어느 레벨까지 켤지는 정해진 바 없다.
앞 절의 사다리는 노드 하나의 카테고리를 내리는 규칙이다.
질의가 중첩이나 병치로 노드를 여럿 가지면 그것과 별개로 포기 순서가 필요하다.
2026-08-28 확정, SSoT 는 capability-table.md 3.6절이다. 위에서부터 시도하고 후보가 나오면 멈춘다.
| 단계 | 무엇을 하나 | 잃는 것 |
|---|---|---|
| N1 | 질의 트리 전체를 그대로 담은 후보를 색인에서 찾는다 | 없다 |
| N2 | 트리 모양을 고정한 채 노드마다 앞 절의 fallback 순서를 따라 내려간다 | 노드마다의 카테고리 표현 |
| N3 | 가장 바깥 부모를 벗겨 자식을 최상위 components[] 로 올리고 N1 부터 다시 | 벗긴 부모의 카테고리 표현과 형제 사이의 인접성 |
| N4 | 남은 노드가 모두 단일 카테고리가 될 때까지 N3 을 반복한다 | 위와 같다. 깊이마다 한 번씩 |
| N5 | 규약 1절 「중첩은 평탄화된다」대로 자식 entities 를 부모 items 로 편다 | 자식 전부의 카테고리 표현 |
부모를 벗기면 질의 하나가 여럿으로 갈라져 후보 풀이 커지고, 자식의 내용과 카테고리 표현은 전부 남는다. 반대로 자식을 벗기면 내용을 지불하는데 부모는 여전히 복합 구조라 매칭 난이도가 그대로다. 내용을 내주고 검색 가능성을 못 얻는다.
평탄화와 떼어내기는 둘 다 텍스트를 하나도 버리지 않는다. 다른 것은 표현이다 — 평탄화는 자식의 카테고리 표현을 잃고 부모의 배치를 지키며, 떼어내기는 그 반대다. 표현을 더 많이 남기는 쪽을 먼저 두기로 정했다.
| # | 붙는 규칙 여섯 |
|---|---|
| N-R1 | 벗긴 부모의 label·items·relations[].desc 는 버리지 않고 승격된 첫 조각의 첫 entity items 맨 뒤로 (P3·P7 과 같은 방식) |
| N-R2 | 형제는 큰 묶음부터 그리디로 나눈다. 4형제면 [4] · [3,1] · [2,2] · [2,1,1] · [1,1,1,1] 순. 연속한 형제만 묶고 순서를 바꾸지 않는다 |
| N-R3 | 색인 어휘의 Unclassified 는 카테고리가 아니라 경계다. 질의 type 이 될 수 없다 |
| N-R4 | N 단계 수와 카테고리 강등 칸 수는 서로 다른 예산이다. N3 한 번이 강등 칸을 소모하지 않는다 |
| N-R5 미확정 | 부모 대분류가 Hierarchy 면 N3 을 건너뛰고 N5 로. 깊이 3 이상 계층 질의가 실측에 없어 판정 근거가 없다(B-31) |
| N-R6 | N2 의 조합 순서는 강등 칸수 합이 작은 것부터. 합이 같으면 뿌리에서 먼 노드를 먼저 내린다 — 뿌리를 내리면 자식 슬롯이 함께 바뀌기 때문이다 |
D-7 이 이종중첩 템플릿을 검색 풀에서 제외하기로 확정했으므로(2026-08-11, 전체 약 2%),
뿌리가 Unclassified 인 템플릿이 후보로 걸리지 않는다. 그래서 N1 은 지금 정책상 언제나 비어 있고,
모양이 이종중첩인 채로 남는 N2 도 후보가 0이다. 동종중첩은 D-7 밖이라 N1·N2 가 살아 있다.
D-7 의 결정 근거가 「대부분 조합 fallback 만으로 해결될 것으로 예상」이었으므로, N3~N5 의 결과 품질이 그 예상의 검증 자료가 된다. 되돌릴지는 열려 있다(D-8).
alternatives 와 fallback 순서는 보는 것이 다르다| fallback 순서 | alternatives | |
|---|---|---|
| 어디 있나 | capability 상수. 카테고리마다 미리 박혀 있다 | 생성물. 입력마다 다르다 |
| 무엇을 보나 | 카테고리 대 카테고리만 | 그 입력의 내용을 본다 |
| 언제 정하나 | 규약을 쓸 때 한 번 | 생성할 때마다 |
Gauge → BigNumber → List 는 게이지에 무엇이 담기든 같다. 반면 생성기는 입력을 이미 읽었으므로,
같은 Hierarchy.Pyramid 라도 층마다 크기 차이가 의미를 지니면 Staircase 가 낫다는 것을 안다.
다만 이것은 가정이고 실측이 없다 — 생성기가 고른 alternatives 가 정적 순서보다 나은지 검증된 적이 없어
optional 로 열어 두고 생성기 정책으로 켜고 끈다.
SSoT — projection 은 규약 5절, 복잡도 레벨은 규약 8.8절, 복합 구조 순서는 spec/capability-table.md 3.6절.
코드는 projection.ts(P1~P8 계산·적용) · fallback.ts(카테고리 확정)이고, N1~N5 는 규약만 확정되고 코드는 미착수(I-11)다.
덱에서 가장 중요한 부분이다. 어제까지의 결정이 하루 만에 뒤집혔다.
| 항목 | 2026-08-02 | 2026-08-03 |
|---|---|---|
| 계층 | structure 에 선언하지 않는다 | 컴포넌트를 nested 구조로 두어 해결한다 |
| 꾸밈 | 질의 쪽 필드를 두지 않는다 | 꾸밈구조를 둔다. 다만 1단계는 전역 기준만 |
8/2 결정이 판정 책임을 색인 쪽으로 넘겼는데, 색인 쪽에 그것을 받을 선언이 없었다.
capability-table.md 에 꾸밈 언급이 0건이었다.
그 결정의 근거표가 보존 전용 문서에만 있었다.
허브가 「v0.5 는 이 철학을 따르지 않는다」고 적어 둔 문서다.
7/24 회의의 N / N+α / N+β 는 누적 등급이다 (N ⊂ N+α ⊂ N+β). 여기에 네 가지 문제가 있었다.
N+β 가 「요소 배치와 장식」이다. 배치가 정교한데 그림이 없는 컴포넌트가 있다.
「배경은 원하지만 일러스트는 싫다」에 이름이 없다.
배경·테두리·아이콘이 생기면 「N+β 안쪽」이라 할 수밖에 없다.
N 의 「최소 필요 조건」은 capability 성립 조건과 같은 대상이다. 등급 최하단에 두면 같은 사실이 두 곳에 생긴다.
decoration: # 꾸밈구조 하나 ornament: prefer # 꾸밈 축 하나 + 선호값 하나 → Element.Decoration background: avoid # 꾸밈 축 하나 + 선호값 하나 → Element.Background
prefer — 있으면 가점indifferent — 보지 않는다 (기본값)avoid — 있으면 감점require 를 두지 않는다. 꾸밈을 필수로 걸면 후보가 0이 된다.
축이 RLSC role 하나에 정확히 대응하면 추출이 이미 붙인 표식을 그대로 쓸 수 있다.
minimal(N)·rich(N+β)는 문서와 회의에서 부르는 별명이고 스키마 값이 아니다 — 축이 늘면 뜻이 바뀌기 때문이다.
| 층 | 1단계 (지금) | 요소 대치 착수 후 |
|---|---|---|
| Summary (질의) | 생성하지 않는다. 스키마에 optional 로 자리만 | 필요하면 생성기가 적는다 |
| 카테고리 기본 | 미정 | 45종에 채운다 |
| 시스템 전역 기본 | 여기만 잡는다 (예: 꾸밈 많은 것을 우선) | 유지 |
entity.components[] 와 page relations 가 모두 「스키마에 열어 두고 생성기는 채우지 않는다」.
decoration 도 같은 방식으로 연다.
꾸밈구조를 실제로 쓰는 곳은 요소 대치다. 그런데 그게 돌려면 앞뒤 다섯 구간이 전부 대응해야 한다. 덱 시점에 한 구간이 끊겨 있었다.
신동한님 쪽 모듈(AI 꾸미기)을 참고해 구현하기로 했다 2026-07-23 회의. 흐름은 넷이다.
| ① | ② | ③ | ④ |
|---|---|---|---|
| reference design template / page / component |
교체 target AI 가 식별 |
query · embedding 교체 대상 서술 |
확정 제약 size 등 |
7/23 회의 원문: 「비슷한 요소 찾기 사용. 다만 교체 타겟 결정 및 타겟별 query 생성이 중요」
검색 자체보다 무엇을 바꿀지 정하고 어떻게 서술할지가 문제다.
reference design 이 꾸밈 수준을 이미 정해 버리면 꾸밈구조는 요소 대치에 안 쓰이고 검색 단계에만 쓰인다.
7/23 기록은 「장식 요소는 유지하고 내용 관련 요소만 대치」다.
이석님의 packages/comp-sign 이 시그니처 추출 · 검색 · 랭킹 · 내용 대치 네 단계를 이미 구현하고 있다.
비어 있던 것은 「고른 다음에 무엇을 어디에 어떻게 넣을 것인가」의 규약이다.
그래서 PoC 의 목적은 데모가 아니라 스쿼드가 못 닫고 있는 결정을 실측으로 닫는 것이고,
화면이 있는 이유도 보여 주기 위해서가 아니라 판정 이력을 사람이 열어 볼 수 있게 하기 위해서다.
사용자 입력
→ ① LLM YAML 생성 generator/ LLM 이 YAML 을 쓴다 · 재생성 루프
→ ② 검증 validate.ts 파싱 → id 부여 → zod → capability
→ ③ 카테고리 확정 fallback.ts 성립 조건 + 자기 행 fallback + projection
→ ④ 검색 질의 변환 query.ts structure → 태그·제약 (④ 는 ⑤ 의 입력)
→ ⑤ 실색인 검색 search.ts 태그 군 우선 · 군 안에서 구조 적합도
→ ⑥ 내용 대치 binding.ts RLSC 슬롯에 직접 삽입 (규약 경로)
┈┈┈┈┈┈┈ 여기까지가 질의 갈래. 아래는 실서비스 경로와의 대조 ┈┈┈┈┈┈┈
→ ⑦ comp-sign 비교 markdown.ts → compSignService.ts → intersect.ts
structure → markdown → textTree → 구조 검색·대치
→ ⑧ 렌더·채점 sheet.ts · audit.ts 같은 기준으로 두 경로를 비교
각 구간은 앞 구간의 산출물만 입력으로 받는다. 그래서 어느 구간이 나빴는지를
뒤의 귀속 채점이 가를 수 있다. 모듈 이름은 전부
src/lib/visual-summary/ 기준이다.
| 구간 | 모듈 | 입력 → 산출물 | 이 구간이 지키는 계약 |
|---|---|---|---|
| ① LLM YAML 생성 | generator/ prompts/system.md vocabulary.ts generate.ts |
사용자 글 → YAML 문자열 | 어휘 45종(41 + PageNavigation_* 4)만 준다. version 은 LLM 이 쓰지 않고 postprocess.ts 가 상수로 붙인다. 스키마 위반은 오류 문장을 되먹여 재생성 |
| ② 검증 | parse.ts assignIds.ts schema.ts validate.ts capabilityCheck.ts |
YAML → VisualSummary 객체 |
파싱 → id 부여(e1.., relation of label→id) → zod → 카테고리별 정합. silent corruption 을 따로 센다 — 파싱은 됐는데 값 타입이 조용히 바뀐 것 |
| ③ 카테고리 확정 | capability.ts establish.ts projection.ts fallback.ts |
구조 → 확정 카테고리 + 투영된 구조 | 요청 카테고리는 원 구조로, 도착지는 투영(P1~P8) 뒤 구조로 성립을 본다. 자기 행만 끝까지 타고 도착지 행으로 갈아타지 않는다 |
| ④ 검색 질의 변환 | query.ts | 확정 결과 → 태그 군 + 제약 | 항목 수·글자 용량 제약과 태그 군(tier) 을 만든다. structureDigest 는 comp-sign structureHash 자리 표시다 — 실물이 오면 이 함수 하나만 바꾼다 |
| ⑤ 실색인 검색 | search.ts | 질의 + 색인 → 후보 순위 | 군이 점수보다 절대 우선하고, 군 안에서 구조 적합도(단위 수·글자 용량·슬롯)로 채점. 이 모듈은 DB 를 모른다 — 색인을 배열로 주입받는다 |
| ⑥ 내용 대치 | rlsc.ts binding.ts |
구조 + 후보 RLSC → 대치된 RLSC | 검색과 같은 단위 정의(detectUnitLayout)를 쓴다 — 점수가 좋다고 판단한 구조 그대로 채워진다 |
| ⑦ comp-sign 비교 | markdown.ts intersect.ts api/…/compSignService.ts |
구조 → markdown → 실서비스 경로 결과 | 같은 입력을 실서비스 경로로도 돌려 나란히 놓는다. 교집합과 RRF 순위 융합으로 판정 지표를 만든다 |
pipeline.ts 가 조립하는 것은 ① 부터 ④ 까지다. 코드 머리말이 그대로 적는다 —
「색인 갈래(RLSC, Search Signature)와 실제 검색 실행(BE)은 범위 밖이고, 그 경계까지의 산출물(질의)을 만든다」.
⑤ 이후는 PoC 가 BE 를 대행하는 구간이다. search.ts 는 실서비스
rankCompCandidates() + BE 검색의 자리를 대신하되 계약의 핵심 둘(군 우선, 군 안 채점)만 재현한다.
comp-sign 은 Visual Summary YAML 을 직접 받지 않는다. 유일한 진입 방언이
parseSummaryTree(markdown) 라서, markdown.ts 가 다리를 놓는다 —
structure → markdown → buildCompSearchData → textTree.
그래서 ⑥(규약 RLSC 대치)과 ⑦(comp-sign 대치)은 경쟁 관계가 아니라 대조 관계다.
⑥ 은 MORDOR PoC 전용 베이스라인이고 실서비스가 쓰는 대치는 ⑦ 의
buildContentReplacement() 하나뿐이다. 둘을 같은 후보 풀·같은 용량 근거로 재야 판정이 성립한다.
버전 제약이 하나 걸려 있다 — nexus 배포판이 4.3.5(SIGNATURE_VERSION 36)라
파이프 표(격자 leaf)와 헤딩 H 마킹이 없다. 그래서 markdown.ts 는 표를
파이프 표가 아니라 중첩 리스트로 직렬화한다. 4.3.8 이 배포되면 바꾼다.
| 구간 | 상태 | 설명 |
|---|---|---|
| Visual Summary 생성 | 실서비스 코드 | 실제 OpenAI 호출과 프롬프트, 재생성 루프가 그대로 돈다 |
| 검증 · 카테고리 확정 · 질의 변환 | 실서비스 코드 | 규약을 코드로 옮긴 것. 문서와의 정합을 테스트가 기계로 대조한다 |
| 시그니처 색인 | 계산은 실서비스 · 저장은 PoC | 실제 createCompSignatureBuilder() 로 만들지만, 실서비스는 테이블에 미리 적재하고 PoC 는 서버가 뜰 때 메모리에 즉석으로 만든다 |
| 후보 조회 | PoC 코드 | 실서비스는 BE 가 DB 를 조회하는데 PoC 는 메모리 안에서 해시를 맞춰 본다 |
| 랭킹·대치 (구조 검색) | 실서비스 코드 | rankCompCandidates, buildContentReplacement 를 그대로 호출한다. 내용시각화 BE 가 쓰는 4단계 경로다 |
| 랭킹·대치 (시멘틱 검색) | PoC 자체 구현 | 검색 search.ts, 대치 binding.ts. comp-sign 이나 BE 경로가 아니다 |
| 결함 채점 | 자체 구현 | 실서비스에 대응물이 없는, 이 PoC 가 새로 만든 계측기 |
색인 규모는 로컬 태깅 컴포넌트 2,468건(시그니처 3,424벌 · 고유 구조 해시 668개 · 빌드 33초 · 30분 캐시). 실서비스는 178,095건이라 이 방식을 그대로 쓸 수 없고, 그것이 아직 스쿼드가 정해야 할 열린 결정이다. 범위 밖 — 차트·이미지 데이터 대치, 색상 대치, 실제 테이블 적재, 백엔드 검색 실행.
design_object_semantic_tags 의 의미 태그로 후보를 찾는다. 태그가 맞는 후보를 먼저 채우고, 그 안에서 항목 수와 글자 용량이 얼마나 맞는지로 점수를 매긴다.
의미 태그를 보지 않는다. 내용을 markdown 으로 바꿔 comp-sign 에 넣으면 구조 해시와 변형이 나오고, 해시가 정확히 일치하는 컴포넌트를 채점 항목 20여 종으로 순위 매긴다.
두 축이 깨끗하게 갈린 것이 뜻밖의 자산이 됐다. 스쿼드가 합의한 판정 지표가 「두 검색의 교집합 상위 10건 품질」인데, 이 PoC 에 그 두 검색이 각각 실서비스 코드로 있어서 교집합을 실제로 계산할 수 있다.
comp-sign 의 입력은 markdown 인데 Visual Summary 는 항목 트리를 내놓는다. 그 사이가 structure → markdown 변환이다.
트리를 직접 조립하지 않고 markdown 을 거치는 이유는 comp-sign 이 트리와 해시를 같은 파싱 과정에서 만들기 때문이다 —
트리를 직접 만들면 해시 경로와 어긋날 수 있다고 패키지 소스가 명시한다.
이전 라운드에서는 대치 결과 23장을 손으로 봤다. 결함을 실제로 찾아냈지만 코드를 고칠 때마다 23장을 다시 볼 수 없어 「이 변경이 좋아졌나」를 말할 수 없었다. 그래서 같은 판정 기준을 기계로 옮겼다. 16종 각각이 §2 의 원인 넷 중 하나에 대응한다.
| 원인 | 결함 | 무슨 일이 벌어진 것인가 |
|---|---|---|
| 텍스트 용량 초과 | capacity.lineOverflow | 넣은 글이 그 자리의 줄 수를 넘는다 |
| capacity.charOverflow | 줄 수를 모르는 자리에서 글자 수가 용량을 넘는다 | |
| 매핑과 위계 오류 | mapping.categoryDrift | 규약이 허용하지 않는 카테고리의 컴포넌트를 골랐다 |
| mapping.roleInversion | 제목에 들어갈 내용이 설명 자리로 내려간다 | |
| mapping.markerAbuse | 순서 번호 자리에 문장이 들어간다 | |
| mapping.orderInversion | 화면 순서가 입력 순서와 뒤집힌다 | |
| 슬롯 수 불일치 | slots.unitDeficit | 항목이 칸보다 많다 |
| slots.unitSurplus | 칸이 항목보다 많아 빈 칸이 남는다 | |
| slots.lineDeficit | 여러 항목이 한 자리에 접히거나 아예 버려진다 | |
| slots.lineSurplus | 채우지 못한 텍스트 자리가 남는다 | |
| 대치 실패 | replace.residue | 결과에 남은 글이 사용자 입력에서 온 것이 아니다 |
| replace.placeholder | comp-sign 이 임시 문구로 채웠다 | |
| replace.emptied | 채울 내용이 없어 템플릿 원문을 비웠다 | |
| replace.markupLeak | markdown 표기가 결과 글에 그대로 나갔다 | |
| replace.unmapped | 대치할 텍스트를 실제 요소에 못 붙였다 | |
| replace.contentLoss | 사용자가 넣은 조각이 결과 어디에도 없다 |
심각도는 셋이다 — blocker ×5(사용자 내용이 사라졌거나 남의 내용이 남음), major ×2(위계 어긋남), minor ×1(빈 자리·임시 문구). 결함 수를 그냥 더하면 가벼운 결함이 많은 결과가 더 나빠 보이므로 가중치를 곱해 더한다.
넘침 판정을 comp-sign 채점과 같은 계산으로 맞췄다(글자 수가 아니라 줄 수 기준). 자리마다의 용량도 comp-sign 시그니처가 담은 값을 두 경로 모두에서 그대로 쓴다. 이게 성립하려면 RLSC 노드 식별자와 sheet 요소 식별자가 같아야 하는데, 색인 2,468건의 텍스트 자리 17,899개 전량에서 결합률 100% 였다.
기계 채점을 그대로 믿지 않고 눈으로 확인해 잘못 잡은 것 셋을 걷어냈다 — 순서 번호를 「입력에서 오지 않은 글」로 세던 것, 정상 배치를 위계 어긋남으로 세던 것, 잔존 템플릿에 markdown 기호가 있으면 한 결함을 두 번 세던 것. 셋 다 회귀 테스트로 고정했다.
귀속은 단일 결과가 아니라 대안과의 비교에서만 나온다. 두 경로 다 상위 후보 전부에 대치를 돌려 보고 그중 하나만 쓰는데, 채점기가 그 버려지던 것을 주워 담아 셋으로 나눈다.
| 조건 | 귀속 |
|---|---|
| 후보 풀 안 어느 것으로도 못 피한 결함 | 생성 탓 |
| 같은 경로의 다른 후보로는 피할 수 있던 것 | 검색 탓 |
| 같은 후보를 다른 경로가 더 잘 채운 것 | 대치 탓 |
정직성 장치가 하나 붙는다 — 랭킹이 애초에 볼 수 없었던 결함(시그니처 밖 자리의 넘침 등)은 검색 탓에서 덜어낸다. 랭킹에게 없는 정보로 벌점을 매기면 이 수치로 가중치를 튜닝할 때 잘못된 방향으로 간다.
| 지표 | 시멘틱 검색 | 구조 검색 | 순위 융합 |
|---|---|---|---|
| 심각도 가중 평균 (낮을수록 좋음) | 20.0 | 22.0 | 20.7 |
| 1위 후보가 결함 0 인 비율 | 0.0% | 1.6% | 1.5% |
| blocker 없는 입력 비율 | 8% | 7% | 원문에 없음 |
08-15 이전에는 구조 검색(17.5)이 시멘틱(19.9)을 크게 이겼다. 「검색이 허용한 카테고리 밖에서 고른 것」을 결함으로 새로 세자 순위가 뒤집혔다.
구조 검색이 앞서 보이던 것의 대부분은 의미를 재지 않은 덕이었다.
텍스트 넘침이 양쪽 모두 1위 결함이고 건수가 거의 같다(시멘틱 176 · 구조 177).
대치 방식이 아니라 검색 풀과 용량 자체의 문제라는 뜻이다.
귀속을 세면 생성 36 · 검색 466 · 대치 17 · 랭킹이 못 본 것 74.
랭킹 가중치 실험(MOR-1936)이 대치 알고리즘을 다듬는 것보다 값이 큰 다음 수라는 근거가 여기서 나온다.
다만 두 검색은 1위 후보가 65개 중 2개(3%)만 겹쳐서, 「교집합 상위 10건」을 그대로 지표로 쓰면 표본이 거의 남지 않는다.
comp-sign 의 태그 군 셋은 「그 후보를 끌어온 근거가 사용자냐 LLM 이냐」로 나눈다. PoC 실색인 검색의 군 넷은 「그 태그가 강등 사다리의 어느 지점에서 나왔나」로 나눈다.
| comp-sign 태그 군 | 그 컴포넌트가 후보에 들어온 이유 |
|---|---|
| 0군 | 사용자가 직접 고른 분류에 속한 태그를 갖고 있다 |
| 1군 | LLM 이 글을 보고 추정한 태그를 갖고 있다. 0군과 겹치는 태그는 뺀다 |
| 2군 | 0군에도 1군에도 없다 — 태그와 무관하게 구조 해시만으로 걸린 후보 |
| PoC 검색 군 | 질의가 그 태그를 어디서 얻나 |
|---|---|
| 1군 | 생성기가 적은 type 과 alternatives |
| 2군 | 요청 카테고리의 fallback 행 |
| 3군 | 강등 사다리가 최종 확정한 카테고리 |
| 4군 | 안전망. 종단 셋. 1~3군이 하나도 못 찾았을 때만 발동한다 |
양쪽 다 군이 점수보다 절대 우선이다. 1군 후보가 아무리 점수가 높아도 0군을 앞설 수 없고,
2군은 fallback 행의 순서 그대로라 Timeline 이 List 보다 항상 먼저다.
이 규칙은 원래 없었고 실사용 로그 10건 실행에서 「같은 군 안에서 순서가 점수에 밀리는」 문제를 발견해 고정한 것이다.
규약 5절은 「성립 조건을 못 채우면 후보에서 빠진다」는 이분법인데, comp-sign 은 제외하지 않고 뒤 군으로 미룬다. 규약은 컴포넌트가 무엇을 소화하는지를 보고 구현은 그 후보가 어디서 왔는지를 본다 — 축이 다르다. PoC 는 1군에서만 빼고 2·3군으로 내려보내므로 규약 쪽에 가깝지만 완전히 같지는 않다.
| 계층 | 무엇을 하나 | 상태 |
|---|---|---|
| 복합 구조 순서 (N1~N5) | 노드가 여럿일 때 어느 노드부터 포기하나 | 규약 확정(08-28) · 코드 미착수 (I-11) |
| exact structure match | 해시와 태그로 동일 구조 후보를 찾는다 | 동작 풀이 얕으면 실패가 잦다 |
| semantic fallback | 카테고리 강등과 P1~P8 | 규약·코드 모두 완료 |
| 4단계 comp-sign 대치 | textTree 와 시그니처로 텍스트를 넣는다 | 실서비스 경로 · 규약 contract 미완 |
| 5단계 property 대치 | 이종 type 사이 카테고리 고유 속성 투영 | 부분 T-7 추출만 있고 T-8 미착수 |
structure projection 과 property projection 은 이름만 비슷하다
앞은 내용(structure)을 옮기고 뒤는 카테고리 고유 속성(질의 쪽 params, 색인 쪽 properties)을 옮긴다.
P1~P8 만으로는 「List 안의 BigNumber」처럼 서로 다른 카테고리 사이에서 속성을 옮기는 문제를 풀지 못하고, 그것이 5단계 T-8 의 영역이다.
PoC 규약 RLSC 대치(binding.ts)는 실서비스 경로가 아니다 — MORDOR PoC 전용 기준선이고,
내용시각화 BE 가 쓰는 대치는 buildContentReplacement 하나다.
| 단계 | 결과 |
|---|---|
| 생성 | 10/10 성공 (재생성 루프 사용 7회) |
| 검색 | 컴포넌트 15개 전부 후보 확보 — 검색 군으로 1군 5 · 2군 8 · 3군 1 · 4군 안전망 1 |
| 대치 | entity 56개 중 56개 수용 (43개 배치, 13개 접기) |
절반 이상이 2군이라는 것은 생성기가 고른 카테고리를 색인이 그대로 대 주지 못한다는 뜻이다. 이 실행에서 시스템 구멍 두 가지를 찾아 코드에 반영했다 — 같은 군 안에서 순서가 점수에 밀리는 문제(2군 정렬을 태그 순위 우선으로 고정), 마지막 fallback 카테고리마저 색인에 없으면 후보가 0이 되는 문제(4군 안전망 추가).
전 컴포넌트(실서비스 17만여 건)에 시그니처와 속성을 한꺼번에 구울 수는 없다. 세 대치 경로를 공정하게 비교하려면 같은 후보 풀 위에 미리 구워 둬야 한다.
| # | 규칙 |
|---|---|
| 1 | 기준 pool 은 indexPool.ts 술어와 같다 — sheet_json 과 structure_json 이 둘 다 있는 것 |
| 2 | 평가 pool 은 그중 고정 subset. 실사용 50건(컴포넌트 65개)이 입력이다 |
| 3 | 후보 pool 크기는 약 5,000건 제안 — 카테고리별 후보가 마르지 않고 굽는 비용이 하루 안에 끝나는 지점 |
| 4 | 시그니처 · I.I.S. 경계 · I.I.S. 속성을 같은 design_object_id 집합에 굽는다. 한쪽만 있으면 5단계 비교가 성립하지 않는다 |
| 5 | 5단계 화면은 속성 bake 와 T-8 규칙이 있어야 연동된다. 지금은 4단계 2-way 만 가능하다 |
비용 어림의 근거는 실측이다 — 시그니처 빌드가 2만 건에 약 4.4분, 5만 건에 약 9.9분이고
properties 추출이 137건에 4분(입력 23만 토큰)이었다. 5,000건이면 추출 약 2.4시간 · 입력 약 840만 토큰으로 어림된다.
| 무엇 | 어디 (aippt-prisonbreak) |
|---|---|
| 규약을 코드로 옮긴 것 — 어휘·타입·스키마·capability 상수·establish/fallback/projection·query·audit | src/lib/visual-summary/ |
| 항목 트리를 markdown 으로 바꾸는 다리 | …/markdown.ts |
| 결함 채점과 귀속 | …/audit.ts |
| 교집합과 순위 융합(RRF) | …/intersect.ts |
I.I.S. 대행 생산 — 경계 추출, properties·구조 대응, 노드 검색·대치 | …/iis/ |
| 생성 프롬프트와 재생성 루프 | …/generator/ |
| 규약 예시 18종 · 안티패턴 5종 · 평가셋 50건 · 생성 스냅샷 | …/fixtures/ |
| 두 경로가 공유하는 후보 풀 | src/app/api/visual-summary/indexPool.ts |
| comp-sign 실제 코드 호출 | src/app/api/visual-summary/compSignService.ts |
| Eregion 화면 (탭 다섯) | src/app/visual-summary/ |
comp-sign v4.3.8 의 네 함수 — buildCompSignatures(구조 해시·text_map·채점 feature, DB 적재용) ·
buildCompSearchData(markdown → textTree 와 조회용 해시) · rankCompCandidates(채점·중복 제거·정렬) ·
buildContentReplacement(대치 텍스트 생성·box 보정·형제 그룹).
DB 접근과 후보 fetch 는 호출자(BE) 몫이고 이 패키지는 순수 계산만 한다.
입력이 markdown 이라는 점이 중요하다 — Visual Summary YAML 이 이 경로에 직접 들어갈 자리가 아직 없다.
I.I.S. 는 색인 쪽 모듈이다. 질의를 만들지 않고, 이미 있는 컴포넌트 안을 더 잘게 나눈다. 그 결과가 대치에 닿는 경로가 이 절이다.
현행 검색은 컴포넌트 전체에 붙은 최대 4개 태그로 후보를 고른다. 한 컴포넌트 안에 여러 의미가 섞여 있으면 그 안의 어느 부분이 요청 카테고리인지 특정할 수 없다.
실물이 그렇다 — design_object_id 4757227 에는
Comparison Table · Hierarchical Tree · List · Highlighted Message 넷이 함께 붙어 있다.
최상위 하나가 이 넷을 동시에 가질 수는 없으니 하위에 여러 유형의 노드를 품고 있다는 뜻이다.
| T | 모듈 | 무엇을 하나 | 상태 |
|---|---|---|---|
| T-4 | iis/extractBoundary.ts | 경계 추출. 컴포넌트 안 어느 노드 묶음이 어느 카테고리인지 LLM 이 판정해 iis_semantic_component 에 적재 |
코드 있음 사람 검수 미완 |
| T-5 | iis/nodeSearch.ts | 노드 단위 검색. 경계 노드마다 그 서브트리를 독립된 컴포넌트처럼 취급해 검색 | 코드 있음 메인 통합 미완 |
| T-6 | iis/nodeBinding.ts | 노드 단위 대치. 매칭된 경계 서브트리 안에만 채우고 밖은 원본 보존 | 코드 있음 평가셋 전량 미실행 |
| T-7 | iis/extractProperty.ts | 속성·구조 대응 추출. 경계가 잡힌 노드에 카테고리 고유 속성과 구조 대응을 붙인다 | v1 코드 정확도 검수 미완 |
| T-8 | iis/propertyMatch.ts | 속성 대조와 정책. 질의 params ↔ 노드 properties 를 맞대고 정책 셋을 다 낸다 |
판정부만 |
T-5·T-6 의 설계가 같은 문장을 공유한다.
nodeSearch.ts 는 경계 노드의 서브트리를 독립 컴포넌트로 취급해
rankComponents() 를 그대로 재사용하고,
nodeBinding.ts 는 bindComponentToRlsc() 를 그대로 재사용한다 —
그 함수가 이미 「RLSC 트리 하나」에 대해서만 동작하므로, 컴포넌트 전체 대신 매칭된 서브트리를 넘기면 그만이다.
nodeBinding 이 더하는 것은 둘뿐이다 — 그 서브트리를 찾는 것과, 대치 결과를 원래 자리에 도로 이어붙이는 것. T-6 완료 판정의 핵심이 「태그 밖 노드는 안 건드린다」이다.
이유가 코드 주석에 적혀 있다 — 「같은 규칙을 두 벌 만들면 반드시 어긋난다」. PR 리뷰가 같은 종류의 Critical 을 다섯 번 낸 원인이었다고 한다.
반복 단위(patternLabel)와 role 로 경계 위치를 규칙으로 뽑고 LLM 은 카테고리만 고르게 하는 안은 기각됐다.
반복 단위와 역할은 배치 정보이지 의미 경계가 아니기 때문이다 —
같은 반복 묶음이 절차일 수도 목록일 수도 있고, 의미상 한 경계가 여러 반복 단위에 걸칠 수도 있다.
규칙으로 뼈대를 먼저 고정하면 LLM 이 고칠 수 없는 자리에 오답이 박힌다. 그래서 RLSC 를 줄여 보여 주는 투영은 「판단하지 않는다. 무엇을 보여 줄지만 정한다」.
| 산출물 | 무엇인가 | 없으면 무엇을 모르나 |
|---|---|---|
| properties | 카테고리마다 정해진 표현 값 — 피라미드 꼭대기가 어느 쪽인가, 순서가 어느 방향인가 | 이 컴포넌트를 어떻게 그리는가 |
| structure 구조 대응 | 경계 안 어느 노드가 label 인지 items 인지의 대응표 | 사용자 내용의 어느 조각을 어느 노드에 넣는가 |
한 컴포넌트에 한 번만 부른다. 노드마다 따로 부르지 않는 이유가 코드에 적혀 있다 — 한 컴포넌트 안의 경계 여럿이 같은 그림 하나를 공유하고, 회전 방향·오름차순 같은 속성은 서로 무관하지 않다 (Cycle 의 rotation 과 그 안 Steps 의 sequence 가 같은 그림에서 나온다).
속성은 「읽어낼 수 없으면 뺀다」가 계약이다. 허용 밖 키·모양 밖 값·없는 노드 참조는 버리고 보고할 뿐 재시도를 걸지 않는다 — 값 하나가 어긋났다고 컴포넌트 전체를 다시 물으면 맞게 읽은 나머지까지 버리게 된다. 재시도는 응답을 아예 못 읽을 때만 건다.
질의 속성과 노드 속성이 어긋났을 때 무엇을 할지는 미리 고르지 않는다.
완료 판정 자체가 「세 정책을 다 돌려 결과를 비교한 표. 어느 하나를 미리 고르지 않는다」이기 때문이다 —
exclude(후보 탈락) · reorder(채우는 순서를 뒤집어 해소) · ignore(감점만).
reorder 가 blueprint 의 property projection 이고,
구조 투영 P1~P8 과는 다른 축이다 — 앞은 내용을 옮기고 뒤는 표현 값을 옮긴다.
경로가 둘이고 별개로 진행된다.
질의 쪽은 사용자 입력을 검색 조건으로 바꾸고(Summary · structure),
색인 쪽은 이미 있는 템플릿을 미리 뽑아 둔다(RLSC · Search Signature v2).
둘은 BE 검색 모듈에서 합류한다. structure 에서 RLSC 로 가는 화살표는
변환이 아니라 capability 대조이고, 그 규약이 capability-table.md 다.
템플릿 페이지 → ALSC → Structuriser → RLSC → 유효 컴포넌트 게이트 → design_objects.
거기서 comp-sign 시그니처와 semantic 태깅 두 갈래가 갈린다.
파이프라인 그림에서 굵은 테두리 셋 중 하나 — Visual Summary(질의 표현) · Search Signature v2(색인 contract) · RLSC(구조 어휘).
실물 RLSC 는 Group/Text/SVG/Chart 노드 트리이고, Text 노드가 role 을 단다 —
Role.Element.Title · Subtitle · Description · Marker.
규약 7절의 대응(entity.label → Title, items[] → Description)이 이 슬롯 위에 선다.
4단계에서 Old RLSC → I.I.S. → New RLSC. 노드마다 semantic tag 가 붙어 §12 의 모호성이 사라진다.
New RLSC 가 충분히 쌓이면 Structuriser 자체 모델을 재학습한다는 것이 그다음 계획이다.
binding.ts 가 실제로 넣는 자리entity.label → 단위의 Title 슬롯 entity.value → 단위의 Subtitle 슬롯 (없으면 Description 앞줄, 그것도 없으면 label 병기) entity.items[] → 단위의 Description 슬롯들에 분배 (모자라면 마지막 슬롯에 이어 붙임) 순번 → 단위의 Marker 슬롯 (01, 02, …) 페이지 제목 → 머리 영역(반복 단위 밖)의 Title/Subtitle/Description
RLSC 서브트리의 role 시그니처 반복으로 찾은 반복 단위(detectUnitLayout)에 맞춘다.
검색 채점(search.ts)과 같은 단위 정의를 쓰므로,
점수가 좋다고 판단한 구조 그대로 채워진다.
추출 쪽은 이미 노드 단위로 핵심·위성·장식을 식별하고 있다. §6 이 지적한 「질의 쪽에 위성 자리가 없다」는 구멍의 반대편이 이것이다.
| 태그 | 무엇인가 | 대치에서의 의미 |
|---|---|---|
| CORE | 컴포넌트 경계 그 자체 | 반드시 채워야 하는 슬롯 |
| DESC | satellite 컴포넌트 | 있으면 채우는 슬롯 |
| DECO | 컴포넌트 안팎을 가리지 않는 장식 요소 | 비우거나 제거 가능 |
OUT 은 폐기됐다 2026-09-05원 출처(2026-07-31)의 「DESC·DECO·OUT」 표기는 RAT pod 의 semantic tagging 검증 트랙에서 파생된 것이고, 그 트랙 자체가 holding 또는 deprecated 다. I.I.S. 대치 계약에서 유효한 것은 위 셋뿐이라고 2026-09-05 에 정리됐다.
| 이름 | 무엇인가 | 만드는 곳 · 쓰는 곳 |
|---|---|---|
| structure | YAML 의 entities·relations·dataset. 질의와 P1~P8 의 입력 | 생성기 · validate.ts · projection.ts |
| textTree | comp-sign 이 markdown 을 파싱해 만든 대치용 텍스트 트리 | compSignService.ts · buildContentReplacement |
| text_map text_node_roles | 컴포넌트 시그니처의 슬롯 용량·역할. 런타임 용량의 SSoT(legacy textCapacity 아님) | buildCompSignatures 적재 · 채점 · 대치 |
| RLSC text slots | PoC 자체 대치가 RLSC 서브트리의 Title/Description/Marker 에 직접 넣는 경로 | binding.ts · rlsc.ts |
다리는 structure → markdown → buildCompSearchData → textTree 다.
comp-sign 경로는 Visual Summary YAML 을 직접 받지 않는다 — markdown 과 textTree 를 받는다.
이름을 섞어 쓰면 fallback 이후 대치 계층을 따라갈 수 없다.
| 구간 | 담당 |
|---|---|
| 단어장 v7 정의와 유지 | 김수현 |
| Summary 생성기 | 스키마 정원석 · 생성 실무 허재영, 황현진 |
| 시멘틱 쿼리 추출 LLM · 컴포넌트 태깅 | 황현진 |
| 태깅 결과 수신·검증·적재 | 류민 → 박지우 |
| 노드 분류와 카테고리별 속성 | 신영빈 · 류민 |
| I.I.S. (4단계) | 류민 덱 시점 정지 |
시그니처·랭킹·대치 계산 (comp-sign) | 이석 |
| Visual Summary 규약 | 정원석 |
| 검색과 대치 실행 | 최운식 (BE) |
layouts 태깅은 BE 로 가지 않는다. RAT pod 내부용이고 검색에는 컴포넌트 태깅만 쓴다.
dataset 을 DataViz Matrix 로 바로 넘길 수 있나 (어댑터 실측)nested_scope 를 concentric_rectangles 로 볼 수 있나rankCompCandidates 위계 가중치 A/Btree children → Graph relations 규칙entity.components[] 생성 시점
덱은 3주 전 사진이다. 아래 대조표는 손으로 쓴 것이고,
그 아래 두 표(DASHBOARD.md 로드맵·절별 잔여)와 §6 의 변경 12건은
mordor-wiki 원문에서 자동 동기화된다 —
원본이 바뀌면 sync-sources.py 가 낡음을 잡아낸다.
| 단계 | 무엇이 바뀌는가 | 목표 시점 | 지금 상태 |
|---|---|---|---|
| 1단계 (현행) | Markdown Summary, 임베딩 검색 | 지금 | 운영 중, 변동 없음 |
| 2단계 | 컴포넌트에 Semantic Component Category | 2026-08-07 확정. 4단계로 직행 | |
| 3단계 | YAML + structure 검색 | 없음 | 실행하지 않음 (2026-08-06 Cancelled) |
| 4단계 | RLSC node 태그로 정확한 범위 특정 | 단독 단계로는 건너뛴다 (2026-09-08 확정) | 실행 티켓 여섯이 Cancelled. 끝난 산출물(fallback map, 꾸밈 축 등)은 5단계가 그대로 쓴다 |
| 5단계 | node 에 semantic category 속성까지 | 여기로 직행한다 (2026-09-08 확정, 정원석) | 경계 4,764건·속성 3,955건 로컬 파일럿(09-06), 노드 검색 엔진 배선(09-07). 정확도 판정(K-9-1)과 10만 건 추출(MOR-2415)이 남았다 |
↻ 로드맵 5단계 현재 상태 · DASHBOARD.md — 원본에서 자동 동기화
| 덱이 열어 둔 것 | 지금 | 근거 |
|---|---|---|
B-24 type 을 41종으로 좁힐지 49종으로 열지 열림 |
닫힘 49종으로 확정. 페이지 역할 4종은 어휘에 넣고, 지도 4종은 capability 성립 불가로 표시 | 2026-08-06 정원석 · MOR-1909 |
| B-18 꾸밈구조 규약 표기 열림 | 닫힘 키는 decoration, page 수준도 연다. 1단계에서 생성기는 안 채운다 |
덱 당일 2026-08-04 규약 2.7절에 반영 |
| B-22 장식 role 표식을 색인으로 넘기는 경로 끊김 | 아직 열림 — §10 의 끊긴 구간이 그대로다 | MOR-1935 |
| B-25 대분류를 없애고 중분류만 남겨도 되나 | 아직 열림 B-24 와 별개 항목으로 남았다 | 허재영 2026-08-04 제기 |
| fallback 엣지 55개, 최대 두 칸 | 개정 45종 · 엣지 130개, 칸 수 상한 폐지. 근접도 순서만 지키면 몇 칸이든 | capability-table.md 2026-08-17 |
| capability 41행 | 확장 45행 (41종 확정 + PageNavigation 4종. 그 성립 조건도 2026-08-27 에 채워져 격차가 닫혔다 — 남은 것은 Opening 이 맨 앞장 전용인지 하나뿐이다) |
capability-table.md 범위 절 |
| 「선택 속성」한 열에 내용과 표현이 섞여 있다 | 해결 선택 내용 / 속성 두 열로 분리. fallback 때 내용은 옮기고(P3·P7) 표현은 버린다(P2) | 2026-08-23 |
| I.I.S. 정지 — 류민, 2026년 6월 중순부터 막힘 | 우회 기다리지 않는다. PoC 에서 같은 출력을 대행 생산하는 것이 4단계 실행 경로 (D-5 닫힘) | 2026-08-22 DASHBOARD 4절 |
| 급한 순서 1위 = C-1 BE 정책 협의 | 재편 실행 1순위는 I-8 평가 pool bake. 그 다음 I-7+I-9(속성 projection), I-2(대치 contract) | 2026-08-22 PoC 우선순위 |
| — | 신규 B-30 measure↔matrix projection 규칙(P9·P10) 미정 — Gauge↔PictogramChart fallback 이 여기 걸려 있다 |
2026-08-17 열림 |
| — | 신규 B-27 도착의 개수 상한을 넘을 때 규약 5절 1번(후보 탈락)과 P8(접기)이 같은 상황에 답이 둘 | MOR-1934 |
TODO.md 는 할 일을 아홉 절(A~J)로 나눈다. 품질을 좌우하는 것은
I절(내용 대치 contract) 이고, 그것이 §2 의 BAD 85% 구간이다.
| 절 | 무엇을 다루는가 | 마감 | 남은 것 |
|---|---|---|---|
| A | 규약 확정 | 2026-08-07 | 1건 (A-4) |
| B | 규약 열린 결정 | A 에 종속 | 0건 |
| C | 2단계 배포 | 사실상 스킵 (2026-08-07) | 2건 (C-6, C-7) |
| D | 스쿼드 차원에서 정할 것 | 각각 다름 | 1건 (D-8) |
| E | 7/24 회의 후속 | 미정 | 3건 |
| F | 사후 검증 (마감 후로 미룸) | 마감 후 | 1건 (F-2) |
| G | 최근 해소된 것 | 없음 | 기록만 |
| H | 문서 정합 백로그 | 없음 | 3건 |
| I | 내용 대치 contract | 미정 | 14건 |
| J | 생성 모델 파인튜닝 | 착수 전 | 8건 |
| K | Week 27 PoC | week 27 | 2건 (K-9-1, K-11) |
↻ 절별 남은 일 · DASHBOARD.md — 원본에서 자동 동기화
덱에는 없던 축이다. 2026-08-24 싱크에서 mastra 기반 생성 파이프라인의 첫 실측이 공유됐다.
평가셋 50건 × 3회, 모델 gpt-5.6-luna, 재시도 없음.
| 항목 | split — 정의를 tool 로 받아 거른다 | inline — 정의 45종 전량 주입 |
|---|---|---|
| 규약 통과 | 49~50 / 50 | 49~50 / 50 |
| 라벨 정렬 | 21~25 / 50 | 19~20 / 50 |
| 1,000건 비용 | $3.36 | $2.19 |
| 지연 중앙값 | 8,894 ms | 6,741 ms |
값의 타입 규칙과 「스키마에 없는 키를 만들지 않는다」규칙을 넣기 전 37/50, 넣은 뒤 49~50/50. 케이스 단위 흔들림이 10~18/50 이므로 이 상승은 흔들림보다 크다.
split 이 3회 모두 앞섰지만 150 시도 기준 46% 대 39%, 차이 7.3pp. 비용은 1.53배다.
「다름」23건 중 모델이 확실히 틀린 것은 10건 남짓이고, 그 다수가 Enumeration.List 로 물러선 경우다.
카테고리 우선순위도 P0~P2 로 재편됐다 (2026-08-21 김수현). P0 는 10월 배포에서 잘 되어야 하는 범위이고 UX 의 유저 프리셋 버튼과 같은 범위다. 역제안 대상으로 지목된 넷은 CombinedResult · ProblemSolution · BigNumber · SectionDivider. 「잘 되어야 한다」의 판정 기준은 아직 비어 있다.
통합본이 부록을 쓰면서 문서 사이에 어긋난 자리를 다섯 확인했다. 파생물이 규약 본문보다 뒤처진 것이 셋이었고, 넷은 그 자리에서 닫혔다. 남은 것은 5번 하나와 3번의 꼬리다.
| # | 무엇이 어긋나 있었나 | 어떻게 됐나 |
|---|---|---|
| 1 | visual-summary-0.5.schema.json 에 structure.columns 와 entity.values[] 가 없다 | 닫힘 2026-08-29 에 규약 2.2절에서 파일을 다시 내보냈다 |
| 2 | semanticCategory enum 과 capability.json 에 PageNavigation 4종이 빠져 있다 | 닫힘 enum 이 결합값 45종(0.5.3), capability.json 도 45종이 됐다 |
| 3 | capability-table.md 2.6절의 페이지 역할 4종 성립 조건이 비어 있다 | 닫힘 2026-08-27 에 채워졌다. 남음 Opening 이 맨 앞장 전용인지 — 골든셋은 맨 앞장 전용으로 만들었고(08-25 황현진) 단어장 오너 확인 대기 |
| 4 | fallback 엣지 수가 131개와 128개로 함께 적혀 있다 | 오탐 남아 있는 숫자는 전부 이력 서술이다. 현재 값은 130개 — 2026-09-05 에 PictogramChart↔Gauge 와 PictogramChart → BigNumber 를 빼면서 줄었다(B-30, measure↔matrix projection 규칙을 만들지 않기로 확정) |
| 5 | capability.json 이 BigNumber 의 선택 내용에 delta 를 넣어 뒀는데 스키마의 entity 에는 delta 가 없다 — measure 에만 있다 | 열림 항목이 여럿인 BigNumber 는 증감을 적을 자리가 없다. 둘 중 어느 쪽을 맞출지 정해야 한다 |
자기정합 검사 14가지를 마지막으로 전량 돌린 것은 2026-08-04 였고, 그 뒤 개정 다섯 번이 검사 없이 들어갔다. 2026-08-29 에 전량 다시 돌려 통과시켰다.
그 과정에서 검사 둘을 고쳤다 — F2(「어느 행도 대체 후보를 셋 이상 두지 않는가」)는 두 칸 상한이 2026-08-17 에 없어져 폐기했고,
F3 은 「종단 셋으로 끝나는가」였는데 같은 날 List 뒤에 ListingTable 을 안전망으로 덧붙인 행이 넷 생겨
「거치거나 자신이 그 셋인가」로 고쳤다.
이 대조는 capability.test.ts 가 capability.json 과 45종 전량을 맞대는 형태로 코드에도 있다.
다만 docs/ 가 비공개 submodule 이라 CI 체크아웃에 없어서 로컬에서만 돌고 CI 에서는 건너뛴다.
먼저 볼 것 둘은 규약(spec/schema-v0.5.md)과 할 일 SSoT(TODO.md)다.
나머지는 필요할 때 찾아 들어가면 된다.
앞으로 이 문서는 항상 아래 둘을 다시 읽어 갱신한다. 값이 어긋나면 이쪽이 맞다.
구현 aippt-prisonbreak/src/lib/visual-summary/ — 모듈 37개 · 9,753줄.
진입점은 README.md(모듈 구성)와 _SIGNATURE.md.
규약 aippt-prisonbreak/docs/projects/mordor/visual-summary/ — mordor-wiki 가 submodule 로 붙은 것.
spec/ 이 규약, design/ 이 설계 근거.
이번 갱신 기준 mordor-wiki 013fff13 (정본 v0.5.6, 2026-09-12 조회)
구현 쪽 README 가 스스로 적는다 — 「이 모듈은 그 규약의 실행 가능한 파생물이고, 문서와 어긋나면 문서를 따른다」.
정합은 capability.test.ts 가 spec/schema/capability.json 과 45종 전량을 기계로 대조한다.
다만 docs/ 가 비공개 submodule 이라 CI 에서는 skip 되고 로컬에서만 돈다.
| 문서 | 무엇 |
|---|---|
| spec/schema-v0.5.md 규약 | SSoT. 0절 v0.4→v0.5 변경 12건 · 2절 스키마 · 5절 fallback 규칙 · 9절 열린 결정 |
| TODO.md 할 일 | A~J 아홉 절. B절이 규약 열린 결정 29건의 SSoT |
| DASHBOARD.md | 진행 현황 요약판. 로드맵 5단계 상태 · 절별 잔여 건수 · 병목 셋 |
| spec/capability-table.md | 45종 성립 조건 · 선택 내용/속성 · fallback 순서 · 엣지 130개 projection · 생성기 불허 9종(10.1절) |
| design/decoration-model.md | 꾸밈구조 설계 SSoT — §9 의 근거 |
| design/pipeline-flow.md | 전체 흐름 |
| design/content-binding-contract.md | 내용 대치 구간 contract — I절 8건의 근거 |
| reference/semantic-taxonomy-v7.md | 단어장 v7 49종 |
| spec/schema/…0.5.schema.json | 기계 판정용 SSoT. TypeScript 타입과 zod 는 여기서 나온 파생물 |
| meetings/2026-08-24-…sync.md 최신 | 생성 파이프라인 실측 · I.I.S. 골든셋 · P0 재편 — §15 의 근거 |
| reference/2026-08-04-visual-summary.pdf | 이 페이지의 원본 덱 24쪽 (로컬) |
| reference/visual-summary-overview.pdf 최신 | 2026-08-29 통합본 96쪽 — 개념·일정·작업 상태·구현물 로직에 부록(45종 전량 · params 27종 · fallback 엣지 131개(당시) · 열린 결정 47건 · 자기정합 14가지)까지. §6·§8·§11·§16 의 근거 (로컬) |
github.com/miridih/mordor-wiki → projects/mordor/visual-summary/.
aippt-prisonbreak 를 클론했다면 docs/ submodule 이 같은 저장소다 —
git submodule update --init docs 후 docs/projects/mordor/visual-summary/.
GitHub 계정이 없으면 Confluence 발행본으로 공유한다.