---
title: Carry-D7d-1 — scene_detail v28 description align implementation plan (v1)
date: 2026-05-19
status: closed (W1 atomic `05af1d5` + W2 closure-docs wave; range review/push gate pending at W2 closure commit time, final pushed range/count external memory only)
spec_ref: docs/superpowers/specs/2026-05-19-carry-d7d-1-scene-detail-v28-description-align-v1-design.md (status draft, Codex APPROVED_FOR_PLAN after spec quality iter 1 + narrow re-review 1/2; status closed only at W2 closure-docs commit)
roadmap_ref: docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md §5.7 Area #7 Sub-area (e) Carry-D7d-1 resolution
prerequisites:
  - Spec v1 APPROVED_FOR_PLAN (Codex M5 verdict; status draft, closed only at W2 closure-docs commit).
  - Area #7d v1 closed (push `b9c610e`).
  - Area #7b v1 closed (push `e751e72`, scene_detail/27 4-point sync source).
non_supersedes:
  - Carry-A099 / Carry-A100 / Carry-P021 (Area #7a 정합 보존).
---

# Carry-D7d-1 — scene_detail v28 description align implementation plan (v1)

## 1. Purpose + Spec Reference

본 plan = Carry-D7d-1 spec (status draft, Codex APPROVED_FOR_PLAN; status closed only at W2 closure-docs commit) 의 W1 implementation + W2 closure docs wave 실행 contract. spec §1-§9 fully 참조 (본 plan 안 spec 본문 재기술 0, ambiguity 제거 위한 inline command 만 포함).

**Spec 참조 key index** (본 plan 작성 시 cross-reference, edit 0 의무):
- spec §1.2 In-scope = 3 그룹 (v28 prompt dir 2 file + 4-point sync code 3 anchor + 7 sync-required tests).
- spec §2 W0 evidence inventory (5 sub-section).
- spec §3 Sync Contract (12-site table) + §3.1 R2 nuance test_area_7b_no_drift.py SIBLING_INVENTORY semantic 전환.
- spec §4 W1 Implementation Contract (commit boundary + 6 pre-commit verify gate + targeted pytest + manual gate boundary).
- spec §5 W2 Closure Contract (5 repo-local docs + external memory + W2 pre-commit placeholder substitution gate + range review + push gate).
- spec §6 Test/Gate Contract (G1-G5).
- spec §7 Doctrine (4-Gate + NO VLM + TEMPLATE ONLY + 4 self-reference doctrine + Workflow).
- spec §8 Closure Boundary (Codex Q4 verbatim allowed claim + 5 forbidden claims + Carry-A099/A100/P021).
- spec §9 Closure (deferred to W2 closure-docs wave, in-place REPLACE template).

## 2. Plan Iter Trace

- **iter 0** (본 plan session, strategy 본 instance proposed + Codex MCP 의논): Codex spec narrow re-review 2 verdict `APPROVED_FOR_PLAN` 의 plan drafting guidance (M6) = "Continue plan v1 drafting in this same fresh session, as long as session usage remains moderate. Use a concise plan target, likely 450-650 lines, not Area #7d-scale. Re-discuss session health before W1 implementation atomic." 6 section structure + inline exact commands only where they remove ambiguity + test_area_7b_no_drift.py nuanced sibling semantic conversion 정확 보존 권고.
- **iter 1** (plan quality round, 본 plan 작성 후 Codex 의논): `NEEDS_REVISION_MINOR` (4 IMPORTANT + 3 MINOR + operational note — IMPORTANT 1 historical provenance preserve doctrine + IMPORTANT 2 11 files / 12 sync sites + IMPORTANT 3 Site 12 actual surface `scene_detail_v27_dir` fixture + IMPORTANT 4 W2 substitute step executable + MINOR 1 frontmatter spec_ref status + MINOR 2 anchor-based grep + MINOR 3 PASS count + operational note "bash polling loop 폐기").
- **iter 1 narrow re-review** (TEXT FIX 1/2 적용 후): `APPROVED_FOR_EXECUTION_WITH_NARROW_TEXT_FIXES` (TEXT FIX 1 §1 line 19 spec status drift + TEXT FIX 2 §3.5 commit body 4 integration test files).
- **W1 entry sanity**: `APPROVED_FOR_W1_ENTRY_THIS_SESSION` (preflight evidence 정합 + 4 hard guard — historical provenance preserve / R2 nuance / Site 12 fixture surface / no global v27 zero grep).
- **W1 per-wave**: `APPROVED_FOR_W2_ENTRY` + `CLOSE_HANDOFF_W2_FRESH` (W1 commit `05af1d5` 11 file diff + sha256 + Python imports + active v27-pattern grep clean + 127 pytest re-run PASS + provenance preserve verified).
- **W2 entry sanity**: `APPROVED_FOR_W2_ENTRY_THIS_SESSION_WITH_NARROW_GUARDS` (8 narrow guard 흡수 — 6 file scope + placeholder substitution gate + closure wording guards Carry spec/plan/roadmap/audit 03/Area #7d source spec all stale + W2 commit body explicit W1 hash + Carry plan frontmatter narrow + Carry spec §9 live content 12-subsection + pre-commit verification add-ons).
- **W2 per-wave + W1-W2 range review**: pending at W2 commit time.

## 3. W1 Implementation Atomic Wave

### 3.1 Pre-W1 Entry Sanity (Codex re-discuss + UTC resolution + git status hygiene)

**(W1.0.a) Codex re-discuss session health** (Codex R8 + M6 권고 정합 obligatory):
- W1 entry 직전 Codex MCP 의논 — session usage check + W1 commit risk re-confirm (prompt pack + core version anchors + 7 sync-required tests touch).
- Codex APPROVED_FOR_W1_ENTRY (또는 CLOSE_HANDOFF_W1_FRESH) verdict 후만 W1 진입.

**(W1.0.b) UTC timestamp resolution + new dir name**:
```bash
UTC=$(date -u +%Y%m%d%H%M)
NEW_DIR="prompts/_base/scene_detail/28.${UTC}"
echo "Carry-D7d-1 W1 NEW_DIR = $NEW_DIR"
# Expected: 28.202605XXXX 형식, 27.202605181937 보다 후행 (시간 단조 증가).
```

**(W1.0.c) git status hygiene**:
- `git status --short` 안 본 carry scope 외 file modification 0 verify.
- 본 carry scope 외 untracked file (예: `error.log`, `backend/db.sqlite`, `backend/tests/_audit_outputs/*`) = git add 대상 X 의무.
- Working branch = `main` (Codex push 시 origin main).

### 3.2 W1 File Operations (12 site, spec §3 table 정합)

#### 3.2.1 New v28 prompt dir (site 1-2)

```bash
mkdir -p "$NEW_DIR"
# Site 1: detail_schema.json modified narrow update (spec §3 row 1)
cp prompts/_base/scene_detail/27.202605181937/detail_schema.json "$NEW_DIR/detail_schema.json"
# 본문 안 `t2i_variations.items.properties.camera_effect.description` 정확 위치 narrow edit:
#   - old: "카메라 구도 + 색감 (필수)"
#   - new: "카메라 구도 + 색감 (필수, 시나리오 derivation; closed-list 강제 X)"
# Other JSON Schema field 변경 0 (type=string + required preserve).
# Site 2: system.md byte-identical copy (spec §3 row 2)
cp prompts/_base/scene_detail/27.202605181937/system.md "$NEW_DIR/system.md"
# sha256 match obligatory (spec §G2).
```

#### 3.2.2 4-point sync code (site 3-5, Codex IMPORTANT 1 historical provenance preserve)

**Provenance preservation doctrine** (Codex IMPORTANT 1): 기존 `Area #7b W3` historical comment 은 v27 생성의 역사적 근거이므로 **삭제 X / 보존 의무**. v28 bump 시 narrative comment 안 **append Carry-D7d-1 narrow sentence** (provenance chain stack preserve). "replace all Area #7b W3 comments" 금지.

- **Site 3** `detail_steps.py:106`:
  - old: `SCENE_DETAIL_PROMPT_VERSION = "27.202605181937"  # 2026-05-19 (Area #7b W3) — v27 prompt: ...`
  - new: `SCENE_DETAIL_PROMPT_VERSION = "28.${UTC}"  # 2026-05-19 (Area #7b W3) — v27 prompt: ... + Carry-D7d-1: v28 (description align with Area #7d fallback policy).` (Area #7b W3 historical comment 그대로 preserve + 끝에 Carry-D7d-1 narrow append).

- **Site 4** `version_registry.py:34`:
  - old: `"scene_detail_composer": "1.27.0", # 2026-05-19 — Area #7b W3: v27 prompt + schema_version 11 보존 ...`
  - new: `"scene_detail_composer": "1.28.0", # 2026-05-19 — Area #7b W3: v27 prompt + schema_version 11 보존 ... + Carry-D7d-1: v28 (description align with Area #7d fallback policy, schema_version 11 보존).` (historical preserve + append).
  - SCENE_DETAIL_SCHEMA_VERSION value 변경 0 (11 유지).

- **Site 5** `version_registry.py:126`:
  - old: `"prompt_dependency": "scene_detail/v27", # major suffix only — alignment test enforces ...`
  - new: `"prompt_dependency": "scene_detail/v28", # major suffix only — alignment test enforces ...` (line 126 inline comment preserve; suffix 만 substitute).
  - line 127 `updated_at` comment narrow append: `2026-05-19 — Area #7b W3 ... + Carry-D7d-1: v28 (description align with Area #7d fallback policy)` (historical preserve + append).

#### 3.2.3 7 sync-required tests (site 6-12, spec §3 table + §3.1 R2 nuance 정합)

**Provenance preservation doctrine** (Codex IMPORTANT 1, Site 6-9 적용): 기존 docstring/comment 안 `Area #7b W3` historical mention 보존 + Carry-D7d-1 narrow append (P2 권고 "all v27 active-version assertions/prose + append Carry-D7d-1 provenance"). 즉 active-version assertion + active-prose 만 v28 substitute, historical comment 는 preserve + append.

**Site 6** `test_prompt_versions.py` (211/213/216/221/222 5 site, spec amend 2 N-2 정합):
- line 211 comment: Area #7b W3 historical preserve + Carry-D7d-1 narrow append (예: ` + Carry-D7d-1: v27 → v28 description align`).
- line 213 assert: `SCENE_DETAIL_PROMPT_VERSION.startswith("27.")` → `startswith("28.")`.
- line 216 function name: `test_version_registry_scene_detail_composer_1_27_0` → `test_version_registry_scene_detail_composer_1_28_0`.
- line 221 comment: Area #7b W3 historical preserve + Carry-D7d-1 narrow append.
- line 222 assert: `MODULE_VERSIONS["scene_detail_composer"] == "1.27.0"` → `== "1.28.0"`.
- `SCENE_DETAIL_SCHEMA_VERSION == 11` assert (line 206) 유지.

**Site 7** `test_scene_detail_continuity_alignment.py` (file-level):
- 4-point sync 3 strict assert (line 75 `MODULE_VERSIONS == "1.27.0"` → `"1.28.0"` + line 111 `prompt_dependency == "scene_detail/v27"` → `"scene_detail/v28"` + 후속 active site).
- docstring line 13-18 active-version mention (예: `startswith("27.")` / `"1.27.0"` / `"scene_detail/v27"`) 모두 `28.` / `1.28.0` / `v28` substitute (active-prose only).
- 후속 v27 active prompt-version block (~line 129) + 후속 latest-dir checks 안 v27 → v28 substitute (active site only).
- historical narrative (`Area #7b W3 ...`) preserve + Carry-D7d-1 narrow append where applicable.

**Site 8** `test_scene_detail_spatial_alignment.py` (file-level, Site 7 와 평행 구조):
- 4-point sync 3 strict assert + 후속 active site (line 114 `scene_detail/v27` → `scene_detail/v28` + line 136/141 `startswith("27.")` → `startswith("28.")` + 후속 active v27 mention 모두).
- docstring line 13-21 안 active-version mention substitute.
- historical narrative preserve + Carry-D7d-1 narrow append where applicable.

**Site 9** `test_g4_5a_spatial_integration.py` (file-level):
- line 562-606 4-point sync verify block 안 active-version mention:
  - line 562 docstring: `v27 / 1.27.0 / scene_detail/v27` → `v28 / 1.28.0 / scene_detail/v28` (active-prose).
  - line 563-568 4 row comment active mention substitute.
  - line 583 path navigation: `27.<timestamp>` → `28.202605190927` (actual W1 UTC value).
  - line 592 assert: `startswith("27.")` → `startswith("28.")`.
  - line 599 assert: `MODULE_VERSIONS == "1.27.0"` → `"1.28.0"`.
  - line 606 assert: `prompt_dependency == "scene_detail/v27"` → `"scene_detail/v28"`.
- 후속 active site (예: line ~770 `current.startswith("27.")` config_hash check) → `"28."`.
- historical narrative (line 575 `Area #7b W3 (1.27.0 / v27, canonical VWR SOT reference clause)` 등) preserve + Carry-D7d-1 narrow append where applicable.

**Site 10** `test_area_7b_no_drift.py` (line 47/83/96, R2 nuanced SIBLING_INVENTORY semantic 전환, spec §3.1 정합 — Codex M6 권고 "preserve test_area_7b_no_drift.py nuanced sibling semantic conversion exactly"):
- **(a) line 47** `NEW_DIR_EXPECTED["scene_detail"]`: `"27."` → `"28."` simple substitute (C1 latest activation 의무).
- **(b) line 83** `SIBLING_INVENTORY` entry semantic 전환:
  - **old**: `("scene_detail", "27.", "26.202605181435"): ["detail_schema.json"]` (Area #7b W3 v26→v27 historical sibling — detail_schema.json byte-identical).
  - **new**: `("scene_detail", "28.", "27.202605181937"): ["system.md"]` (Carry-D7d-1 v27→v28 active sibling — **system.md** byte-identical; **detail_schema.json** = modified, sibling X).
  - v26→v27 historical sibling check (detail_schema.json) = active-latest no-drift canary scope 외 → drop (Codex R2 verbatim 권고). historical preservation 별도 carry 외 (Codex M2 confirmed acceptable, no new Carry-D7d-1b).
- **(c) line 96** `MODIFIED_FILES`: `("scene_detail", "27.", "system.md")` → `("scene_detail", "28.", "system.md")` substitute (v28 system.md 가 byte-identical copy 이므로 canonical VWR clause membership 의무 preserve, C6 정합).

**Site 11** `test_area_5_residue_gate.py` (172-185, reclassified):
- line 179 `_latest_prompt_dir("prompts/_base/scene_detail/27.*/")` → `"prompts/_base/scene_detail/28.*/"`.
- line 172 function name `test_active_prompt_residue_scene_detail_v27_no_closed_phrase_examples` → `_v28_*`.
- line 173 docstring `Item 7: scene_detail v27 active prompt — closed-list phrase example 0 hits.` → `v28`.
- line 177 prose `active prompt latest = v27 fresh canary scope` → `v28 fresh canary scope`.

**Site 12** `test_area_7b_residue_gate.py` (file-level, reclassified, Codex IMPORTANT 3 actual surface 정정):
- **(a) Fixture rename** line 87: `def scene_detail_v27_dir() -> Path:` → `def scene_detail_v28_dir() -> Path:` (fixture function name substitute, NOT `test_gate_1_8_*` — Codex IMPORTANT 3 정정).
- **(b) Helper call** line 88: `return _latest_active_dir("scene_detail", "27.")` → `"28."`.
- **(c) Caller updates** (fixture rename cascade):
  - line 206 `def test_gate_1_8_scene_detail_system_md_residue(scene_detail_v27_dir: Path) -> None:` → parameter `scene_detail_v28_dir: Path`.
  - line 208 `body = (scene_detail_v27_dir / "system.md").read_text(...)` → `scene_detail_v28_dir`.
  - line 235 tuple `("scene_detail_v27_dir", "system.md")` → `("scene_detail_v28_dir", "system.md")`.
  - line 315 `scene_detail_v27_dir: Path,` → `scene_detail_v28_dir: Path,`.
  - line 327 `(scene_detail_v27_dir, "system.md")` → `(scene_detail_v28_dir, "system.md")`.
- **(d) Prose updates** (active-latest references):
  - line 285 prose `latest dir (5.* / 3.* / 10.* / 12.* / 2.* / 27.* / 12.*)` → `... / 28.* / ...`.
  - line 295 dict literal `"scene_detail": "27."` → `"28."`.
- **(e) Function name** `test_gate_1_8_scene_detail_system_md_residue` (line 206) = NOT mandatory rename (clarity-only, optional). v28 substitute scope = fixture name + helper + caller + active-latest prose만.

#### 3.2.4 Boundary preserve (No edit obligatory)

- `prompts/_base/scene_detail/27.202605181937/` (archive preserve, 변경 0).
- `prompts/_base/scene_detail/28.202605190927/system.md` content (byte-identical copy, edit 0).
- `prompts/_base/scene_extractor_v2/20.202605190631/` (Area #7d fallback path, 변경 0).
- `backend/app/core/step_manifest.py` (verify-only, edit 0 unless mismatch).
- `backend/app/services/prompt_service.py` (Area #7d W2 closed, 변경 0).
- audit 02 (P-4 narrow cross-reference 추가 X + §11.2 untouched).
- Area #7a / #7b / #7c / #7d / #6 closure boundary preserve.

### 3.3 W1 Pre-Commit Verify Gates (6 check, spec §4.3 + manual gate boundary 정합)

**(a) UTC timestamp resolution + new dir name** (W1.0.b 정합):
```bash
[ -d "$NEW_DIR" ] && echo "OK new dir: $NEW_DIR" || { echo "FAIL new dir missing"; exit 1; }
```

**(b) New dir 2 file count**:
```bash
count=$(ls "$NEW_DIR" | wc -l | tr -d ' ')
[ "$count" -eq 2 ] || { echo "FAIL: file count $count != 2"; exit 1; }
ls "$NEW_DIR" | sort
# Expected: detail_schema.json + system.md
echo "OK 2 file exact in $NEW_DIR"
```

**(c) system.md sha256 byte-identical v27→v28**:
```bash
S27=$(shasum -a 256 prompts/_base/scene_detail/27.202605181937/system.md | cut -d' ' -f1)
S28=$(shasum -a 256 "$NEW_DIR/system.md" | cut -d' ' -f1)
[ "$S27" = "$S28" ] && echo "OK sha256 match system.md" || { echo "DRIFT: system.md sha mismatch v27=$S27 v28=$S28"; exit 1; }
```

**(d) Description exact match in v28 detail_schema.json** (spec §G1):
```bash
NEW_HIT=$(grep -cF '"카메라 구도 + 색감 (필수, 시나리오 derivation; closed-list 강제 X)"' "$NEW_DIR/detail_schema.json")
OLD_HIT=$(grep -cF '"카메라 구도 + 색감 (필수)"' "$NEW_DIR/detail_schema.json")
[ "$NEW_HIT" -ge 1 ] && [ "$OLD_HIT" -eq 0 ] && echo "OK description exact match (new=$NEW_HIT, old=$OLD_HIT)" \
  || { echo "FAIL description match (new=$NEW_HIT, old=$OLD_HIT)"; exit 1; }
```

**(e) 4-point sync grep** (site 3-5, Codex MINOR 2 anchor-based — assignment-line anchored to avoid comment false positive):
```bash
# Anchor-based ripgrep: assignment-line 시작 strict (^SCENE_..., quoted key + value pair)
rg -n "^SCENE_DETAIL_PROMPT_VERSION = \"28\\.${UTC}\"" backend/app/core/steps/detail_steps.py | wc -l | grep -q "^[[:space:]]*1$" \
  && rg -n '"scene_detail_composer": "1\.28\.0"' backend/app/core/version_registry.py | wc -l | grep -q "^[[:space:]]*1$" \
  && rg -n '"prompt_dependency": "scene_detail/v28"' backend/app/core/version_registry.py | wc -l | grep -q "^[[:space:]]*1$" \
  && echo "OK 4-point sync (3 anchor, anchored grep)" \
  || { echo "FAIL 4-point sync (anchored grep)"; exit 1; }
# Alternative: Python import + assert (assignment-line 확실, comment false positive 0)
cd backend && .venv/bin/python -c "
from app.core.steps.detail_steps import SCENE_DETAIL_PROMPT_VERSION
from app.core.version_registry import MODULE_VERSIONS, _MODULE_INFO
assert SCENE_DETAIL_PROMPT_VERSION == '28.${UTC}', f'site 3 drift: {SCENE_DETAIL_PROMPT_VERSION}'
assert MODULE_VERSIONS['scene_detail_composer'] == '1.28.0', f'site 4 drift: {MODULE_VERSIONS[\"scene_detail_composer\"]}'
assert _MODULE_INFO['scene_detail_composer']['prompt_dependency'] == 'scene_detail/v28', f'site 5 drift: {_MODULE_INFO[\"scene_detail_composer\"][\"prompt_dependency\"]}'
print('OK 4-point sync (Python assert, comment false positive 0)')
"
cd ..
```

**(f) STEP_MANIFEST verify-only** (R7 + Codex IMPORTANT 4, concrete dict access):
```bash
cd backend && .venv/bin/python -c "
from app.core.step_manifest import STEP_MANIFEST
from app.core.steps.detail_steps import SCENE_DETAIL_SCHEMA_VERSION
assert STEP_MANIFEST['scene_detail']['schema_version'] == SCENE_DETAIL_SCHEMA_VERSION == 11, (
    f'STEP_MANIFEST scene_detail schema_version drift: {STEP_MANIFEST[\"scene_detail\"][\"schema_version\"]} vs {SCENE_DETAIL_SCHEMA_VERSION}'
)
print('OK STEP_MANIFEST verify-only')
"
cd ..
```

**Manual gate boundary** (spec §4.3 정합): 본 (a)-(f) 6 check = manual pre-commit verification gates, repo pre-commit hooks (예: `ruff` / `prettier`) 와 별개. Hook output 이 본 manual gates 를 대체하지 않음.

### 3.4 W1 Targeted Pytest (7 sync-required tests, spec §4.4 정합)

```bash
cd backend
.venv/bin/pytest \
  tests/test_prompt_versions.py \
  tests/prompts/test_scene_detail_continuity_alignment.py \
  tests/prompts/test_scene_detail_spatial_alignment.py \
  tests/integration/test_g4_5a_spatial_integration.py \
  tests/integration/test_area_7b_no_drift.py \
  tests/integration/test_area_5_residue_gate.py \
  tests/integration/test_area_7b_residue_gate.py \
  -v --tb=short
cd ..
# Expected: ALL PASS (NO VLM + no live LLM + closed-world exact membership only).
```

### 3.5 W1 Path-Limited git add + Commit

**path-limited add scope** (12 site, 0 file out-of-scope):
```bash
git add \
  "$NEW_DIR/detail_schema.json" \
  "$NEW_DIR/system.md" \
  backend/app/core/steps/detail_steps.py \
  backend/app/core/version_registry.py \
  backend/tests/test_prompt_versions.py \
  backend/tests/prompts/test_scene_detail_continuity_alignment.py \
  backend/tests/prompts/test_scene_detail_spatial_alignment.py \
  backend/tests/integration/test_g4_5a_spatial_integration.py \
  backend/tests/integration/test_area_7b_no_drift.py \
  backend/tests/integration/test_area_5_residue_gate.py \
  backend/tests/integration/test_area_7b_residue_gate.py
git status --short
# Expected: 11 file staged / 12 sync sites (Codex IMPORTANT 2 정정 — 2 v28 file + 2 code anchor file + 7 test file = 11 files; site 5 (version_registry.py line 126) 와 site 4 (line 34) 가 same file 의 2 site).
# 0 out-of-scope.
```

**Commit message format** (spec §4.1 정합, Codex iter 권고 시 narrow update):
```
W1(carry-d7d-1-scene-detail-v28-description-align-v1): scene_detail v28 description align — 12 site sync atomic

- v28 prompt dir 2 file (28.202605190927/detail_schema.json modified + system.md byte-identical copy from v27)
- 4-point sync 3 anchor (detail_steps.py SCENE_DETAIL_PROMPT_VERSION + version_registry.py MODULE_VERSIONS + _MODULE_INFO prompt_dependency, schema_version 11 preserve)
- 7 sync-required tests (test_prompt_versions + 2 prompt test files + 4 integration test files, file-level scope, function/fixture rename + assert + comment narrow update)
- STEP_MANIFEST verify-only (no bump/edit unless mismatch — concrete dict access STEP_MANIFEST["scene_detail"]["schema_version"] == SCENE_DETAIL_SCHEMA_VERSION == 11)
- carrier shape preserve (camera_effect string + required), Area #7d fallback description policy alignment

Targeted pytest (Codex MINOR 3): `backend/.venv/bin/pytest backend/tests/test_prompt_versions.py backend/tests/prompts/test_scene_detail_continuity_alignment.py backend/tests/prompts/test_scene_detail_spatial_alignment.py backend/tests/integration/test_g4_5a_spatial_integration.py backend/tests/integration/test_area_7b_no_drift.py backend/tests/integration/test_area_5_residue_gate.py backend/tests/integration/test_area_7b_residue_gate.py -v --tb=short` — N tests, N PASS, 0 FAIL (W1 execution 시 실측 N 값 commit body 안 기록 의무).

Codex APPROVED_FOR_W1_ENTRY (W1 entry sanity round) + spec amend 2 narrow re-review APPROVED_FOR_PLAN + plan narrow re-review APPROVED_FOR_EXECUTION.

NO VLM. no live LLM. closed-world exact phrase membership only.
```

### 3.6 W1 Codex per-wave review

W1 commit 후 즉시 Codex per-wave review 의무 ([[feedback_codex_mcp_discussion_workflow]] 정합):
- Codex live verify: §3.2 12 site 정확 sync + §3.3 6 pre-commit gate 정확 통과 + §3.4 7 test ALL PASS evidence.
- Codex verdict 예상 = `APPROVED_FOR_W2_ENTRY` or `NEEDS_REVISION_NARROW` (narrow fix-up commit 가능, 별도 amend hash trace).
- `CLOSE_HANDOFF_W2_FRESH` verdict 시 session 종료 + W2 fresh session 진입.

## 4. W2 Closure Docs Atomic Wave

### 4.1 W2 File Operations (5 repo-local docs, spec §5.1 정합)

**path-limited git add scope (5 file)**:

#### 4.1.1 (a) 본 spec — frontmatter status + §9 in-place REPLACE
- frontmatter `status:` field rewrite: `draft (Codex spec iter pending; W1/W2 pending; push pending after APPROVED_FOR_PUSH, final pushed range/count external memory only)` → `closed (W1 atomic + W2 closure-docs wave; push gate pending at W2 closure commit time — Codex APPROVED_FOR_PUSH 후 즉시 push origin main, final pushed range/count = external memory only)`.
- §9 deferred closure section in-place REPLACE (heading `## 9. Closure (deferred to W2 closure-docs wave)` 이미 존재 → append X, 본문 substitute, Area #7d W4 함정 1 정합).
- §9.1-§9.12 12 sub-section live content 작성 (spec §9 template 정합, controller-substitute target 모두 substituted, design-time placeholder-free).

#### 4.1.2 (b) Roadmap §5.7 Sub-area (e) bullet narrow append
- File: `docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md`.
- §5.7 Sub-area (e) cinematography closed-list SOT dual-site bullet 안 narrow append: `Carry-D7d-1 resolved at W1 atomic + W2 closure-docs` (heading 변경 X, 기존 bullet text preserve).
- Sub-area (e) bullet 안 기존 `Carry post #7d = Carry-D7d-1 / ...` mention 안 `Carry-D7d-1` status update (`deferred` → `resolved`).

#### 4.1.3 (c) Audit 03 L-8 row narrow update
- File: `docs/visual-reliability-audit/2026-05-14-semantic-string-routing-debt-audit/03-llm-side-heuristic-audit.md`.
- L-8 row (cinematography closed-list SOT dual-site Area #7d) 안 narrow append: `Carry-D7d-1 resolved` (row 신설 X, content append narrow only).

#### 4.1.4 (d) Area #7d source spec narrow update (Codex R4)
- File: `docs/superpowers/specs/2026-05-19-area-7d-cinematography-sot-dual-site-v1-design.md`.
- §10.1 Carry-D7d-1 entry 안 status update: `deferred (medium cost — 4-point sync + pinned tests cascade 부담 회피)` → `resolved at Carry-D7d-1 W1 commit + W2 closure-docs` narrow update.
- §11.10 Carry Follow-up Post #7d row 1 (Carry-D7d-1) 안 status update: `Status: deferred` → `Status: resolved at Carry-D7d-1 W1 commit + W2 closure-docs` narrow update.

#### 4.1.5 (e) Area #7d source plan narrow update (Codex R4)
- File: `docs/superpowers/plans/2026-05-19-area-7d-cinematography-sot-dual-site-v1-implementation.md`.
- §10.1 Carry-D7d-1 row 안 status update narrow.
- §11.8 Carry Follow-up Post #7d row 1 안 status update narrow.

### 4.2 W2 Pre-Commit Placeholder Substitution Gate (spec §5.2 정합)

<!-- HISTORICAL AUDIT TRAIL / TEMPLATE ONLY: §4.2 W2 placeholder substitution gate description (historical — gate executed at W2 commit time `3334cbb`; interior `28.<UTC...>` placeholder mentions preserve as verbatim original substitution patterns; replacement gsub regex / awk marker-exclusion filter / grep pattern verbatim original W1 design-time wording — W2 fix-up 1 narrow `HISTORICAL_AUDIT_TRAIL_TEMPLATE_ONLY` marker wrap obligatory per Codex W2 per-wave NEEDS_REVISION_NARROW false-negative finding; future re-runs should use fixed-string `rg -n -F` over awk-filtered body, not `grep -cE` with literal `<` which BRE/ERE word-boundary may under-match). -->

**Rule** (Codex IMPORTANT 3 흡수): W2 closure commit 직전, repo-local closure docs (§4.1 (a)-(e) 5 file) 안 live `28.<UTC-timestamp>` / `28.<UTC>` / `28.<timestamp>` placeholders 모두 actual W1 dir name (예 `28.202605XXXX`) 으로 substitute. HISTORICAL AUDIT TRAIL / TEMPLATE ONLY marker block 안 placeholder = substitute X (marker 보존).

**Substitution mechanism** (Codex IMPORTANT 4 executable substitute step):
```bash
# W2 시 W1 commit 이미 존재 → W1 dir name 을 live filesystem 에서 resolve
W1_DIR_NAME=$(ls -1 prompts/_base/scene_detail/ | grep -E "^28\\." | sort | tail -n 1)
[ -n "$W1_DIR_NAME" ] || { echo "FAIL: W1 v28 dir missing in prompts/_base/scene_detail/"; exit 1; }
echo "W2 substitution target W1 dir = $W1_DIR_NAME"

# Substitution target: 6 closure docs (5 repo-local closure docs + Area #7d 2 source files)
CLOSURE_DOCS=(
  docs/superpowers/specs/2026-05-19-carry-d7d-1-scene-detail-v28-description-align-v1-design.md
  docs/superpowers/plans/2026-05-19-carry-d7d-1-scene-detail-v28-description-align-v1-implementation.md
  docs/superpowers/specs/2026-05-19-area-7d-cinematography-sot-dual-site-v1-design.md
  docs/superpowers/plans/2026-05-19-area-7d-cinematography-sot-dual-site-v1-implementation.md
  docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md
  docs/visual-reliability-audit/2026-05-14-semantic-string-routing-debt-audit/03-llm-side-heuristic-audit.md
)

# Per-file: temp-file + awk marker exclusion + gsub replacement + move-back
for f in "${CLOSURE_DOCS[@]}"; do
  [ -f "$f" ] || { echo "FAIL: closure doc missing: $f"; exit 1; }
  TMP="${f}.tmp.carry-d7d-1"
  awk -v repl="$W1_DIR_NAME" '
    /HISTORICAL AUDIT TRAIL.*TEMPLATE ONLY/{flag=1; print; next}
    /end TEMPLATE ONLY/{flag=0; print; next}
    {
      if (!flag) {
        gsub(/28\.<UTC-timestamp>/, repl)
        gsub(/28\.<UTC>/, repl)
        gsub(/28\.<timestamp>/, repl)
      }
      print
    }
  ' "$f" > "$TMP"
  mv "$TMP" "$f"
done
echo "OK W2 placeholder substitution (6 closure docs, marker block 보존)"
```

**Substitute order obligatory** (Codex IMPORTANT 4):
1. **Resolve W1 dir name** (`ls prompts/_base/scene_detail/ | grep "^28\\." | sort | tail -1`).
2. **Per-file temp-file + awk marker exclusion + gsub replacement + mv back** (위 bash block).
3. **Pre-Commit Verify** (substitute 후 verify, 아래 block).

**Pre-Commit Verify** (W2 gate, spec §5.2 executable marker-block exclusion helper 정합):
```bash
CLOSURE_DOCS=(
  docs/superpowers/specs/2026-05-19-carry-d7d-1-scene-detail-v28-description-align-v1-design.md
  docs/superpowers/plans/2026-05-19-carry-d7d-1-scene-detail-v28-description-align-v1-implementation.md
  docs/superpowers/specs/2026-05-19-area-7d-cinematography-sot-dual-site-v1-design.md
  docs/superpowers/plans/2026-05-19-area-7d-cinematography-sot-dual-site-v1-implementation.md
  docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md
  docs/visual-reliability-audit/2026-05-14-semantic-string-routing-debt-audit/03-llm-side-heuristic-audit.md
)
TOTAL_HITS=0
for f in "${CLOSURE_DOCS[@]}"; do
  [ -f "$f" ] || { echo "FAIL: closure doc missing: $f"; exit 1; }
  hits=$(awk '/HISTORICAL AUDIT TRAIL.*TEMPLATE ONLY/{flag=1; next} /end TEMPLATE ONLY/{flag=0; next} !flag' "$f" \
         | grep -cE "28\\.<UTC|28\\.<timestamp|28\\.<UTC-timestamp")
  TOTAL_HITS=$((TOTAL_HITS + hits))
done
[ "$TOTAL_HITS" -eq 0 ] && echo "OK W2 placeholder substitution gate (marker-excluded hit 0)" \
  || { echo "FAIL: placeholder residue $TOTAL_HITS hits in marker-excluded body"; exit 1; }
```

**Note** (Codex M3 implementation note): listed closure docs 가 W2 시점에 존재 의무 (W1 commit 시 본 plan + spec 이미 존재 + Area #7d source spec/plan 이미 존재 + roadmap/audit 03 이미 존재). 본 plan = W2 commit 시 path-limited add 의 일부. missing file 시 helper guard `[ -f "$f" ]` fail-fast (위 bash block 안 적용).

<!-- end TEMPLATE ONLY -->

### 4.3 W2 External Memory (non-git, git add 대상 X)

- `~/.claude/projects/-Users-manta-Documents-Projects-TheRoad-I1/memory/MEMORY.md` 안 본 carry index entry 추가 + Carry-D7d-1 next-session pointer entry 해소.
- `memory/session_20260519_carry_d7d_1_closure.md` 신설 (본 carry session memo, frontmatter + 본문 종합).
- Area #7d post-closure carry status update (next_session_area_7d_w4_execution.md 또는 별도 carry 진행 memo 안 Carry-D7d-1 해소 status reference).
- **git add 대상 X** (Codex IMPORTANT 2 정합 — external memory 는 non-git).

### 4.4 W2 Path-Limited git add + Commit

```bash
git add \
  docs/superpowers/specs/2026-05-19-carry-d7d-1-scene-detail-v28-description-align-v1-design.md \
  docs/superpowers/plans/2026-05-19-carry-d7d-1-scene-detail-v28-description-align-v1-implementation.md \
  docs/superpowers/specs/2026-05-19-area-7d-cinematography-sot-dual-site-v1-design.md \
  docs/superpowers/plans/2026-05-19-area-7d-cinematography-sot-dual-site-v1-implementation.md \
  docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md \
  docs/visual-reliability-audit/2026-05-14-semantic-string-routing-debt-audit/03-llm-side-heuristic-audit.md
git status --short
# Expected: 6 file staged (5 repo-local closure docs + 1 본 plan), 0 out-of-scope.
# Note: 본 plan = W1 commit 시 untracked 였을 가능성 — W2 add 시 함께 staged.
```

**Commit message format** (W2 closure docs atomic, spec §5 정합):
```
W2(carry-d7d-1-scene-detail-v28-description-align-v1): closure docs atomic

- 본 spec frontmatter status closed + §9 closure section in-place REPLACE (12 sub-section live content)
- roadmap §5.7 Sub-area (e) Carry-D7d-1 resolved narrow append
- audit 03 L-8 Carry-D7d-1 resolved narrow update
- Area #7d source spec §10.1 + §11.10 Carry-D7d-1 status deferred → resolved (Codex R4)
- Area #7d source plan §10.1 + §11.8 Carry-D7d-1 status deferred → resolved (Codex R4)
- 본 plan first commit (drafting closure)

W1 commit reference: <W1 hash> (path-limited git add scope = 12 site sync atomic).
W2 pre-commit placeholder substitution gate PASS (marker-excluded hit 0, executable awk + grep -c chain).
Final pushed range/count = external memory only.

Codex iter trace post W1: W1 per-wave APPROVED + W1-W2 range review APPROVED_FOR_PUSH (or APPROVED_WITH_NARROW_FIX_UP).

NO VLM. closed-world exact phrase membership only.
```

### 4.5 W2 Range Review + Push Gate

**Codex range review (W1+W2)** 의무 ([[feedback_codex_mcp_discussion_workflow]] 정합):
- live verify: W1 commit `<hash>` 12 site sync evidence + W2 commit `<hash>` 5 closure docs scope + 4-point sync evidence (current SCENE_DETAIL_PROMPT_VERSION + MODULE_VERSIONS + prompt_dependency live grep) + targeted pytest 7 file ALL PASS + W2 placeholder substitution gate evidence.
- Codex verdict 예상 = `APPROVED_FOR_PUSH` (직접 push) or `NEEDS_REVISION_MINOR` (narrow fix-up commit 1+ + 재 range review).

**Push gate** (Codex APPROVED_FOR_PUSH 후 즉시, 사용자 ask 0):
```bash
git push origin main
# Final pushed range external memory: <pre-W1 HEAD>..<W2 HEAD> = N commits (W1 + W2 + N-2 narrow fix-up if any).
```

- 사용자 ask 0 ([[feedback_push_no_user_ask]] 정합).
- /clear ONLY post-push session reset ([[feedback_session_reset_clear_not_exit]]).

## 5. Doctrine (4-Gate + NO VLM + closed-world + standalone token global ban + TEMPLATE ONLY + Legacy escape, spec §7 정합)

본 plan = spec §7 doctrine 정합 inline 재반복 X (spec 참조). 본 plan 안 doctrine 적용 정합 의무 site:

- **4-Gate Boundary Doctrine** ([[feedback_llm_based_judgment]]): W1 12 site 안 semantic regex 0 (description literal substitute + plain string membership only) / closed-list full-phrase 정합 / carrier string shape preserve / silent default 추가 0.
- **NO VLM hard constraint** ([[feedback_no_vlm_dependency]]): W1 targeted pytest + W2 closure docs 안 VLM 사용 0.
- **standalone token global ban 엄금**: 어떤 W1 test 안에도 single token (`low angle` / `warm amber` / `bird's eye` 등) global ban 0.
- **closed-world exact phrase membership only**: §3.3 (d) `grep -cF` (fixed string) + spec §G1 정합.
- **TEMPLATE ONLY + W3/W4 self-reference + Substitution self-referential bug + Legacy 본 commit retroactive escape** ([[session_20260519_area_7c_v1_closure]] + [[session_20260519_area_7d_v1_closure]] 함정 1): W2 closure docs body 안 self-reference placeholder slug 사용 X + explicit hash literal + "final pushed range/count = external memory only" suffix 의무 + 본 plan §3.5 W1 commit message 본문 안 self-reference hash mention 0.
- **Workflow doctrine** ([[feedback_codex_mcp_discussion_workflow]] / [[feedback_codex_mcp_claude_mcp_response_trigger]] / [[feedback_subagent_model_opus]] / [[feedback_push_no_user_ask]] / [[feedback_session_50pct_codex_close_check]] / [[feedback_session_reset_clear_not_exit]]): 본 plan 매 step Codex first 의무.

## 6. References + Carry Follow-up

### 6.1 References (spec §8.4 정합 inline)
- Spec final: `docs/superpowers/specs/2026-05-19-carry-d7d-1-scene-detail-v28-description-align-v1-design.md` (status closed post-W2, Codex APPROVED_FOR_PLAN after iter 1 + narrow re-review 1/2).
- Area #7d v1 closure commit `b9c610e` ([[session_20260519_area_7d_v1_closure]]).
- Area #7b W3 commit `5060254` (scene_detail/27 4-point sync source).
- Area #7d W1 commit `6cc4933` (fallback target wording source).
- Roadmap, audit 03, Area #7d source spec/plan (W2 closure docs targets).
- Memory references (spec §8.4 inline list 정합).

### 6.2 Carry Follow-up Post Carry-D7d-1 (spec §8.3 정합)
1. **Carry-A099** — VWR system.md director_notes prose redesign V8+.
2. **Carry-A100** — VWR system.md t2i_context demonym redesign V8+.
3. **Carry-P021** — scene_consistency 7 enumeration broad.

### 6.3 Closure Boundary (spec §8.1-§8.2 정합)
- Allowed claim (Codex Q4 verbatim): `scene_detail primary camera_effect description aligned with Area #7d fallback description policy`.
- Forbidden claims (Codex R5 5 항목): full dual-owner remediation / field-shape migration complete / cinematography closed-list 완전 폐기 (scene_detail) / structured cinematography object introduced / VLM/LLM validation.
