# t-분포(t-distribution) 설계서 — 구현자용

설계·검증: Claude (coordinator, claude-opus-5-5). 구현: 이 문서를 받은 서브에이전트. 정한 것은 그대로 따르고, 바꿔야 하면 바꾸지 말고 멈추고 묻는다(보고에 질문으로 적고 끝낸다). 이 저장소 밖의 파일(특히 `~/.claude/`)은 읽지 않는다. 스크린샷과 산출물은 `out/t-distribution/` 아래에 둔다.

이 페이지는 6부 "확률과 통계"의 첫 문서다. 기계가 아닌 개념이지만 **원리가 일어나는 장치를 상상해 그린다**: 상자를 n개 뽑아 무게를 재고, t를 셈해 구슬을 칸에 떨어뜨리는 "표본 뽑는 기계". 다른 문서와 같은 Anatomy 방식(등각 투영, kit 톤, 그림 안 라벨, 버튼)을 쓴다. 3D·XR은 없다.

## 0. 먼저 읽기
`docs/concept.md`, `.agents/skills/isowiki-entry/SKILL.md`, `docs/knowhow.md`(특히 "그림 안 라벨", "휴대폰", "판과 모서리 문구", "맞춰 읽는 눈금과 시간이 걸리는 움직임"), `docs/provenance.md`의 "베리언트" 절, 코드 본보기 `pages/thermometer/variants/sol-codex/figure/{model.mjs,scene.mjs,index.mjs,live.js}`(판 위 장치, 버튼, 투어, 움직이는 라벨), kit 참조 `.agents/skills/anatomy/references/kit.md`.

## 1. 한 문장
라벨에 500 g이라고 적힌 상자를 n개 뽑아 무게를 재면, 평균은 500 g에서 조금 벗어난다. 그 벗어남을 "표본에서 잰 퍼짐 ÷ √n" 단위로 잰 값이 t다. 기계가 이것을 여러 번 되풀이해 t마다 구슬을 칸에 떨어뜨리면 종 모양이 쌓이는데, n이 작을수록 양 끝(±1.96 바깥)에 구슬이 더 많이 떨어진다 — 퍼짐까지 적은 표본에서 재기 때문이다. 그 쌓인 모양이 t-분포다.

독자가 하는 일: "표본 크기" 3개·5개·30개를 고르고, "한 번"으로 한 표본이 재어지는 과정을 보고, "100번"으로 칸을 빨리 채운다. 판독값의 "바깥" 비율이 n 3에서 약 19%, 30에서 약 6%(정규 곡선이라면 5%)인 것을 본다. 손대지 않으면 투어가 3개 → 30개 → 5개를 돈다.

## 2. 파일과 메타
- `pages/t-distribution/index.md`(공유), `pages/t-distribution/variants/opus-subagent/index.md`(베리언트), `pages/t-distribution/variants/opus-subagent/figure/{model.mjs, scene.mjs, live.js, index.mjs}`.
- `build.mjs`: `PARTS` 끝에 6부 `{ n: 6, ko: "확률과 통계", en: "Probability & Statistics", items: [["sampling", "표본과 평균"], ["normal-distribution", "정규 분포"], ["t-distribution", "t-분포"], ["t-test", "t-검정"], ["p-value", "p값"]] }`, `LABELS` 끝에 `"t-distribution":"t-분포", "t-test":"t-검정", "normal-distribution":"정규 분포", "p-value":"p값", sampling:"표본과 평균"`. 이 두 곳만.
- `generator`와 `revisions`는 고치지 않는다. 병합할 때 조정자가 채운다.

공유 `pages/t-distribution/index.md` (그대로):
```
---
title: t-분포
en: t-distribution
part: 6
related: [t-test, normal-distribution, p-value, sampling]
default: opus-subagent
revisions:
  - date: 2026-10-15
    target: [article]
    model: claude-opus-5-5
    modelId: claude-opus-5-5
    harness: claude-code 2.1.299
    session: c0557bfd-7c20-45bf-a3c9-ce3c1f39ab97
    note: "공유 정보(제목, 부, 연결 문서). 설계서에서 그대로 옮김."
---
```

베리언트 `pages/t-distribution/variants/opus-subagent/index.md` 시작 판:
```
---
description: 작업 중
lead: 작업 중
card: 적게 뽑을수록 꼬리가 두껍다
generator:
  model: 작업 중
  modelId: null
  harness: 작업 중
  effort: [high]
  prompt: []
  note: "작업 중. 병합 때 조정자가 채운다."
revisions:
  - date: 2026-10-15
    target: [figure]
    model: 작업 중
    modelId: null
    note: "작업 중. 병합 때 조정자가 채운다."
---

(4단계에서 쓴다.)
```

