# Prompt Hygiene v1 Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Active prompt 안 시나리오 leak + over-specific example 6 row 을 generic placeholder 로 교체 (3 module / 5 unique site / `t2i_visual_converter.py` path bump 1 곳).

**Architecture:** prompt_loader 의 file fallback latest 동작 활용 — `scene_extractor_v2` / `t2i_review` 는 새 version dir 만 생성하면 자동 active. `t2i_visual_converter` 만 hardcoded Path 우회 — 새 dir + Python source path string bump 의무. P-1 orphan 분리, t2i_review classifier behavior 4 region byte-unchanged.

**Tech Stack:** prompts/_base/<module>/<version>/ dir 구조, Python prompt_loader (`backend/app/modules/prompt_loader.py`), bash verification (`find` / `diff` / `grep`).

**Spec:** `docs/superpowers/specs/2026-05-15-prompt-hygiene-v1-spec.md`

**Acceptance summary** (자세는 spec §5):
1. Full-pack copy (stem 누락 0)
2. P-6 unchanged guard (4 region diff 0)
3. Residue grep active new dirs only (0 hits)
4. Active source verification (load_prompt + PROMPT_DIR)
5. Codex fix direction 정합

---

## File Structure

### Files to create

- `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/system.md` (P-2/P-3 fix)
- `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/turn_scene_detail.md` (P-3b/P-4 fix)
- `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/turn0_context.md` (unchanged copy)
- `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/turn1_split_long.md` (unchanged copy)
- `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/scene_detail_schema.json` (unchanged copy)
- `prompts/_base/t2i_visual_converter/v4/system.md` (P-5 fix)
- `prompts/_base/t2i_review/4.<TIMESTAMP>/scene_system.md` (P-6 fix, line 45-78 만)
- `prompts/_base/t2i_review/4.<TIMESTAMP>/entity_system.md` (unchanged copy)
- `prompts/_base/t2i_review/4.<TIMESTAMP>/entity_schema.json` (unchanged copy)
- `prompts/_base/t2i_review/4.<TIMESTAMP>/scene_schema.json` (unchanged copy)

### Files to modify

- `backend/app/modules/t2i_visual_converter.py:9-12` — `PROMPT_DIR = ... / "v3"` → `"v4"`

### Files to verify (no change)

- `backend/app/modules/prompt_loader.py` — DB-first / file-fallback 동작 (재read 의무 0, spec §2 인용)
- `backend/app/modules/pipeline/t2i_review.py:451` — `target.replace()` 계약 (unchanged guard 의 reason)

### TIMESTAMP

본 plan 의 `<TIMESTAMP>` placeholder = 14자 `YYYYMMDDHHmm` 형식 (기존 dir 명명 패턴 `17.202604101200` 따름). Task 1 실행 시점에 결정 — 예: `18.202605151200`. **plan 안에서는 placeholder 유지**, implementation 시 단일 timestamp 사용 (3 module 동일하지 않아도 OK, 단 각 module 안 새 dir 은 1개).

---

## Task 0: Residue Grep Baseline

**Goal:** Hygiene v1 적용 전 active old dirs 안 leak keyword hit count 기록. Task 4 사후 측정 비교용.

**Files:**
- 측정 대상: `prompts/_base/scene_extractor_v2/17.202604101200/` + `prompts/_base/t2i_visual_converter/v3/` + `prompts/_base/t2i_review/3.202605121200/`
- Output: `/tmp/hygiene-v1-baseline.txt` (임시, commit 안 함)

**No commit** — 측정 task only.

- [ ] **Step 1: Active old dirs 의 residue grep baseline 측정**

Run:
```bash
cd /Users/manta/Documents/Projects/TheRoad-I1
KEYWORDS="은성|ZRBB|동녘|강의원|캡슐속|청록색|투명 벽|compact room|wet floor|shared bench|Figure A|Figure B|Korean police|Joseon|tiled-roof"

{
  echo "=== scene_extractor_v2/17.202604101200/ ==="
  grep -rn -E "$KEYWORDS" prompts/_base/scene_extractor_v2/17.202604101200/ || echo "(no hits)"
  echo "=== t2i_visual_converter/v3/ ==="
  grep -rn -E "$KEYWORDS" prompts/_base/t2i_visual_converter/v3/ || echo "(no hits)"
  echo "=== t2i_review/3.202605121200/ ==="
  grep -rn -E "$KEYWORDS" prompts/_base/t2i_review/3.202605121200/ || echo "(no hits)"
} | tee /tmp/hygiene-v1-baseline.txt
```

