# 검증 화면 — 컴포넌트 규칙

실행 결과를 **눈으로 파고드는 화면**을 만들 때 읽는다.
설계 단계의 화면(값이 아직 없는 것)은 `.claude/guides/experiment-figures-guide.md`.

작성 2026-09-01.

## 왜 이 문서가 있나

같은 화면을 실험마다 처음부터 만들었다. 인터랙티브 검증 페이지가 **9개 · 약 9.7MB** 이고,
셋(`public/token-inspector.html` · `public/rank-cut.html` · `namesilo-winner-traits/label.html`)이
**gmgn iframe 도크를 각자 다시 구현했다.** 같은 결함도 다른 실험에서 되풀이됐다.

> **토큰 클릭이 안되는데** — 2026-08-27 web-deploy-cohorts
> **토큰 클릭은 안되는데,** — 2026-08-29 quote-cluster-stats

**페이지 구조는 일반화하지 않는다.** `rank-cut`(컷 슬라이더+묶음 트리) · `label`(라벨링) ·
`news-rank-board`(550건 판정+4분면) · `creator-board`(발행자별 조달처) — 공통 레이아웃이 없고
억지로 맞추면 안 쓰인다. **일반화하는 단위는 컴포넌트다.**

---

## 층 셋 — 아래 둘만 공통

```
상위 목록      묶음 · 텍스트 · 무엇이든        실험 고유. 계약 없음
   ↓ 클릭
토큰 목록      토큰 배열만 받는다              공통
   ↓ 클릭
토큰 상세      토큰 하나                       공통
```

상위가 무엇이든 아래 둘은 그대로다. 토큰 목록이 최상위인 경우도 그냥 된다.
`rank-cut` 이 이미 이 모양이다 — 좌측에 상위 목록, 우측에 토큰 목록과 상세가 세로로 쌓인다.

---

## 컴포넌트마다 — 고정과 자유

**무슨 정보가 들어가나는 고정, 어떻게 배치·표현하나는 자유.**

| 컴포넌트 | 고정 | 자유 |
|---|---|---|
| **토큰 목록** | 행에 주소 · 심볼 · `max_mc` · `first_transfer_at` + **지금으로부터 며칠 전** · AF 지표 <br> 행 클릭 가능 · 정렬 가능 | 어느 칸을 더 넣나 · 정렬 기본값 · 그룹핑 |
| **토큰 상세** | gmgn iframe · 주소 복사 · **연결된 컨텐츠 전부** · 그 토큰의 메트릭 **전부** | 탭이냐 스크롤이냐 · 배치 |
| **분포 차트** | 축에 단위 · **기준선을 그림 안에 실선** · 로그면 축에 표기 · n 표시 | 히스토그램 · 막대 · 산점도 중 무엇 |
| **컨텐츠 카드** | 원문 전문(자르면 자른 표시) · **부모가 있으면 붙임**(P20) · 원본 링크 · 작성 시각 · **플랫폼별 필드 전부** | 카드냐 인라인이냐 |
| **필터 · 컷 컨트롤** | 지금 값 표시 · 이 값이 무엇을 바꾸는지 한 줄 · **바꿔도 선택 유지** | 슬라이더냐 버튼이냐 |

### 다 넣는다 — 목록만 예외

**파고드는 화면(토큰 상세 · 컨텐츠 카드)은 넣을 수 있는 것을 다 넣는다.**
지금까지 반복 요청이 전부 「이것도 넣어줘」였다.

> **max mc 도** 보여줄 수 있나? 그리고 리스트에 **날짜도** 표기해줘
> 토큰 `first_transfer_at`, **현재시간으로 몇일전껀지** 등도 + **`af_cum_buy` 같은 메트릭도** 포함

**목록은 반대다.** 스캔하는 화면이라 칸이 7개를 넘으면 못 읽는다.
필수 다섯 + 실험이 고르는 한둘로 좁힌다. 「실험마다 추가」가 적용되는 곳이 여기다.

### 무엇을 넣을지는 `guides/audit-sources/` 가 정한다

플랫폼별로 **무슨 필드가 실제로 오는지**가 거기 있다 — `x` · `telegram` · `youtube` ·
`instagram` · `github` · `tiktok` · `reddit` · `website`. 컨텐츠 카드는 그 문서의 필드를 펼친다.
**지어내지 않는다.** CLAUDE.md 가 그 폴더를 「fetcher 가 실제로 반환하는 것의 ground truth」로 지목한다.