## 3. 모형 (model.mjs) — 무게 g, 그림 길이 mm, 시간 s
아래 코드를 **그대로** 옮긴다(조정자가 돌려 본 코드다).
```js
// A sampling machine for the t-distribution. Boxes from a filling line weigh N(500 g, 3 g); the machine weighs
// n of them, works out t = (mean - 500) / (s / sqrt n) and drops a marble into the bin for that t.
export const MU = 500, SIGMA = 3;                 // g: the line's true mean and spread
export const SIZES = [3, 5, 30];                  // sample sizes on the buttons
export const T_MIN = -4, T_MAX = 4, BIN = 0.5;    // bins of t; anything outside goes to the two end bins
export const BINS = (T_MAX - T_MIN) / BIN;        // 16 inner bins
export const CUT = 1.96;                          // the normal curve's 95% line
export const TAIL = { 3: 0.1891, 5: 0.1216, 30: 0.0597, normal: 0.05 }; // exact share of |t| > 1.96
export const T_STAR = { 3: 4.303, 5: 2.776, 30: 2.045, normal: 1.96 };   // two-sided 95% cut-offs (df = n - 1)
export const EXAMPLE = [498, 501, 495, 499, 497]; // the worked example: mean 498, s = sqrt 5, t = -2.00

// Seeded random numbers (mulberry32) and normal draws (Box-Muller), so every page load shows the same start.
export function rng(seed) {
  let a = seed >>> 0;
  const next = () => { a = (a + 0x6d2b79f5) >>> 0; let t = a; t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; };
  return { next, normal: () => { const u = 1 - next(), v = next(); return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v); } };
}
export const round1 = (x) => Math.round(x * 10) / 10;
export const draw = (r, n) => Array.from({ length: n }, () => round1(MU + SIGMA * r.normal()));
export function stats(xs) {
  const n = xs.length, mean = xs.reduce((a, b) => a + b, 0) / n;
  const s = Math.sqrt(xs.reduce((a, x) => a + (x - mean) ** 2, 0) / (n - 1));
  const se = s / Math.sqrt(n);
  return { n, mean, s, se, t: (mean - MU) / se };
}
// Bin index: 0 = below T_MIN, 1..BINS = inner bins, BINS + 1 = above T_MAX.
export const binOf = (t) => (t < T_MIN ? 0 : t >= T_MAX ? BINS + 1 : 1 + Math.floor((t - T_MIN) / BIN));
// Densities for the curves drawn behind the bins.
const lgamma = (z) => { const g = 7, c = [0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7]; if (z < 0.5) return Math.log(Math.PI / Math.sin(Math.PI * z)) - lgamma(1 - z); z -= 1; let x = c[0]; for (let i = 1; i < g + 2; i++) x += c[i] / (z + i); const t = z + g + 0.5; return 0.5 * Math.log(2 * Math.PI) + (z + 0.5) * Math.log(t) - t + Math.log(x); };
export const tPdf = (t, df) => Math.exp(lgamma((df + 1) / 2) - lgamma(df / 2)) / Math.sqrt(df * Math.PI) * (1 + (t * t) / df) ** (-(df + 1) / 2);
export const normalPdf = (t) => Math.exp(-t * t / 2) / Math.sqrt(2 * Math.PI);
// Run k draws of size n from a seeded stream: counts per bin, share beyond +-CUT, and the last sample.
export function run(n, k, seed) {
  const r = rng(seed), counts = new Array(BINS + 2).fill(0); let out = 0, last = null;
  for (let i = 0; i < k; i++) { last = draw(r, n); const { t } = stats(last); counts[binOf(t)]++; if (Math.abs(t) > CUT) out++; }
  return { counts, out, last };
}
// Population shown in the cabinet: columns every 2 g from 494 to 506, balls per column = round(40 * 2 * pdf).
export const CABINET = Array.from({ length: 7 }, (_, i) => { const g = 494 + 2 * i; return { g, balls: Math.round(40 * 2 * normalPdf((g - MU) / SIGMA) / SIGMA) }; });
export const SEED = 7, PREFILL = 1000, MAX_DRAWS = 1000; // the bins hold at most 1000 draws; more empties them first
export const START = { n: 5, draws: PREFILL, sample: EXAMPLE };   // bins filled by run(5, 1000, SEED); the rail shows EXAMPLE
```
설계자 검산(이 코드를 node로 돌린 값 — 받아들임 기준은 이것만 쓴다):
- `stats(EXAMPLE)`: 평균 498, s 2.236, s÷√n 1, t −2.00.
- `run(n, 1000, SEED)`의 "바깥"(|t| > 1.96) 수: n 3 → 191(19%), n 5 → 132(13%), n 30 → 64(6%). 정확한 비율(TAIL): 18.9%, 12.2%, 6.0%, 정규 5%.
- `run(5, 1000, 7).counts` = [8, 7, 7, 18, 25, 47, 86, 143, 181, 184, 120, 81, 34, 19, 15, 8, 6, 11] (0번 = −4 아래, 17번 = 4 이상).
- `CABINET`: 494:1 496:4 498:9 500:11 502:9 504:4 506:1 (39개).
- 곡선 꼭대기(밀도): t df 2 0.354, df 4 0.375, df 29 0.396, 정규 0.399.