**Expected**: 6 lines hits 기록. 다음 6 line 예상:
- `scene_extractor_v2/.../system.md:60` 동녘/강의원
- `scene_extractor_v2/.../system.md:63` 캡슐속
- `scene_extractor_v2/.../turn_scene_detail.md:108` 캡슐속
- `scene_extractor_v2/.../turn_scene_detail.md:83-85` Korean police / Joseon / tiled-roof
- `t2i_visual_converter/v3/system.md:19` 청록색 + 투명 벽
- `t2i_review/.../scene_system.md:45-78` compact room / wet floor / shared bench / Figure A / Figure B

baseline 결과를 정확히 기록 후 Task 1 진입.

---

## Task 1: Module 2 (`scene_extractor_v2`) — 새 dir + 4 fix

**Goal:** `scene_extractor_v2/18.<TIMESTAMP>/` 새 dir + full-pack copy + P-2/P-3/P-3b/P-4 fix.

**Files:**
- Create dir: `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/`
- Create files (full-pack copy from `17.202604101200/`):
  - `system.md` (P-2 / P-3 fix)
  - `turn_scene_detail.md` (P-3b / P-4 fix)
  - `turn0_context.md` (unchanged)
  - `turn1_split_long.md` (unchanged)
  - `scene_detail_schema.json` (unchanged)

- [ ] **Step 1: 새 dir create + full-pack copy**

Run (TIMESTAMP 결정 후 실제 dir 이름 사용 — 예 `18.202605151200`):
```bash
TS=$(date +%Y%m%d%H%M)
NEWDIR="prompts/_base/scene_extractor_v2/18.${TS}"
mkdir -p "$NEWDIR"
cp -p prompts/_base/scene_extractor_v2/17.202604101200/*.md "$NEWDIR/"
cp -p prompts/_base/scene_extractor_v2/17.202604101200/*.json "$NEWDIR/"
echo "Created: $NEWDIR"
ls -la "$NEWDIR/"
```

**Expected**: 5 files (`system.md`, `turn_scene_detail.md`, `turn0_context.md`, `turn1_split_long.md`, `scene_detail_schema.json`).

- [ ] **Step 2: P-2 fix — `system.md:60` 빙의/원격조종 예시**

Edit `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/system.md`:

Find:
```
예: "동녘(강의원)" → 동녘의 몸만 보이고, 강의원은 다른 곳에 있으므로 강의원 제외
```

Replace with:
```
예: "<visible_body_name>(<remote_identity_name>)" → visible_body 만 현장에 있고, remote_identity 는 다른 곳에 있으므로 remote_identity 제외. 본 분류 기준은 visual_world_rules.rules[] 의 rule_type=possession 을 따른다.
```

- [ ] **Step 3: P-3 fix — `system.md:63` 컨테이너 수식어 예시**

Edit `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/system.md`:

Find:
```
- **수식어로만 등장하는 소품**: "캡슐속 남자들" → 캡슐이 이 장소에 없으면 제외
```

Replace with:
```
- **수식어로만 등장하는 소품**: "<container descriptor> 안의 인물들" → container 가 이 장소에 없으면 제외
```

- [ ] **Step 4: P-3b fix — `turn_scene_detail.md:108` 컨테이너 + 헬기 예시**

Edit `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/turn_scene_detail.md`:

Find:
```
- 예: "캡슐속 남자들"이 헬기에 타고 있다면 → 캡슐은 헬기에 없으므로 제외
```

Replace with:
```
- 예: "<container descriptor> 안의 인물들"이 <transport vehicle>에 타고 있다면 → container 는 transport vehicle 에 없으므로 제외
```

- [ ] **Step 5: P-4 fix — `turn_scene_detail.md:83-85` Korean/Joseon hard-prime**

Edit `prompts/_base/scene_extractor_v2/18.<TIMESTAMP>/turn_scene_detail.md`:

Find (multi-line, line 83-85):
```
한국 배경이면 "Korean police officer", "Korean-style apartment", "Korean convenience store"
조선시대면 "Joseon-era nobleman", "tiled-roof wooden structure"
```

Replace with:
```
시대/지역 cue 가 시나리오에 있으면 그 cue 를 보존하여 표현 (`<region-derived demonym> police officer`, `<region-style apartment>`, `<region-style convenience store>`, `<era-derived noble role>`, `<era-appropriate roofed wooden structure>` 형식). 문화 cue 제거 X, generic placeholder 만.
```

- [ ] **Step 6: Full-pack count verify**

Run:
```bash
test "$(find prompts/_base/scene_extractor_v2/18.${TS}/ -maxdepth 1 -type f | wc -l)" -eq 5 \
  && echo "PASS: 5 files" \
  || echo "FAIL: expected 5"
```

**Expected**: `PASS: 5 files`.

- [ ] **Step 7: Active source verify — `load_prompt`**

Run:
```bash
PYTHONPATH=backend .venv/bin/python -c "
from app.modules.prompt_loader import load_prompt
print(load_prompt('scene_extractor_v2', 'system')[:200])
"
```

**Expected**: 새 `18.<TIMESTAMP>/system.md` content prefix 가 출력 (P-2 placeholder 가 포함되어 있어야 함 — "동녘(강의원)" 없음).

Run:
```bash
PYTHONPATH=backend .venv/bin/python -c "
from app.modules.prompt_loader import load_prompt
print(load_prompt('scene_extractor_v2', 'turn_scene_detail')[:200])
"
```

**Expected**: 새 `18.<TIMESTAMP>/turn_scene_detail.md` content prefix 가 출력 (P-3b/P-4 placeholder 가 포함).

- [ ] **Step 8: Residue grep — 새 dir hits 0**

Run:
```bash
KEYWORDS="은성|ZRBB|동녘|강의원|캡슐속|청록색|투명 벽|compact room|wet floor|shared bench|Figure A|Figure B|Korean police|Joseon|tiled-roof"
hits=$(grep -rn -E "$KEYWORDS" prompts/_base/scene_extractor_v2/18.${TS}/ | wc -l)
test "$hits" -eq 0 && echo "PASS: 0 hits" || echo "FAIL: $hits hits remaining"
```

**Expected**: `PASS: 0 hits`.

- [ ] **Step 9: Commit**

```bash
git add prompts/_base/scene_extractor_v2/18.${TS}/
git commit -m "$(cat <<'EOF'
feat(prompt-hygiene-v1): scene_extractor_v2 18.<TIMESTAMP> — P-2/P-3/P-3b/P-4 fix

Module 2 (scene_extractor_v2) 새 version dir — full-pack copy + 4 fix
(P-2 빙의/원격조종 / P-3 컨테이너 / P-3b 컨테이너+헬기 / P-4 Korean/Joseon).
file fallback latest = 새 dir, code 변경 0.

acceptance §5.1 (5 files), §5.3 (residue 0), §5.4 (load_prompt new dir
prefix), §5.5 (Codex P0-2/P0-3/P1-1 fix direction 정합).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 2: Module 3 (`t2i_visual_converter`) — 새 v4 + P-5 + path bump

**Goal:** `t2i_visual_converter/v4/` 새 dir + full-pack copy + P-5 fix + Python source path bump.

**Files:**
- Create dir: `prompts/_base/t2i_visual_converter/v4/`
- Create file (full-pack copy from `v3/`): `system.md` (P-5 fix)
- Modify: `backend/app/modules/t2i_visual_converter.py:9-12`

- [ ] **Step 1: 새 v4 dir create + full-pack copy**

Run:
```bash
NEWDIR="prompts/_base/t2i_visual_converter/v4"
mkdir -p "$NEWDIR"
cp -p prompts/_base/t2i_visual_converter/v3/system.md "$NEWDIR/"
echo "Created: $NEWDIR"
ls -la "$NEWDIR/"
```

**Expected**: 1 file (`system.md`).

- [ ] **Step 2: P-5 fix — `system.md:19` 청록색 sci-fi 예시**

Edit `prompts/_base/t2i_visual_converter/v4/system.md`:

Find:
```
예시: "[주인공]이 투명 벽 너머로 남자를 올려다본다, 청록색 발광, 미디엄 숏"
```

Replace with:
```
예시: "[primary character] looks toward [secondary visible target], <lighting cue>, <shot scale>"
```

- [ ] **Step 3: `t2i_visual_converter.py:9-12` path string bump**

Edit `backend/app/modules/t2i_visual_converter.py`:

Find (line 9-12, exact context):
```python
PROMPT_DIR = PROMPTS_BASE / "t2i_visual_converter" / "v3"
```

Replace with:
```python
PROMPT_DIR = PROMPTS_BASE / "t2i_visual_converter" / "v4"
```

- [ ] **Step 4: Full-pack count verify**

Run:
```bash
test "$(find prompts/_base/t2i_visual_converter/v4/ -maxdepth 1 -type f | wc -l)" -eq 1 \
  && echo "PASS: 1 file" \
  || echo "FAIL: expected 1"