### 빈 값의 뜻을 가른다

다 넣으면 빈 칸이 많아진다. **「없음」 · 「0」 · 「수집 안 함」이 섞이면 오독한다** —
`pitfalls.md` P22 가 정확히 그 실패다(`$ifNull` 로 결측을 셌는데 0 이 같이 걸렸다).
audit 문서가 필드마다 값의 성격을 적어두었으니 그걸 따라 표시를 가른다.

---

## 조각은 두 등급

**A급 — 그대로 복사.** 데이터 계약이 좁아 실험과 무관하다. 지금 세 페이지에 각자 구현돼 있고 하나로 뽑으면 끝난다.

```
gmgn 도크        주소 하나만 받는다
빌드 스탬프       생성 시각 + 데이터 기준 시각
선택 유지         필터가 바뀌어도 현재 선택을 놓지 않는다
축 · 기준선 그리기  값과 라벨만 받는다
```

**B급 — 계약 + 렌더 함수.** 실험마다 데이터가 달라 조각이 그대로 안 된다.
모양을 좁게 정하고 실험이 매핑한다.

```
renderTokenList(tokens, opts)
renderTokenDetail(token)
renderDist(values, { axis, unit, baseline, log })
renderContent(items)
```

놓을 자리는 이미 있다 — `render-section.sh` 가 `.claude/guides/samples/` 의 벤더 파일을
출력물 옆으로 복사한다(`mermaid.min.js` 등). 거기에 kit 하나를 더 놓으면
**오프라인 자립을 깨지 않는다.**

### 일반화하지 않는 것

묶음 트리(quote-cluster) · 4분면(news-rank) · 라벨링 UI(namesilo) — **실험 고유다.**
넣으려 들면 계약이 넓어져 아무것도 재사용이 안 된다.

---

## 설계 화면(S2 · S3)의 조각 셋

**여기부터는 값이 있는 화면이 아니라 `/exp:design` 의 승인 화면 얘기다.** S2·S3 이 골격을
버리면서 「이 밀도로 쓴다」를 전할 데가 없어졌는데, **전체 페이지를 참조로 두면 이름만 다른
골격이 된다.** 위 원칙 그대로 — 페이지는 일반화하지 않고 조각만 일반화한다.

글로는 안 전해지는 것이 셋이다. 실측 근거: 이 셋으로 그린 예시 화면이 별도 검증자에게
**2회차까지 반박을 받았고**, 걸린 것이 전부 아래 조각의 밀도 문제였다.

### ① 체크 항목 + 근거 줄

**☑ 는 통과가 아니다. 「무엇을 보고 판정했나」 한 줄이 붙어야 통과다.**
`figures-guide §7` 목록이 이미 있었는데도 E7 이 그 8번 항목의 실패였다 — 근거 칸이 없어
안 대보고 통과시켜도 표가 안 났다.

```html
<li>단마다 x·y축 <b>이름과 단위</b>가 있다. y축에 「무엇의 %」가 들어간다
    <span class="src draft">E7</span>
  <div class="ev">② 의 y축이 <code>%</code> 가 아니라 <b>「해당 카테고리의 생존율 (%)」</b>,
    ③ 은 <b>「60분 시점 생존율 (%)」</b>. r1 은 5단 전부 한 글자였다</div></li>
```

| 고정 | 자유 |
|---|---|
| 항목마다 `.ev` 근거 줄 하나 · **화면의 실제 문자열·숫자를 인용** · 어느 실패에서 나왔는지 태그 | 배치 · 태그 표기 |

**근거에 쓸 게 없으면 그 항목은 통과가 아니라 되돌아갈 자리다.** 실제로 「병렬 표기」 항목이
그렇게 잡혔다 — ☑ 는 이미 찍혀 있었고 근거를 쓰려니 쓸 게 없었다.
반대로 **인용한 값이 화면에 없으면 거짓 근거**고, 그건 검증자가 잡는다.

### ② 단계별 추적표 (S3 절 2 · S1 검산)

**값이 단계마다 어떻게 바뀌는지를 따라간다.** 행 = 개체, 열 = 단계. 계산 로직을 의사코드로만
남기면 맞는지 알 수 없다(E5).