## 4. 세계와 카메라
- 1 단위 = 1 mm, x 오른쪽, y 앞, z 위. 판은 x–z 평면에 서 있고 앞면이 y = 0. 부품은 y 0…14(판 앞).
- 카드 600 × 460. `k.fitProjection(points, 600, 460, { pad: 22, azimuth: 76, elevation: 14 })`. points: `k.boxCorners({x:-300,y:-40,w:600,d:100,r:8}, -17, 0)`, `k.boxCorners({x:-285,y:-14,w:570,d:14,r:4}, 0, 270)`. 설계자가 셈한 값: scale 0.725, 판이 화면 폭 약 510 px(카드의 85%)·높이 약 274 px, 1 mm ≈ 0.89 px. 판이 넓어 좌우 여백이 좁다 → **라벨은 판 위쪽 여백(판 윗변보다 위)과 판 안의 빈 곳**으로 끌어낸다.
- **맞춰 읽는 것은 같은 깊이**(knowhow): 눈금·숫자는 그것을 읽는 부품과 같은 y에 그린다 — 자의 눈금은 막대와 같은 y 6, t 축 숫자·곡선·±1.96 선은 칸 앞면과 같은 y 14.

| 부품 | 형상 |
|---|---|
| 받침판 | `basePlate(P, {x:-300,y:-40,w:600,d:100,r:8}, { label, strip })` |
| 판 | 흰 칠한 슬래브 x −285…285, y −14…0, z 0…270, 모서리 r 4 |
| 모집단 상자 | 유리 앞판 상자 x −270…−140, y 0…12, z 168…262(테두리 프레임 + 엷은 유리). 안에 공(r 4, y 6) 7줄: 줄 i(0…6)의 x = −255 + 18·i, 무게 g = 494 + 2·i, 공 수 = `CABINET[i].balls`, 공 중심 z = 174 + 8.5·k(k = 0, 1, …). 상자 아래 앞에 각 줄 무게 숫자(494…506, y 12) |
| 내리막 | 상자 오른쪽 아래 구멍(x −140, z 174)에서 막대 왼쪽 끝(x −110, z 205)으로 가는 홈통(tube r 3) |
| 저울 막대(자) | 가로 막대 x −110…270, z 200, y 6, 지름 4(`tubePieces`). 눈금(y 6): 488…512 g, 1 g마다 짧게, 4 g마다 길게 + 숫자(z 186). 위치 x(g) = −100 + (g − 488)·15 → 488 −100, 500 80, 512 260 |
| 표본 공 | 막대 위에 r 5, y 6. 값 오름차순으로 놓고, 같은 층에서 10 mm 안에 이미 공이 있으면 한 층 위로: 중심 z = 207 + 10·층 |
| 참 평균 선 | x(500)에 막대 위로 빨간 점선 z 200…250(y 6) — 고정 |
| 표본 평균 받침 | 막대 아래 파란 쐐기(받침점) 꼭짓점이 막대 밑(z 198), 밑변 z 189, 폭 10 — x = x(평균). 평균은 공들이 균형을 이루는 점이다 |
| 퍼짐 s 괄호 | z 258에서 x(평균 − s)…x(평균 + s) 가로선, 양 끝 아래로 6 mm |
| s÷√n 자 | z 176에서 x(500)부터 x(평균)까지 선, x(500)에서 평균 쪽으로 s÷√n·15 mm마다 눈금. 끝에 "t −2.00"(소수 둘, U+2212) |
| 운반대 | 가로 레일 z 152, x −240…240(y 10, 얇은 막대). 수레(16 × 10 × 10 상자, 아래 깔때기)가 x_t = t·52(끝 칸으로 갈 때는 ±221)에 선다 |
| 구슬 칸 | 칸 18개: 0번(t < −4) x −234…−208, 1…16번 x = −208 + 26·(i−1)…+26, 17번(t ≥ 4) x 208…234. 칸막이(유리 지느러미) z 15…140, y 0…14. 칸의 채움 높이 h = (count/총수)/BIN·K, **K = 300 mm**(밀도 1당), 바닥 z 15. 채움은 구슬 색 막대 + 안에 10 mm마다 구슬 테두리 무늬, 윗면은 정확한 h |
| 곡선 | y 14(칸 앞면): t-곡선(df = n−1) z = 15 + K·tPdf(t, df), x = t·52, t −4…4(0.05 간격) — 짙은 실선, lit. 정규 곡선 z = 15 + K·normalPdf(t) — 점선 |
| ±1.96 | x = ±1.96·52 = ±101.9에 빨간 점선 z 15…150(y 14), 그 바깥 칸 바탕을 엷은 빨강으로 |
| t 축 | 칸 아래 z 6(y 14)에 −4…4 숫자(1마다), 오른쪽 끝에 "t" |
| 떨어지는 구슬 | r 5 |