```

**Expected**: `PASS: 1 file`.

- [ ] **Step 5: Active source verify — `PROMPT_DIR` path bump 확인**

Run:
```bash
PYTHONPATH=backend .venv/bin/python -c "
from app.modules.t2i_visual_converter import PROMPT_DIR
print(PROMPT_DIR)
"
```

**Expected**: `.../prompts/_base/t2i_visual_converter/v4` 출력 (path bump 정상 적용 시).

- [ ] **Step 6: Active source verify — system.md content prefix**

Run:
```bash
PYTHONPATH=backend .venv/bin/python -c "
from pathlib import Path
from app.modules.t2i_visual_converter import PROMPT_DIR
print((PROMPT_DIR / 'system.md').read_text()[:200])
"
```

**Expected**: 새 v4/system.md content prefix 가 출력 (P-5 placeholder 가 포함되어 있어야 — "청록색 발광" 없음).

- [ ] **Step 7: Residue grep — 새 dir hits 0**

Run:
```bash
KEYWORDS="은성|ZRBB|동녘|강의원|캡슐속|청록색|투명 벽|compact room|wet floor|shared bench|Figure A|Figure B|Korean police|Joseon|tiled-roof"
hits=$(grep -rn -E "$KEYWORDS" prompts/_base/t2i_visual_converter/v4/ | wc -l)
test "$hits" -eq 0 && echo "PASS: 0 hits" || echo "FAIL: $hits hits remaining"
```

**Expected**: `PASS: 0 hits`.

- [ ] **Step 8: Commit**

```bash
git add prompts/_base/t2i_visual_converter/v4/ backend/app/modules/t2i_visual_converter.py
git commit -m "$(cat <<'EOF'
feat(prompt-hygiene-v1): t2i_visual_converter v4 — P-5 fix + path bump

Module 3 (t2i_visual_converter) 새 v4 dir — full-pack copy + 1 fix (P-5
청록색 sci-fi 예시) + Python source path string bump (v3 → v4).
hardcoded Path bypass — path bump 의무 (file fallback 0).

acceptance §5.1 (1 file), §5.3 (residue 0), §5.4 (PROMPT_DIR 정상 출력),
§5.5 (Codex P1-2 fix direction 정합).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 3: Module 4 (`t2i_review`) — 새 dir + P-6 fix + unchanged guard

**Goal:** `t2i_review/4.<TIMESTAMP>/` 새 dir + full-pack copy + P-6 fix (scene_system.md:45-78 만) + 4 region byte-unchanged guard.

**Files:**
- Create dir: `prompts/_base/t2i_review/4.<TIMESTAMP>/`
- Create files (full-pack copy from `3.202605121200/`):
  - `scene_system.md` (P-6 fix, line 45-78 만)
  - `entity_system.md` (unchanged)
  - `entity_schema.json` (unchanged)
  - `scene_schema.json` (unchanged)

- [ ] **Step 1: 새 dir create + full-pack copy**

Run:
```bash
TS=$(date +%Y%m%d%H%M)
NEWDIR="prompts/_base/t2i_review/4.${TS}"
mkdir -p "$NEWDIR"
cp -p prompts/_base/t2i_review/3.202605121200/*.md "$NEWDIR/"
cp -p prompts/_base/t2i_review/3.202605121200/*.json "$NEWDIR/"
echo "Created: $NEWDIR"
ls -la "$NEWDIR/"
```