```
모양 띠     10 입력 → 10 판정 → 7 통과 + 3 실패 → 4 카테고리 행
추적표      # · 입력 요약 · ① 반환 · ② 검증 · ③ 배정(맞음) · ③′ 배정(틀림) · 결과
대비        맞는 집계 ↔ 틀린 집계를 나란히. 무엇이 갈리는지 한 줄
검사값      이 표가 낳은 숫자 — 실행 세션의 회귀 검사값이 된다
```

| 고정 | 자유 |
|---|---|
| 단계마다 열이 하나씩 늘어난다 · **갈림길이 있으면 맞음/틀림을 나란히** · 회귀 검사값 명시 · 표본 규칙 한 줄 | 행 수 · 표냐 카드냐 · 모양 띠를 그릴지 |

**표본은 결과와 무관한 규칙으로 뽑는다**(E6). 지어낸 더미면 결과가 없어 문제없고, 실제
데이터를 쓰면 「등간격 추출」처럼 결과를 먼저 계산해야 하는 규칙을 쓰지 않는다.

### ③ 출처 배지 — 인라인

골격 화면은 칸마다 오른쪽 위에 붙였지만 **자유 레이아웃엔 「칸」이 없다.** 값 옆에 붙인다.

```html
실패율이 <b>5%</b><span class="src mine">⚠ 제가 정함</span> 를 넘으면 집계하지 않고 멈춘다
```

| 고정 | 자유 |
|---|---|
| 넷 중 하나(`said`/`draft`/`mine`/`open`) · **값 바로 옆** · 색은 배경, 글자는 진한 잉크 | 어느 값에 붙일지 · 범례를 둘지 |

쓰임은 하나다 — **`⚠ 제가 정함` 만 눈으로 훑으면 지시가 빈 곳이 나온다.** r1 은 S3 한 절에서만
`mine` 이 19개였다. `open` 이 하나라도 남으면 승인 대상이 아니다.

---

## 페이지 레벨은 셋만

컴포넌트로 안 내려가는 것만 남긴다.

```
빌드 스탬프     생성 시각 + 데이터 기준 시각. 둘은 다르다
오프라인 자립   외부 CDN · 폰트 · 이미지 금지. gmgn iframe 만 예외
패널 둘         목록 + 상세. 셋 이상 금지 — 중간 패널이 상세를 좁힌다
```

> `fix(quote-cluster-stats): rank-cut 헤더에 빌드 스탬프를 박는다`
> 지금 비율이 너무 안맞아. 가장 우측의 **토큰 디테일이 최소 1/3** 은 차지하고

---

## 하지 말 것

- **행을 클릭할 수 없게 두는 것.** 목록이 있으면 클릭된다고 가정하고 만든다 — 두 실험에서 같은 말을 들었다
- **차트를 새 창으로 보내는 것.** 돌아올 때 스크롤과 선택이 날아간다
- **중앙값만 내는 것.** 꼬리가 안 보인다 — 「중앙값말고 전체 실제 범위를 볼 수 있는 표도」
- **필터를 움직여 보던 토큰이 사라지게 두는 것.** `fix: 보고 있는 토큰이 사라지지 않게 한다`
- **데이터를 통째로 인라인하고 크기를 안 재는 것.** 2.8MB 짜리가 이미 둘 있다

---

## 이미 있는 구현

**새로 짜기 전에 여기서 가져올 수 있는지 먼저 본다.**

| | 무엇이 다듬어져 있나 |
|---|---|
| `public/token-inspector.html` | `GmgnDock`(도크 헤더 · 액션 · 프레임) · `localStorage` 상태 유지 |
| `public/rank-cut.html` | 좌/우 2패널(`pane-l` `pane-r`) · 컷 슬라이더와 손익 표시 · 묶음 트리 펼침 |
| `namesilo-winner-traits/label.html` | 수기 라벨링 · 빌드 스탬프 |

---

## 남은 일

**이 문서는 규칙이지 코드가 아니다.** 셋에 흩어진 A급 조각을 한 벌로 뽑는 것이
F8 을 실제로 닫는 일이고 아직 안 했다. 그때까지는 이 규칙으로 누락만 막는다.

컨텐츠 전문까지 다 실으면 페이지가 커진다. 모수를 줄일지 상위 N 개만 전문을 실을지는
**실험 설계(S1 모수)에서 정할 것**이라 이 문서의 문제가 아니다.