## 5. 그리는 순서 (뒤 → 앞)
1. 받침판 2. 판 3. 판 위의 인쇄(±1.96 바깥 바탕) 4. 모집단 상자 뒷면·공·유리 5. 내리막 6. 저울 막대 눈금·숫자, 참 평균 선, 표본 평균 받침, 막대 7. 표본 공 8. 퍼짐 괄호, s÷√n 자 9. 운반대·수레·떨어지는 구슬 10. 칸 채움 11. 칸막이 12. 곡선, ±1.96 선, t 축 13. 라벨

## 6. 판(plate)
- title "t-분포". hint "버튼으로 표본 크기와 뽑기".
- readout: `n ${n} · ${draws}번 · 바깥 ${round(100·out/draws)}%`, 뽑은 것이 없으면 `n ${n} · 0번`. 가장 긴 경우 "n 30 · 1000번 · 바깥 19%" 꼴(22자; n 30의 실제 값은 6%). START: "n 5 · 1000번 · 바깥 13%".
- keys: [{ mark: "lit", label: "t-곡선: 표본이 작을수록 꼬리가 두껍다" }] — t-곡선을 lit.
- caption(모형값): 상자 무게는 평균 500 g, 퍼짐 3 g의 정규 분포. 칸 너비는 t 0.5, 칸 높이는 그 칸에 떨어진 비율. 처음 1000번은 미리 뽑아 둔 것이고 난수는 고정된 씨앗에서 나온다. 공은 상자를, 구슬은 t 하나를 뜻한다.
- controls(`lib/controls.mjs`): 그룹 "표본 크기" 버튼 "3개"/"5개"/"30개", 그룹 "뽑기" 버튼 "한 번"/"100번"/"비우기".
- 그림 안 라벨: 모집단 · 참 평균 · 표본 평균 · 퍼짐 s · 구슬 칸 · t-곡선 · 정규 곡선 · 바깥(±1.96). 판 윗변 위 여백과 판 안 빈 곳으로 끌어내고, 지시선은 다른 부품을 가로지르지 않는다. 움직이는 부품(표본 평균 받침, 퍼짐 괄호)의 앵커는 따라간다.

## 7. 움직임 (2단계; 1단계는 START 한 장면)
- 상태: n, counts, draws, out, sample(막대 위 공들), 난수 흐름 r = rng(SEED)(START는 `run(5, 1000, SEED)`를 돌린 뒤의 흐름을 이어 쓴다. 막대에는 EXAMPLE).
- **한 번**(1.8 s): 상자에서 n개 공이 밝아짐(가장 가까운 줄의 공) 0.3 s → 내리막을 굴러 막대 위 자리로 0.6 s → 받침이 평균으로 미끄러지고 퍼짐 괄호가 벌어지고 s÷√n 자 눈금이 생김 0.4 s → 수레가 x_t로 0.3 s → 구슬이 칸으로 떨어짐 0.2 s(그때 counts·draws·out·판독값 갱신). 표본은 다음 뽑기까지 막대에 남는다.
- **100번**(2 s): 100번을 한꺼번에 셈. 그중 30개 구슬이 2 s에 걸쳐 각자의 칸으로 떨어지는 모습만 보이고, 끝에 칸 높이를 맞춘다. 막대에는 마지막 표본. draws + 100이 MAX_DRAWS를 넘으면 먼저 비운다.
- **표본 크기 바꾸기**: 칸을 비우고(draws 0), 막대를 비우고, 곡선을 df = n−1로.
- **비우기**: 칸만 비운다.
- **동시에 일어나는 일**: 움직이는 중 표본 크기·비우기 → 진행 중인 움직임을 끊고 바로 적용. 움직이는 중 "한 번" → 하나만 줄 세움(이미 줄 섰으면 무시). 움직이는 중 "100번" → 지금 것을 끝낸 뒤 시작. 투어는 조작하면 멈추고 마지막 조작 8 s 뒤 처음부터.
- **투어**: [3개 → 한 번 ×2 → 100번 ×5 → 4 s 머묾] → [30개 → 한 번 → 100번 ×5 → 4 s] → [5개 → 한 번 → 100번 ×5 → 4 s] → 반복. 각 걸음은 앞 움직임이 끝난 뒤.
- 화면 밖이면 멈춤, reduced motion이면 투어 없이 즉시 상태. aria-pressed는 지금 n과 맞춘다.
- 휴대폰: 끌기가 없으니 무대는 `touch-action: pan-y` 그대로.