**Expected**: 4 files (`scene_system.md`, `entity_system.md`, `entity_schema.json`, `scene_schema.json`).

- [ ] **Step 2: P-6 fix — `scene_system.md:45-78` 3 example blocks**

Edit `prompts/_base/t2i_review/4.<TIMESTAMP>/scene_system.md`:

**Block 1 (line 45-47)** — `compact room` / `existing tabletop`:

Find (exact lines from `3.202605121200/scene_system.md:45-47`):
```
- close_framing_existing_ref:
  - 발견: close-up 샷에서 인물 뒤에 compact room 의 the existing tabletop 이 그대로 보이게 묘사함.
  - target/suggestion: target 안에 the existing tabletop 처럼 reference 표면이 보이는 표현. suggestion 은 close-framing 으로 인물 윤곽 / 의상 / 손 / 얼굴 영역만 남도록 변경.
```

Replace with:
```
- close_framing_existing_ref:
  - 발견: close-up 샷에서 인물 뒤에 <existing background object> 가 그대로 보이게 묘사함.
  - target/suggestion: target 안에 <existing background object> 처럼 reference 표면이 보이는 표현. suggestion 은 close-framing 으로 인물 윤곽 / 의상 / 손 / 얼굴 영역만 남도록 변경.
```

**Block 2 (line 61-63)** — `wet floor planks visible behind subject's hands`:

Find:
```
- physical_inconsistency:
  - 발견: close-framing 인데 인물 손 뒤로 wet floor planks visible behind subject's hands 같이 광각 디테일이 보임.
  - target/suggestion: target 안 광각 디테일 표현. suggestion 은 close-framing 의 self-contained 표현 (foreground 인물 한정).
```

Replace with:
```
- physical_inconsistency:
  - 발견: close-framing 인데 인물 손 뒤로 <frame-edge surface> visible behind subject's hands 같이 광각 디테일이 보임.
  - target/suggestion: target 안 광각 디테일 표현. suggestion 은 close-framing 의 self-contained 표현 (foreground 인물 한정).
```

**Block 3 (line 76-78 만 — line 65-74 unchanged guard region 의 example/keyword 는 보존)** — `the bench in the left background` / `the same bench they both occupy` / `the shared bench`:

Find (actual source from `3.202605121200/scene_system.md:76-78`):
```
#### 예시 (synthetic placeholder)
- target: `C01O01 in [outfit] sits hunched on the bench in the left background at a three-quarter angle from the left, eyes fixed on a small object`
- suggestion: `C01O01 in [outfit] sits hunched at the left of the same bench they both occupy at a three-quarter angle from the left, eyes fixed on the small object being offered across the shared bench`
```

Replace with:
```
#### 예시 (synthetic placeholder)
- target: `<character_id> in [outfit] sits hunched on <support surface descriptor> in the left background at a three-quarter angle from the left, eyes fixed on <small object descriptor>`
- suggestion: `<character_id> in [outfit] sits hunched at the left of the same <shared support surface descriptor> they both occupy at a three-quarter angle from the left, eyes fixed on the small object being offered across the <shared support surface descriptor>`
```

**Note**: implementation 시 `3.202605121200/scene_system.md` 의 line 45-47, 61-63, **76-78** 정확히 read 후 placeholder 교체. 핵심 = `compact room` / `existing tabletop` / `wet floor planks` / `the bench in the left background` / `the same bench they both occupy` / `the shared bench` (line 45-47/61-63/76-78 안) 모두 generic placeholder.

**중요 — Unchanged 의무 (line 65-74 unchanged guard region 안)**: `Figure A` / `Figure B` (line 69) + `shared bench/shared table/the same X they both occupy` (line 74) 는 classifier instruction (검출 패턴 + target/suggestion 작성 방식) 의 의도된 example/keyword — **절대 변경 X**. 본 keyword 들이 fix-target line 76-78 의 같은 phrase 와 일치하지만, fix-target range 안 의 의도된 leak 만 placeholder 화.

