# 최소 검증 시나리오 — 전 파이프라인을 통과하되 샷 2~3개

2026-08-24 · 상태: 실측 진행 중

## ① 왜 만드나

프롬프트 분석을 하려는데 기록 분류가 엉망이면 소용이 없다. 그런데 직전 판
(6쪽·4,148자)은 11씬·shot_extract 81샷이 나와 한 바퀴에 10시간이 걸렸다.
분류나 프롬프트를 고칠 때마다 다시 돌릴 수가 없다.

→ **84스텝 전 구간을 실제로 통과하되 샷은 2~3개인 최소 시나리오**가 먼저 필요하다.

## ② 무엇이 범위인가 — 「전 구간」의 정의

`if_*` 조건은 거의 전부 **settings 플래그**로 갈린다(`applicability.py`).
실외·도면 경로는 시나리오 내용이 아니라 `.env` 가 켠다.

**플래그는 한 줄도 건드리지 않는다**(사용자 지시 2026-08-24). 지금 프로덕션
설정 그대로 두고, 시나리오가 통제할 수 있는 것만 통제한다:

| 시나리오가 정하는 것 | 무엇이 걸리나 |
|---|---|
| 씬 수 | scene_summary·beat_extract·shot_extract·scene_director 호출 수 |
| 샷 수 | scene_image_pipeline (가장 비싼 자리) |
| 실내 배경 유무 | `floor_plan_*` 7스텝의 일감 |
| 실외 배경 유무 | `outdoor_*` 6스텝의 일감 |
| 의식 없는 인물 | `character_state_variant` (직전 판 일감 0) |
| 의상 | `composite_image_gen` (`if_has_outlooks`) |

**도달 불가로 확정한 것** — 플래그가 꺼져 있어 시나리오로 어쩔 수 없다:
`floor_plan_semantic_readback` · `floor_plan_light_sidecar` · `dwelling_zone_map`
· `bg_space_partition` · `shot_projection_card` · `space_set_bg`.
앞의 셋은 `floor_plan_prompt_version ∈ {6,7}` 을 요구하는데 현재 `10` 이라,
플래그를 켜도 안 돈다. 직전 판에도 안 돌았다.

## ③ 시나리오 구성

`artifact/20260824_minimal_e2e_scenario/골목끝.txt` → 같은 이름 `.pdf` (2쪽)

3씬 · 약 900자:

1. `#1. 정비소 안 – 저녁` — 실내. 민수(작업복)·연희(우비). 공구 상자·자전거·손전등.
2. `#2. 갈래길 – 저녁` — 실외, 네 갈래 사거리. 노인(외투)이 의식 없이 누워 있다.
3. `#3. 정비소 안 – 밤` — 실내 복귀. 같은 배경을 두 씬이 공유한다.

인물 3 · 배경 2(실내 1·실외 1) · 소품 3 · 의상 3벌 · 의식 없는 인물 1.

**검열 회피** — 노인은 넘어져 의식을 잃은 것으로만 쓴다. 피·상처·폭력 묘사
없음. 직전 판에서 변환이 검열에 막혀 스텝이 안 닫힌 사고가 있었다.

## ④ ★세그먼테이션이 이 시나리오를 어떻게 자르는가 (실측)

`segment_rule.choose_rule` 의 순위는 **①C7(헤딩 줄에 글자가 있는 비율)
②매치 수**다. C1~C7 은 어휘를 안 읽으므로, **짧은 줄을 전부 헤딩으로 잡는
규칙이 C1~C7 을 다 통과하면서 매치 수로 정답을 이긴다.**

첫 초안(2씬·꺾쇠 머리말·화자 줄 별도)으로 실측한 결과:

| 후보 | 판정 | 매치 | C7 |
|---|---|---|---|
| `^#\d+\.\s+.*$` (정답) | 통과 | 3 | 1.00 |
| `^[^\s\d][^\n]{0,14}$` (짧은 줄 전부) | 통과 | **11** | 1.00 |

→ **짧은 줄 규칙이 이겼다.** 씬 11개 중 8개가 화자 줄(`연희`)과 짧은
지문 줄(`불빛이 번진다.`)이었다. 개수도 경계도 조용히 틀린다.

**고친 방법** — 계약으로는 못 막으므로 원고에서 없앤다:
- 대사를 `이름: 대사` 한 줄로 합친다 (화자 줄 소멸)
- 모든 줄을 20자 이상으로 맞춘다 (지문 접힘 끝줄 포함)
- 꺾쇠 머리말(`<로그라인>` 등)·`FADE IN/OUT` 제거, 머리말은 한 문단으로

**고친 뒤 실측**: 15자 미만 줄은 **씬 헤딩 3개뿐**. 위험 후보 6개 중
어느 것도 다른 경계를 못 찍는다 — 위험 규칙조차 정답과 **같은 3개 경계**를
찍으므로 어느 쪽이 이겨도 결과가 같다. 승자 = 정답 규칙, 씬 3개.

측정 도구: `scratchpad/check_segmentation.py` (LLM 없이 계약만 돌린다 — 공짜).

## ⑤ 샷 수를 어떻게 2~3개로 두는가

`shot_selection` 은 씬당 `max(1, min(절대상한, 샷수//2))` 를 고른다.
씬에 샷이 1개면 LLM 을 안 부르고 자동 통과하므로, **씬당 샷 2개 이상**이어야
선별 경로도 검증된다.

직전 판 실측이 **56자당 1샷**(4,558자 → 81샷)이었으므로 씬당 150~250자면
씬당 2~3샷이 나오고, 절반으로 잘려 **총 3샷**이 된다.

★샷 수는 LLM 이 정한다. 첫 주행에서 빗나가면 씬 길이를 줄여 다시 쓴다 —
그래서 이미지 스텝 전에 `shot_extract` 까지만 돌려 먼저 잰다.

## ⑥ 알려진 위험

- **lane 마커 방향 검사** — 실외를 갈래길로 잡았으므로(사용자 선택) 직전 판에서
  샷 전체를 막은 그 검사를 만날 가능성이 높다
  ([[project-lane-marker-wedge-drawing-failure]]). 만나면 거기서 멈추고 보고한다.
- **text_cleanup 이 원고를 다시 만진다** — 세그먼테이션은 정리본을 본다.
  정리본에서 짧은 줄이 새로 생기면 ④의 방어가 무너질 수 있다. 실물로 확인해야 한다.

## ⑦ 산출물

- 시나리오: `artifact/20260824_minimal_e2e_scenario/골목끝.{txt,pdf}`
- 빌더: `scratchpad/make_scenario_pdf.py` (생성 후 프로덕션 추출기로 되읽어 대조)
- 계약 시험: `scratchpad/check_segmentation.py`
- 생성·주행: `scratchpad/minimal_e2e_create.py` · `minimal_e2e_runner.py`