## 8. 본문 (4단계)
절: 왜 필요한가 / 어떻게 움직이나 — 표본 뽑는 기계 / 꼬리가 두꺼운 까닭 / 표본이 커지면 / 왜 이렇게 생겼나 / 이 그림에 대하여. 사실은 §9에서만. 그림의 부품 이름(모집단 상자, 저울 막대, 표본 평균 받침, 퍼짐 s, s÷√n 자, 구슬 칸, t-곡선, 정규 곡선)으로 쓴다. 셈은 §9-12의 예처럼 손으로 따라 할 수 있는 산수만(수식 블록은 쓰지 않는다). 역사·발견한 사람·연도·종류 표·출처 목록은 쓰지 않는다. 링크: [[t-test|t-검정]], [[normal-distribution|정규 분포]], [[p-value|p값]] 가운데 자연스러운 곳에 한두 개.

## 9. 사실표 (출처는 싣지 않는다)
1. t는 (표본 평균 − 참 평균) ÷ (s ÷ √n)이다. s는 표본에서 잰 퍼짐(표준 편차)이고 n은 표본 크기다. 모집단이 정규 분포이고 모집단의 퍼짐을 모를 때 쓴다. 자유도는 n − 1이다.
2. 평균 n개는 값 하나보다 덜 흔들린다. 그 흔들림은 √n분의 1로 준다. 그래서 퍼짐을 √n으로 나눈 "평균의 흔들림"(s ÷ √n, 표준 오차)으로 벗어남을 재면 어떤 실험이든 같은 자로 잴 수 있다.
3. 퍼짐을 n − 1로 나누는 까닭: 편차(각 값 − 평균)는 모두 더하면 0이라, n − 1개를 알면 마지막 하나는 정해진다. n으로 나누면 퍼짐을 늘 조금 작게 잰다.
4. 꼬리가 두꺼운 까닭: 평균이 우연히 멀리 떨어질 수도 있고, s가 우연히 아주 작게 재어질 수도 있다. 둘째 길이 t를 크게 만든다. 표본이 작을수록 이런 일이 잦다.
5. 표본 5개(자유도 4)일 때 s는 참 퍼짐보다 작게 재어지는 때가 약 59%, 절반보다 작게 재어지는 때가 약 9%다(자유도 9: 56%, 1.3%).
6. t-분포는 0을 가운데로 좌우 대칭인 종 모양이고, 정규 분포보다 가운데가 낮고 꼬리가 두껍다. 자유도가 커지면 정규 분포에 다가간다. 다른 모양이 아니라 같은 종이 꼬리만 두꺼운 것이다.
7. ±1.96 바깥의 넓이: 정규 5.0%, 자유도 29 6.0%, 9 8.2%, 4 12.2%, 2 18.9%.
8. 양쪽 5%를 남기는 경계(95%)는 자유도 2 4.303, 4 2.776, 9 2.262, 29 2.045, 정규 1.96이다.
9. "자유도 30이 넘으면 t ≈ 정규"는 대략 맞다(자유도 30에서 2.042, 1.96보다 약 4% 넓다). 하지만 컴퓨터는 늘 정확한 t를 셈하므로 바꿔 쓸 까닭이 없다. "n이 30이면 정규 분포 가정이 상관없다"는 다른 말이고 틀릴 수 있다(치우침과 튀는 값이 있으면).
10. 자유도 1의 t-분포는 꼬리가 너무 두꺼워 평균이 없다(이 그림의 가장 작은 표본은 3개, 자유도 2).
11. 퍼짐을 표본에서 재는 대가로 경계를 넓히면(자유도 4에서 1.96 대신 2.776) 잘못 놀라는 비율이 다시 정확히 5%가 된다. 두꺼운 꼬리는 적은 자료로 지나치게 확신하지 않게 막아 준다.
12. 손으로 따라 할 예: 라벨 500 g, 상자 다섯 개 498, 501, 495, 499, 497 g. 평균 2490 ÷ 5 = 498. 편차 0, +3, −3, +1, −1(합 0). 제곱 0, 9, 9, 1, 1(합 20). 20 ÷ 4 = 5, s = √5 ≈ 2.24. s ÷ √5 = 1. t = (498 − 500) ÷ 1 = −2.00, 자유도 4. 자유도 4의 경계 2.776보다 작다. 퍼짐을 알고 있는 셈 치고 정규 곡선(1.96)으로 보면 "놀랍다"고 잘못 말하게 된다.
13. t-분포를 쓰려면 값들이 서로 독립이고 모집단이 대략 정규 분포여야 한다. 튀는 값은 평균과 s를 함께 끌어 어떤 n에서도 결과를 흐린다. 먼저 자료를 그려 본다.
14. 낱말: 모집단, 표본, 표본 평균, 퍼짐(표준 편차) s, 평균의 흔들림 s ÷ √n(표준 오차), 자유도, t-분포, 정규 분포(종 모양 곡선), 꼬리.
15. 이 그림에 대하여 재료: 모집단은 평균 500 g, 퍼짐 3 g의 정규 분포다. 무게는 0.1 g 단위로 반올림했다. 칸은 t 0.5 너비이고 −4보다 작거나 4 이상인 값은 양 끝 칸에 모았다. 칸 높이는 비율이라 곡선과 같은 잣대다. 처음 1000번은 미리 뽑아 두었고 난수는 고정된 씨앗에서 나온다(새로 고침하면 같은 장면). 상자 속 공은 모집단의 모양을 39개로 줄여 보인 것이다.