- [ ] **Step 3: P-6 unchanged guard — 4 region byte/text-level diff 0**

Run:
```bash
OLD=prompts/_base/t2i_review/3.202605121200/scene_system.md
NEW=prompts/_base/t2i_review/4.${TS}/scene_system.md
diff <(sed -n '31,43p;49,59p;65,74p;87,90p' "$OLD") \
     <(sed -n '31,43p;49,59p;65,74p;87,90p' "$NEW")
echo "diff exit code: $?"
```

**Expected**: empty diff output + exit code 0 (no diff). 만약 diff 가 출력되면 FAIL — line 31-43 / 49-59 / 65-74 / 87-90 변경 발생 (classifier behavior 위반).

- [ ] **Step 4: Full-pack count verify**

Run:
```bash
test "$(find prompts/_base/t2i_review/4.${TS}/ -maxdepth 1 -type f | wc -l)" -eq 4 \
  && echo "PASS: 4 files" \
  || echo "FAIL: expected 4"
```

**Expected**: `PASS: 4 files`.

- [ ] **Step 5: Active source verify — `load_prompt`**

Run:
```bash
PYTHONPATH=backend .venv/bin/python -c "
from app.modules.prompt_loader import load_prompt
print(load_prompt('t2i_review', 'scene_system')[:200])
"
```

**Expected**: 새 `4.<TIMESTAMP>/scene_system.md` content prefix 가 출력.

- [ ] **Step 6: Residue grep — fix-target range only (line 45-47 / 61-63 / 76-78)**

t2i_review 는 unchanged guard region (line 65-74) 안에 의도된 classifier example/keyword (Figure A/B + shared bench/shared table) 가 존재. residue grep 은 **fix-target range only** — line 45-47 + 61-63 + 76-78.

Run:
```bash
NEW=prompts/_base/t2i_review/4.${TS}/scene_system.md
KEYWORDS_FIX_TARGET="compact room|wet floor|shared bench|Figure A|Figure B"
hits=$(sed -n '45,47p;61,63p;76,78p' "$NEW" | grep -n -E "$KEYWORDS_FIX_TARGET" | wc -l | tr -d ' ')
test "$hits" -eq 0 && echo "PASS: 0 hits in fix-target range" || echo "FAIL: $hits hits in fix-target range"
```

**Expected**: `PASS: 0 hits in fix-target range`. (line 65-74 unchanged guard region 의 hit 는 의도된 classifier example — 검증 대상 외.)

- [ ] **Step 7: Commit**

```bash
git add prompts/_base/t2i_review/4.${TS}/
git commit -m "$(cat <<'EOF'
feat(prompt-hygiene-v1): t2i_review 4.<TIMESTAMP> — P-6 fix (scene_system.md:45-78 만)

Module 4 (t2i_review) 새 version dir — full-pack copy + 1 fix (P-6 3
example blocks: compact room / wet floor planks / Figure A/B / shared
bench → generic placeholder). file fallback latest = 새 dir, code 변경 0.

P-6 unchanged guard — line 31-43 (검출 패턴) / 49-59 (issue type) /
65-74 (target/suggestion 작성 방식) / 87-90 (target/suggestion 규칙) 모두
byte/text-level unchanged (acceptance §5.2). t2i_review.py:451 의
target.replace() 계약 보존.

acceptance §5.1 (4 files), §5.2 (4 region diff 0), §5.3 (residue 0),
§5.4 (load_prompt new dir prefix), §5.5 (Codex P1-3 fix direction 정합).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 4: Final Verification + Completion

**Goal:** §5.3 residue grep 전체 검증 + §5.4 active source 전체 검증 + §5.5 Codex fix direction 정합 + §10 completion criteria.

**No new file create. Verification only.** Commit optional (plan-progress 기록).

- [ ] **Step 1: Residue grep — module 별 scope 분리**

`scene_extractor_v2` + `t2i_visual_converter` = full new-dir grep (의도된 unchanged region 없음 — 0 hits expected).
`t2i_review` = fix-target range only (line 45-47 / 61-63 / 76-78) — line 65-74 unchanged guard region 안 의도된 classifier example 보존 위해.

Run:
```bash
# 1. scene_extractor_v2 + t2i_visual_converter — full dir
KEYWORDS_FULL="은성|ZRBB|동녘|강의원|캡슐속|청록색|투명 벽|compact room|wet floor|Korean police|Joseon|tiled-roof"
for dir in prompts/_base/scene_extractor_v2/18.* prompts/_base/t2i_visual_converter/v4; do
  hits=$(grep -rn -E "$KEYWORDS_FULL" "$dir" 2>/dev/null | wc -l | tr -d ' ')
  echo "$dir: $hits hits"
done

# 2. t2i_review — fix-target range only
T2I_NEW=$(ls -d prompts/_base/t2i_review/4.* | head -1)/scene_system.md
KEYWORDS_T2I_FIX="compact room|wet floor|shared bench|Figure A|Figure B"
hits=$(sed -n '45,47p;61,63p;76,78p' "$T2I_NEW" | grep -n -E "$KEYWORDS_T2I_FIX" | wc -l | tr -d ' ')
echo "$T2I_NEW (fix-target range): $hits hits"
```

**Expected**: 모두 `0 hits`. (`t2i_review` 의 full-dir grep 시 line 69/74 의 의도된 example/keyword 가 hit 되지만 unchanged guard region — 검증 대상 외.)

- [ ] **Step 2: Active source verification — 4건**

Run:
```bash
echo "=== Module 2 scene_extractor_v2/system ==="
PYTHONPATH=backend .venv/bin/python -c "from app.modules.prompt_loader import load_prompt; print(load_prompt('scene_extractor_v2', 'system')[:200])"

echo "=== Module 2 scene_extractor_v2/turn_scene_detail ==="
PYTHONPATH=backend .venv/bin/python -c "from app.modules.prompt_loader import load_prompt; print(load_prompt('scene_extractor_v2', 'turn_scene_detail')[:200])"

echo "=== Module 3 t2i_visual_converter PROMPT_DIR ==="
PYTHONPATH=backend .venv/bin/python -c "from app.modules.t2i_visual_converter import PROMPT_DIR; print(PROMPT_DIR)"

echo "=== Module 4 t2i_review/scene_system ==="
PYTHONPATH=backend .venv/bin/python -c "from app.modules.prompt_loader import load_prompt; print(load_prompt('t2i_review', 'scene_system')[:200])"
```

**Expected**:
- Module 2 system → 새 18.<TIMESTAMP>/system.md prefix (P-2 placeholder 포함, "동녘" 없음)
- Module 2 turn_scene_detail → 새 18.<TIMESTAMP>/turn_scene_detail.md prefix (P-3b/P-4 placeholder 포함, "Korean police" 없음)
- Module 3 PROMPT_DIR → `.../t2i_visual_converter/v4`
- Module 4 scene_system → 새 4.<TIMESTAMP>/scene_system.md prefix

- [ ] **Step 3: P-6 unchanged guard 최종 확인**

Run:
```bash
OLD=prompts/_base/t2i_review/3.202605121200/scene_system.md
NEW=$(ls -d prompts/_base/t2i_review/4.* | head -1)/scene_system.md
diff <(sed -n '31,43p;49,59p;65,74p;87,90p' "$OLD") \
     <(sed -n '31,43p;49,59p;65,74p;87,90p' "$NEW")