## 10. 받아들임 기준 (1단계)
1. `npm run preview -- t-distribution/opus-subagent`, `CHROME_PATH=$(command -v chromium || command -v google-chrome-stable) npm run check -- t-distribution/opus-subagent` 두 테마 line ends 0, `npm run build`, `npm run check:provenance`.
2. 스크린샷(900 px, 두 테마)과 4배 크롭을 직접 보고: 모집단 상자의 공 7줄(1·4·9·11·9·4·1), 막대 위 공 5개(498, 501, 495, 499, 497 — 498·499·497은 10 mm 안이라 층이 생김), 표본 평균 받침이 498 눈금, 퍼짐 괄호가 495.8…500.2, s÷√n 자가 500에서 498까지 15 mm 눈금 둘과 "t −2.00", 칸 높이가 §3의 counts와 맞음(가운데 9·10번이 가장 높고 약 110 mm), t-곡선(df 4)과 정규 곡선(점선)이 칸 위에 겹침, ±1.96 선과 바깥 바탕, 판독값 "n 5 · 1000번 · 바깥 13%".
3. 버튼으로 3개·30개를 즉시 그려(애니메이션 없이, run(n, 1000, SEED)로 채운 장면) 판독값 "바깥 19%"·"바깥 6%"와 곡선이 바뀌는지.
4. 보고: 바꾼 파일(git status), 설계와 다르게 한 점, 설계에 대한 관찰(`out/t-distribution/report.md`). 질문이 있으면 보고 맨 위에.

## 11. 1b 고침 (1단계 질문과 검증에서, 조정자)
질문 8개는 모두 설계서의 빈틈이었다(설계자 실수). 답:
1. **공 쌓기**: 규칙은 그대로(같은 층 8 mm 안이면 위로). §10-2의 "498·499·497이 쌓임"은 틀렸다 — 15 mm/g에서 1 g 차이는 겹치지 않는다. 대신 아래 4의 공 크기로 바꾼다.
2. **내리막**: 공은 상자 위에서 퍼 올려 내려보낸다. 홈통은 상자 오른쪽 위 구멍(x −140, z 244)에서 막대 왼쪽 끝(x −110, z 206)으로 **내려간다**. 상자 오른쪽 위에 작은 국자(퍼 올리는 팔) 하나 — 2단계에서 공을 떠 올리는 데 쓴다.
3. **상자 높이**: 상자 윗변을 z 266으로(판 윗변 270).
4. **표본 공**: 반지름 r = (n ≥ 30 ? 3 : 4), 층 간격과 쌓는 거리 모두 2r(중심 z = 206 + 2r·층, "같은 층 2r 안이면 위로"). 조정자가 model로 셈한 최악(씨앗 1–500): n 30은 7층(꼭대기 z 251), n 3·5는 2층. 처음의 반지름 5·10 mm로는 n 30이 8층(z 274, 판 밖)까지 갔다.
5. **퍼짐 괄호**: z 258 그대로(4로 더미가 낮아짐).
6. **받침 쐐기**: 꼭짓점 z 198, 밑변 z 192(높이 6) — 눈금 숫자(z 186)를 가리지 않게.
7. **±1.96 바깥 바탕**: 판 인쇄(y 0)가 아니라 칸 앞면과 같은 깊이(y 14)의 엷은 유리 띠로(맞춰 읽는 것은 같은 깊이). 지금보다 훨씬 엷게 — 칸 막대(꼬리의 작은 막대)가 바탕보다 먼저 보여야 한다. 꼬리 칸 막대는 가운데 칸과 같은 색 그대로.
8. **채움 높이 상한**: h = min(비율/BIN·K, 125). 잘린 칸은 윗면에 작은 위쪽 화살표(▲) 표시. 비운 직후 몇 번만 뽑으면 그렇게 된다.
9. **"바깥(±1.96)" 라벨**: 지금처럼 그 구역 안 글자 + 후광으로 둔다(지시선 없음 허용). **정규 곡선 지시선이 ±1.96 점선을 지나는 것**은 허용한다 — 점선은 부품이 아니라 안내선이다.
10. **표본 크기 버튼(2단계 포함)**: 1단계처럼 `run(n, 1000, SEED)`로 **다시 채운다**(비우지 않는다). 막대에는 n 5면 EXAMPLE, 3·30이면 run의 last. 투어의 "3개/30개/5개" 걸음도 같다. 칸이 채워지는 모습은 "비우기" 뒤 "한 번"·"100번"으로 본다. §7의 "표본 크기 바꾸기: 칸을 비우고"는 이것으로 바꾼다. 투어는 [3개 → 비우기 → 한 번 ×2 → 100번 ×5 → 4 s] → [30개 → 4 s → 비우기 → 한 번 → 100번 ×5 → 4 s] → [5개 → 4 s] → 반복.
11. 1단계에서 정한 것(난수 흐름 재생, 칸 바닥판, 레일 끝 막이, 고정색, 곡선 테두리, 라벨 후광, 제목 대문자 끄기)은 그대로 둔다.

## 12. 본문 짜임 다시 (사용자 지적: 배경과 맥락을 끝까지 읽게 — §8을 이것으로 바꾼다)
`docs/concept.md`의 6부 예외 절(물음 → 태어난 문제 → 그림으로 답 → 지금의 쓰임 → 다음 물음)을 따른다. 절과 쓸 사실(§9·§13 번호):

1. (첫 문단, 제목 없이 lead 다음) **물음과 걸린 것**: "라벨에 500 g이라고 적힌 상자 다섯 개를 재 보니 평균 498 g. 라벨이 거짓이라고 말해도 될까?" 답은 미룬다 — "이 물음에 흔히 쓰던 방법은 '그렇다'고 답한다. 그런데 틀렸다." §9-12.
2. **양조장의 문제** — 이 개념이 태어난 문제를 이야기로. §13-1, 2, 3, 4, 5. 연도·생애 연표는 쓰지 않는다("100여 년 전" 정도). "학생이었다"고 쓰지 않는다.
3. **어떻게 움직이나 — 표본 뽑는 기계**: 그림을 따라. §9-1, 2, 14. 카드 실험과 이어 준다("기계가 하는 일이 바로 카드 실험이다" §13-4).
4. **꼬리가 두꺼운 까닭**: §9-4, 5, 6, 7. 버튼 3개·30개와 판독값 "바깥"으로 확인하게.
5. **표본이 커지면**: §9-6, 8, 9, §13-8(여론 조사).
6. **왜 이렇게 생겼나**: §9-2, 3, 11, 13.
7. **지금 어디에 쓰이나**: §13-6, 7, 8 가운데 두세 가지.
8. **처음 물음으로**: 498 g 예로 매듭(§9-12): 정규 곡선이면 "놀랍다"(1.96보다 큼), t-분포(자유도 4, 2.776)로는 "우연히도 흔하다". 마지막 문장은 다음 물음 — "그렇다면 '놀랍다'의 경계는 누가, 어떻게 정할까?" → [[t-test|t-검정]].
9. **이 그림에 대하여**: §9-15.
분량은 지금 다른 문서보다 길어도 된다(이야기 절 몫). 문장은 짧고 쉽게.