echo "diff exit code: $?"
```

**Expected**: empty + exit code 0.

- [ ] **Step 4: Codex fix direction 정합 수동 review**

Spec §5.5 의 fix direction:
- **P-2 placeholder** = visual_world_rules `rule_type=possession` reference pointer 포함 → Step 2 의 P-2 fix text 에 "본 분류 기준은 visual_world_rules.rules[] 의 rule_type=possession 을 따른다." 포함 확인
- **P-4 placeholder** = region/era derivation cue 보존 → Step 5 의 P-4 fix text 에 `<region-derived demonym>` / `<era-derived noble role>` 패턴 포함 확인
- **P-6 placeholder** = abstract `<existing background object>` / `<frame-edge surface>` / `<shared support surface>` / `<foreground actor>` / `<background actor>` 사용 → Step 2 (Task 3) 의 P-6 fix text 에 5 placeholder 모두 사용 확인

수동 review 후 OK 명시.

- [ ] **Step 5: Completion criteria 체크리스트 확인**

Spec §10 의 10 criteria 모두 확인:
- [ ] 3 module 의 새 dir 모두 생성 + full-pack copy (Task 1/2/3 Step 1)
- [ ] 6 P-N fix 모두 적용 (Task 1 Step 2-5 / Task 2 Step 2 / Task 3 Step 2)
- [ ] P-6 unchanged guard 통과 (Task 3 Step 3 + Task 4 Step 3)
- [ ] Residue grep 0 hits in active new dirs (Task 1/2/3 + Task 4 Step 1)
- [ ] Active source verification 4건 통과 (Task 4 Step 2)
- [ ] Codex fix direction 정합 (Task 4 Step 4)
- [ ] Code change 1 곳만 (`t2i_visual_converter.py:9-12`)
- [ ] DB row 변경 0
- [ ] schema 변경 0
- [ ] 이전 version dir 보존 (삭제 0)

모두 PASS 시 Hygiene v1 완료.

- [ ] **Step 6: Final commit (optional)**

본 Task 4 = verification only — 새 commit 의무 없음. 단 verification log 를 commit 하려면:

```bash
echo "Hygiene v1 verification complete (Task 0~4)" > /tmp/hygiene-v1-verify.log
# 또는 commit 없이 종료
```

본 plan 의 final commit = Task 3 의 `t2i_review` commit (마지막). Task 4 는 verification gate only.

---

## Implementation Summary

| Task | Files affected | Code change | Commits |
|------|----------------|-------------|---------|
| 0 | none (baseline 측정) | 0 | 0 |
| 1 | `scene_extractor_v2/18.<TS>/` (5 files) | 0 | 1 |
| 2 | `t2i_visual_converter/v4/` (1 file) + `t2i_visual_converter.py:9-12` | 1 line | 1 |
| 3 | `t2i_review/4.<TS>/` (4 files) | 0 | 1 |
| 4 | verification only | 0 | 0 |
| **Total** | **10 prompt files create + 1 code line** | **1 line** | **3 commits** |

## Risk Mitigation

| Risk (spec §9) | Plan mitigation |
|----------------|-----------------|
| Stem 누락 (full-pack copy 미준수) | Task 1/2/3 Step 6 (full-pack count) + cp 명령에 `*.md` `*.json` glob 모두 포함 |
| t2i_review unchanged guard 위반 | Task 3 Step 3 + Task 4 Step 3 (4 region diff 0) |
| Path bump 누락 (module 3) | Task 2 Step 5 (`PROMPT_DIR` print 검증) |
| Residue grep scope 잘못 | Task 4 Step 1 (active new dirs only) |
| P-6 fix 가 line range 외 변경 | Task 3 Step 3 의 unchanged guard 가 4 region diff 0 검증 — 위반 시 FAIL |

## Out of Scope (사용자 명시, 본 plan 진행 중 절대 안 함)

- P-1 (`entity_extraction/v7/chunk_system.md:24`) — orphan, 별도 cleanup area
- `t2i_review/scene_system.md` 의 line 31-43 / 49-59 / 65-74 / 87-90 — classifier + target/suggestion 계약, unchanged 의무
- `t2i_review.py:383-454` 의 `.replace()` 치환 로직 — L-3 별도 area
- LLM-side classifier instruction redesign (L-1 ~ L-7)
- code-side regex / substring (#1 ~ #19)
- visual_world_rules SOT 일원화 (D-1 ~ D-5 + ADD-6 ~ ADD-11)
- framing_scale enum SOT (next first impl after Hygiene v1 closure)
- DB row override / production source verification
- entity_extractor_v2 prompt content (active path, leak 0 확인됨)
- schema 변경 (모든 stem 의 .json 은 full-pack copy 만)
- 이전 version dir 삭제

## Next After Plan Completion

- Hygiene v1 closure commit 후 audit `00-index.md` §8.1 의 (2) framing_scale enum SOT spec 진입.
- 별도 area carry: orphan cleanup (P-1) / visual_world_rules SOT 일원화 / shot_visibility drift-only / ref-contract phantom guard / representation_binding enum / t2i_review mutation redesign / scene_detail_owned_judge schema echo.