## 13. 사실표 더하기 — 배경과 맥락 (출처는 싣지 않는다)
1. t-분포를 처음 실용으로 쓴 사람은 아일랜드 더블린의 기네스 양조장에서 일하던 화학자이자 양조 기술자 윌리엄 고셋이다. 그는 보리를 기르는 밭, 엿기름과 홉, 실험 양조를 다뤘는데, 실험 양조는 한 번에 하루가 걸려 표본을 많이 모을 수 없었다(그 자신의 말).
2. 그때 흔히 쓰던 방법은 표본에서 잰 퍼짐을 참 퍼짐인 것처럼 놓고 정규 곡선 표를 읽는 것이었다. 고셋은 실험 수가 적으면 그 퍼짐 자체가 믿을 수 없어 판단이 "아주 잘못될 수 있다"고 썼다. 많은 생물·농업 실험이 그렇게 몇 번밖에 되풀이할 수 없었다.
3. 그는 표본이 작을 때 쓸 표를 만들었다(표본 10개까지). 첫 논문의 예는 수면제 시험(환자 10명)과 보리 시험이었고 양조장 자료는 싣지 않았다.
4. 셈으로 풀기 전에 손으로 시험했다: 범죄자 3,000명의 키와 왼손 가운뎃손가락 길이를 카드 3,000장에 적어 잘 섞은 뒤, 뽑힌 차례대로 4장씩 묶어 표본 750개를 만들고 각 표본의 값을 셈했다. 통계에서 가장 이른 모의실험 가운데 하나다(첫 번째는 아니다). 이 그림의 기계가 하는 일이 바로 이것이다(4장씩이면 자유도 3).
5. 논문은 본명 대신 "스튜던트(Student)"라는 이름으로 냈다. 양조장에는 화학자의 논문 발표를 막는 규칙이 있었고, 고셋은 이 결과가 다른 양조장에 쓸모없다고 설득해 가명으로 내도록 허락받았다고 전한다. 회사는 알고 허락했다. "학생"이었던 것이 아니다. — 가명의 정확한 까닭은 설이 갈리므로 "전한다"로 쓰고, "영업 비밀이 새서"라고 단정하지 않는다.
6. 지금 쓰는 t라는 이름과 꼴은 나중에 통계학자 로널드 피셔가 다듬었다. (본문에는 한 줄이면 충분, 연도 없이.)
7. 오늘날 쓰임: 엑셀(T.TEST), R(t.test), 파이썬(SciPy) 같은 도구에 기본으로 들어 있다. 새 공정이나 새 방법이 지금 것보다 나은지 견줄 때 쓴다(미국 표준 기관의 안내서는 두 나라 자동차의 연비를 견주는 예를 든다). 온라인 서비스가 두 화면을 견주는 실험(A/B 시험)에도 쓴다. 고셋의 방법은 공업 품질 관리에 쓰인 첫 검정 가운데 하나로 꼽힌다.
8. 표본이 크면 t와 정규 곡선의 차이는 사라진다: 1,000명 남짓한 여론 조사에서 95% 경계는 t 1.962, 정규 1.960이다. t-분포가 차이를 만드는 곳은 표본이 작을 때다.
9. 물음 거리(셈 확인함): 측정한 퍼짐의 두 배만큼 벗어난 차이는 정규 곡선으로는 우연이 약 4.6%(드물다), 표본 10개(자유도 9)면 약 7.7%, 표본 4개(자유도 3)면 약 14%(일곱 번에 한 번)로 흔하다.
10. 쓰지 않을 말: "스튜던트는 학생이었다", "기네스는 모든 발표를 막았다", "영업 비밀이 새서 규칙이 생겼다", "고셋이 처음부터 무에서 만들었다"(같은 곡선을 다른 길로 먼저 얻은 사람들이 있었다), "첫 모의실험", "고셋이 t라고 불렀다"(처음에는 z였다).

## 14. 2단계 질문의 답 (조정자)
1. **한 번이 칸을 비우지 않게**: `MAX_DRAWS`를 5000으로(model.mjs의 그 한 줄만 바꾼다 — 조정자 결정). 칸이 5000을 넘을 때만 먼저 비운다. 판독값 가장 긴 꼴 "n 30 · 5000번 · 바깥 19%"(22자).
2. **투어의 3개 걸음**: [3개 → 4 s → 비우기 → 한 번 ×2 → 100번 ×5 → 4 s] → [30개 → 4 s → 비우기 → 한 번 → 100번 ×5 → 4 s] → [5개 → 4 s] → 반복.
3. 줄 세우기 해석(한 번 하나, 100번 하나까지)은 맞다.
4. 국자는 지금처럼(살짝 기울며 공이 밝아지고 구멍에서 나온다) 둔다.
