---
title: Carry-A099 — VWR system.md director_notes prose redesign V8+ implementation plan (v1)
date: 2026-05-19
status: closed (Codex plan iter rounds APPROVED — plan v1 + amend 1 + amend 2 narrow + N-5 narrow edit; W1/W2 atomic + W2 fix-up 1 narrow + W3 closure-docs all executed; final pushed range/count external memory only after push)
spec_ref: docs/superpowers/specs/2026-05-19-carry-a099-vwr-system-md-director-notes-prose-redesign-v1-design.md (status closed at W3 closure-docs commit)
roadmap_ref: docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md §5.7 Area #7 carry follow-up
prerequisites:
  - Spec v1 APPROVED_FOR_PLAN (Codex spec amend 1 narrow re-review verdict; status draft, closed only at W3 closure-docs commit).
  - Area #7a v1 closed (push `d0410eb`) — VWR producer SOT boundary preserve.
  - Area #7b v1 closed (push `e751e72`) — Carry-A099 boundary preserve.
  - Area #7c v1 closed (push `62aa2ef`) — abstraction pattern reference.
  - Area #7d v1 closed (push `b9c610e`) — dual-site cascade pattern reference.
  - Carry-D7d-1 v1 closed (push `05d5265`) — TEMPLATE ONLY fix-up 1 doctrine source.
non_supersedes:
  - Carry-A100 (VWR system.md t2i_context demonym redesign V8+).
  - Carry-P021 (scene_consistency 7 enumeration broad, source unresolved).
---

# Carry-A099 — VWR system.md director_notes prose redesign V8+ implementation plan (v1)

## 1. Purpose + Spec Reference

본 plan = Carry-A099 spec (status draft, Codex APPROVED_FOR_PLAN after spec quality iter 1 + amend 1 narrow re-review; status closed only at W3 closure-docs commit) 의 W1 producer + W2 integrated test + W3 closure docs wave 실행 contract. spec §1-§10 fully 참조 (본 plan 안 spec 본문 재기술 0, ambiguity 제거 위한 inline command 만 포함).

**Spec 참조 key index** (본 plan 작성 시 cross-reference, edit 0 의무):
- spec §1.2 In-scope = v8 prompt pack 2 file + prompt-pack activation + STEP_MANIFEST verify + W2 integrated test + W3 closure docs.
- spec §1.3 Out-of-scope = 7 narrow guard 모두 명시.
- spec §2 W0 evidence inventory (W0.1 inventory memo reference).
- spec §3 Sync Contract (4-row table, prompt-pack activation + STEP_MANIFEST verify only).
- spec §4 W1 Implementation Contract (commit boundary + 6 pre-commit verify gate + targeted pytest).
- spec §5 W2 Integrated Test Contract (5 Gate G1-G7 verify gate).
- spec §6 W3 Closure Docs Contract (6 repo-local docs + external memory + range review + push gate).
- spec §7 Test/Gate Contract (G1-G7 verify gate + standalone token global ban X + test anchor preservation).
- spec §8 Doctrine (4-Gate + NO VLM + closed-world + TEMPLATE ONLY).
- spec §9 Closure Boundary (allowed/forbidden claim + Carry priority + references).
- spec §10 Closure (deferred to W3 closure-docs wave, in-place REPLACE template).

## 2. Plan Iter Trace

- **iter 0** (본 plan session, strategy 본 instance proposed + Codex MCP 의논): Codex spec amend 1 narrow re-review verdict `APPROVED_FOR_PLAN` + plan drafting guidance (W1/W2/W3 3-wave + executable commands + prompt_loader API shape 확인 의무 + CONTINUE_THIS_SESSION).
- **iter 1** (plan quality round, 본 plan 작성 후 Codex 의논): pending.

## 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 plan drafting guidance 정합):
- W1 entry 직전 Codex MCP 의논 — session usage check + W1 commit risk re-confirm (prompt-pack producer atomic, no code/test edit).
- 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/visual_world_rules/8.${UTC}"
export UTC NEW_DIR  # subprocess (Python -c source/path proof gate §3.3(f)) 안 inherit 의무, Codex plan amend 1 N-4 정합
echo "Carry-A099 W1 NEW_DIR = $NEW_DIR"
# Expected: 8.202605XXXX 형식, 7.202605181540 보다 후행 (시간 단조 증가).
```

**중요**: `export UTC NEW_DIR` = §3.3(f) Python subprocess (`os.environ.get('NEW_DIR')`) 안 inherit 의무. export 미실행 시 schema-specific existence proof gate 가 silent fail (empty path → `os.path.isfile('')` False). 본 export = N-4 narrow fix doctrine.

**(W1.0.c) git status hygiene**:
- `git status --short` 안 본 carry scope 외 file modification 0 verify.
- 본 carry scope 외 untracked file (예: `error.log`, `backend/db.sqlite`, audit output dir 등) = git add 대상 X 의무.
- Working branch = `main` (Codex push 시 origin main).
- W0.1 inventory memo + Q1-Q7 outline + 본 spec/plan = untracked (W3 closure 시 path-limited add only, spec §6.1 정합).

### 3.2 W1 File Operations (2 file, spec §3 + §4.2 정합)

#### 3.2.1 New v8 prompt pack dir (site 1-2)

```bash
mkdir -p "$NEW_DIR"
# Site 2 (먼저 byte-identical copy): rules_schema.json
cp prompts/_base/visual_world_rules/7.202605181540/rules_schema.json "$NEW_DIR/rules_schema.json"
# Site 1: system.md (copy first, then narrow modify line 57-80)
cp prompts/_base/visual_world_rules/7.202605181540/system.md "$NEW_DIR/system.md"
# Narrow edit line 57-80 director_notes section in $NEW_DIR/system.md:
#   - line 57 heading + line 59 lead + line 61-65 작성 규칙 (절대) 4 rule = preserve verbatim.
#   - line 67-72 올바른 예시 5 (R1-R5) = abstract (작품-specific cue 제거, generic principle process wording).
#   - line 74-78 잘못된 예시 4 (R6-R9) = abstract (인물 이름·씬 번호·구체적 사건 quoted example 제거, type description 으로 lift).
#   - line 80 final self-questioning sentence = preserve by default (spec MINOR 1 정합).
# New abstract wording: canonical process wording 의무 (spec §7.1 G5):
#   English: "principle must be scenario-agnostic, one physical-presence ambiguity per item, no entity/scene/event specifics"
#   Korean equivalent: "원칙은 시나리오에 무관하며, 항목당 하나의 물리적 존재 모호성만 다루고, 특정 인물·씬·사건을 적시하지 않는다"
# 명시적 금지: enumerated output taxonomy 형태 (예: category: [recall, hallucination, screen_layer, crosscut, occlusion]) X.
```

#### 3.2.2 STEP_MANIFEST + prompt_loader source-path verify-only (site 3-4)
- `backend/app/core/step_manifest.py:141` `visual_world_rules.schema_version=1` = no edit (Codex Q2/Q3 lock).
- `_version_sort_key` / `load_prompt` / `load_schema` source-path resolution 자동 — `8.${UTC}` prefix latest active 됨 (수동 invoke X, automatic on next pipeline run).

#### 3.2.3 Boundary preserve (No edit obligatory)
- `prompts/_base/visual_world_rules/7.202605181540/` (archive preserve, 변경 0).
- `backend/app/services/visual_context_helper.py` (4 direct reader file 1) = 변경 0.
- `backend/app/core/steps/character_list_step.py` (4 direct reader file 2) = 변경 0.
- `backend/app/core/steps/director_steps.py:114-129` (4 direct reader file 3, fallback chain line 122-128 preserve) = 변경 0.
- `backend/app/core/steps/beat_shot_steps.py:103-119/311-328` (4 direct reader file 4) = 변경 0.
- `backend/app/core/step_manifest.py` (verify-only).
- Area #7a / #7b / #7c / #7d / Carry-D7d-1 closure boundary preserve.

### 3.3 W1 Pre-Commit Verify Gates (6 check, spec §4.3 + §7.1 G1-G7 정합)

**(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** (spec G2):
```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: rules_schema.json + system.md
echo "OK 2 file exact in $NEW_DIR"
```

**(c) rules_schema.json sha256 byte-identical from v7** (spec G3):
```bash
S7=$(shasum -a 256 prompts/_base/visual_world_rules/7.202605181540/rules_schema.json | cut -d' ' -f1)
S8=$(shasum -a 256 "$NEW_DIR/rules_schema.json" | cut -d' ' -f1)
[ "$S7" = "$S8" ] && echo "OK rules_schema.json sha256 match v7=$S7 v8=$S8" || { echo "DRIFT: rules_schema.json sha mismatch v7=$S7 v8=$S8"; exit 1; }
```

**(d) R1-R9 residue absence in v8 system.md** (spec G4, exact full-phrase membership hit 0):
```bash
SYS="$NEW_DIR/system.md"
for R in \
  "회상/F.B 장면의 인물·소품·혈흔 등은 회상하는 인물의 기억 이미지이며, 회상 종료 후 현재 씬 공간에는 물리적으로 존재하지 않는다." \
  "특정 인물에게만 보이는 환각/현시 대상은 다른 인물이 등장하는 씬에서는 화면에서 제거한다." \
  "CCTV·모니터·창문 너머 등 화면 매개로 보이는 인물은 그 매개 표면 안쪽 평면 이미지로만 그리고, 매개 밖 공간에는 두지 않는다." \
  "교차편집/몽타주로 다른 장소가 보일 때 두 장소의 인물을 한 프레임에 합치지 않는다." \
  "안개·어둠 등 시야 차단 장치는 그 안의 대상을 명확히 묘사하지 말고 차단 그대로 둔다." \
  '"인물A 가 보는 인물B 의 시신은 인물A 의 환각으로 우선 판단한다."' \
  '"수사관과 형사가 장소X 에 도착했을 때 시신이 사라진 상태라면..."' \
  '"특정 씬 번호의 시신은 회상 이미지이다."' \
  '"인물C 의 배가 안개로 들어가는 장면은 다른 세계 이동이 아니다."'; do
  hits=$(grep -cF -- "$R" "$SYS")
  [ "$hits" -eq 0 ] || { echo "FAIL R-id residue: $R (hits=$hits)"; exit 1; }
done
echo "OK R1-R9 residue absent in $SYS"
```

**(e) New process wording presence** (spec G5):
```bash
# canonical process wording hit ≥ 1 (English 또는 Korean equivalent)
EN_HIT=$(grep -cF "principle must be scenario-agnostic" "$NEW_DIR/system.md")
KR_HIT=$(grep -cF "원칙은 시나리오에 무관하며" "$NEW_DIR/system.md")
TOTAL=$((EN_HIT + KR_HIT))
[ "$TOTAL" -ge 1 ] && echo "OK process wording (EN=$EN_HIT KR=$KR_HIT)" || { echo "FAIL: no canonical process wording"; exit 1; }
# enumerated output taxonomy 명시 금지 — closed-list category enum pattern 검사
TAXON_HIT=$(grep -cE "category:\s*\[" "$NEW_DIR/system.md")
[ "$TAXON_HIT" -eq 0 ] || { echo "FAIL: enumerated output taxonomy detected"; exit 1; }
echo "OK enumerated output taxonomy absent"
```

**(f) STEP_MANIFEST schema_version preserve + active source-path proof** (spec G6 + Codex IMPORTANT 3 정합):
```bash
cd backend && .venv/bin/python -c "
import sys
sys.path.insert(0, '.')
from app.core.step_manifest import STEP_MANIFEST
from app.modules.prompt_loader import get_effective_source, get_active_version

# G6: STEP_MANIFEST preserve
assert STEP_MANIFEST['visual_world_rules']['schema_version'] == 1, (
    f'STEP_MANIFEST drift: {STEP_MANIFEST[\"visual_world_rules\"][\"schema_version\"]}'
)
print('OK STEP_MANIFEST schema_version=1 preserve')

# G1: active prompt v8 source-path proof
src = get_effective_source('visual_world_rules', 'system', db=None)
file_cand = src.get('candidates', {}).get('file')
assert file_cand is not None, 'no file candidate for visual_world_rules/system'
fpath = str(file_cand.get('path', ''))
fver = str(file_cand.get('version', ''))
assert fver.startswith('8.'), f'visual_world_rules/system version drift: {fver} (expected 8.* prefix)'
assert '/visual_world_rules/8.' in fpath, f'visual_world_rules/system path drift: {fpath}'
print(f'OK active prompt source-path: version={fver} path={fpath}')

# G1 (module-version sanity): get_active_version 은 module active-version 만 반환 (schema stem-specific path X, Codex plan amend 1 N-3 정합)
module_ver = get_active_version('visual_world_rules', 'rules_schema', db=None)
assert module_ver is not None and module_ver.startswith('8.'), (
    f'visual_world_rules module active-version drift: {module_ver} (expected 8.* prefix)'
)
print(f'OK module active-version sanity: {module_ver}')

# Schema-specific proof: NEW_DIR/rules_schema.json existence (G2 file count) + sha256 byte-identical (G3) 이미 verify 완료
# 추가 schema stem path 증명 = (a) os.path.exists(NEW_DIR/rules_schema.json) [G2 정합] + (b) sha256 match v7 [G3 정합] — Codex N-3 Option 2 downgrade 정합
# Schema-specific proof: NEW_DIR is repo-root-relative, but this script runs from backend/. repo_root join 의무 (N-5 narrow fix doctrine, Codex W1 mid-state Gate (f4) FAIL 흡수).
import os
repo_root = os.path.abspath(os.path.join(os.getcwd(), os.pardir))
new_dir = os.environ.get('NEW_DIR', '')
schema_path = os.path.join(repo_root, new_dir, 'rules_schema.json') if new_dir else None
assert schema_path and os.path.isfile(schema_path), f'schema-specific existence proof FAIL: {schema_path}'
assert '/visual_world_rules/8.' in schema_path, f'schema-specific path proof FAIL: {schema_path}'
print(f'OK schema-specific path proof: {schema_path}')
" && cd ..
```

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

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

```bash
cd backend
.venv/bin/pytest \
  tests/test_visual_world_rules.py \
  tests/integration/test_area_7a_no_drift.py \
  tests/integration/test_area_7a_residue_gate.py \
  tests/services/test_visual_context_helper.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** (2 file, 0 file out-of-scope):
```bash
git add "$NEW_DIR/system.md" "$NEW_DIR/rules_schema.json"
git status --short
# Expected: 2 file staged (W1 = prompt-only, no code/test edit).
# 0 out-of-scope.
```

**Commit message format**:
```
W1(carry-a099-vwr-system-md-director-notes-prose-redesign-v1): director_notes prose abstraction — visual_world_rules v8 (2 file: system.md modified + rules_schema.json byte-identical)

- visual_world_rules/8.${UTC}/system.md modified (line 57-80 director_notes section prose abstraction; 작성 규칙 4 rule + heading + lead + line 80 self-questioning preserve)
- visual_world_rules/8.${UTC}/rules_schema.json byte-identical copy from v7 (sha256 match)
- STEP_MANIFEST['visual_world_rules']['schema_version'] == 1 preserve (no edit)
- Active prompt/schema source-path proof via get_effective_source + get_active_version (v8 resolution verified)

Pre-commit verify (Codex IMPORTANT 3 정합): 6 gate PASS — UTC + 2 file count + sha256 + R1-R9 residue 0 + canonical process wording presence + STEP_MANIFEST preserve + active source-path proof.

Targeted pytest (spec §4.4): `backend/.venv/bin/pytest backend/tests/test_visual_world_rules.py backend/tests/integration/test_area_7a_no_drift.py backend/tests/integration/test_area_7a_residue_gate.py backend/tests/services/test_visual_context_helper.py -v --tb=short` — N tests, N PASS, 0 FAIL (W1 execution 시 실측 N 값 commit body 안 기록 의무).

NO VLM. no live LLM. closed-world exact phrase membership only. standalone token global ban X.

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

### 3.6 W1 Codex per-wave review
- W1 commit 후 즉시 Codex per-wave review 의무.
- Codex live verify: §3.2 2 file + §3.3 6 pre-commit gate PASS + §3.4 4 test PASS evidence.
- Codex verdict 예상 = `APPROVED_FOR_W2_ENTRY` or `NEEDS_REVISION_NARROW`.

## 4. W2 Integrated Test Atomic Wave

### 4.1 W2 File Operations (1 file new, spec §5.1 정합)

**path-limited add scope**: `backend/tests/integration/test_carry_a099_director_notes_abstraction.py` (1 file, new).

**Test file structure** (5 Gate, no live LLM + NO VLM + no regex semantic + no standalone token ban):

```python
"""Carry-A099 — VWR system.md director_notes prose abstraction integrated test.

5 Gate verify (closed-world exact phrase membership only):
- Gate 1 (G4): R1-R9 9 strict residue absence (exact full-phrase) in v8 system.md.
- Gate 2 (G3): rules_schema.json sha256 byte-identical from v7.
- Gate 3 (G5): canonical process wording presence + enumerated output taxonomy absence.
- Gate 4 (G6): STEP_MANIFEST['visual_world_rules']['schema_version'] == 1 preserve.
- Gate 5 (optional, G7): director_steps.py:122-128 fallback chain source preservation canary.

NO VLM + no live LLM + no regex semantic + no standalone token global ban.
"""

import hashlib
from pathlib import Path
import pytest

from app.core.step_manifest import STEP_MANIFEST
from app.modules.prompt_loader import get_effective_source, get_active_version


REPO_ROOT = Path(__file__).resolve().parents[3]
VWR_V7_DIR = REPO_ROOT / "prompts/_base/visual_world_rules/7.202605181540"


R1_R9_STRICT = [
    "회상/F.B 장면의 인물·소품·혈흔 등은 회상하는 인물의 기억 이미지이며, 회상 종료 후 현재 씬 공간에는 물리적으로 존재하지 않는다.",
    "특정 인물에게만 보이는 환각/현시 대상은 다른 인물이 등장하는 씬에서는 화면에서 제거한다.",
    "CCTV·모니터·창문 너머 등 화면 매개로 보이는 인물은 그 매개 표면 안쪽 평면 이미지로만 그리고, 매개 밖 공간에는 두지 않는다.",
    "교차편집/몽타주로 다른 장소가 보일 때 두 장소의 인물을 한 프레임에 합치지 않는다.",
    "안개·어둠 등 시야 차단 장치는 그 안의 대상을 명확히 묘사하지 말고 차단 그대로 둔다.",
    '"인물A 가 보는 인물B 의 시신은 인물A 의 환각으로 우선 판단한다."',
    '"수사관과 형사가 장소X 에 도착했을 때 시신이 사라진 상태라면..."',
    '"특정 씬 번호의 시신은 회상 이미지이다."',
    '"인물C 의 배가 안개로 들어가는 장면은 다른 세계 이동이 아니다."',
]


def _v8_dir() -> Path:
    src = get_effective_source("visual_world_rules", "system", db=None)
    file_cand = src.get("candidates", {}).get("file")
    assert file_cand is not None, "no file candidate for visual_world_rules/system"
    fpath = Path(file_cand["path"]).resolve()
    return fpath.parent


def test_gate_1_r1_r9_residue_absent_in_v8_system_md():
    """G4: 9 strict R-id full-phrase membership hit 0 in v8 system.md."""
    v8 = _v8_dir()
    sys_md = (v8 / "system.md").read_text(encoding="utf-8")
    for idx, residue in enumerate(R1_R9_STRICT, start=1):
        assert residue not in sys_md, f"R{idx} residue present in v8 system.md"


def test_gate_2_rules_schema_sha256_byte_identical_from_v7():
    """G3: rules_schema.json sha256 byte-identical from v7."""
    v8 = _v8_dir()
    v7_bytes = (VWR_V7_DIR / "rules_schema.json").read_bytes()
    v8_bytes = (v8 / "rules_schema.json").read_bytes()
    v7_sha = hashlib.sha256(v7_bytes).hexdigest()
    v8_sha = hashlib.sha256(v8_bytes).hexdigest()
    assert v7_sha == v8_sha, f"rules_schema sha mismatch v7={v7_sha} v8={v8_sha}"


def test_gate_3_canonical_process_wording_presence_and_no_enum_taxonomy():
    """G5: canonical process wording present + enumerated output taxonomy absent."""
    v8 = _v8_dir()
    sys_md = (v8 / "system.md").read_text(encoding="utf-8")
    en_pres = "principle must be scenario-agnostic" in sys_md
    kr_pres = "원칙은 시나리오에 무관하며" in sys_md
    assert en_pres or kr_pres, "canonical process wording (EN or KR) absent"
    # enumerated taxonomy 형태 금지
    import re
    taxonomy_pattern = re.compile(r"category\s*:\s*\[")
    assert not taxonomy_pattern.search(sys_md), "enumerated output taxonomy detected"


def test_gate_4_step_manifest_schema_version_preserve():
    """G6: STEP_MANIFEST['visual_world_rules']['schema_version'] == 1 preserve."""
    assert STEP_MANIFEST["visual_world_rules"]["schema_version"] == 1


def test_gate_5_fallback_chain_source_preservation():
    """G7 (optional): director_steps.py:122-128 fallback chain source preservation canary.

    No file edit verify — line range 안 'possession', 'projection', 'ghost' literal presence preserve.
    """
    director_steps = REPO_ROOT / "backend/app/core/steps/director_steps.py"
    src = director_steps.read_text(encoding="utf-8")
    lines = src.splitlines()
    # line index 121-127 (0-indexed) = spec §2.4 fallback chain line 122-128
    fallback_block = "\n".join(lines[120:128])
    for rule_type in ("possession", "projection", "ghost"):
        assert rule_type in fallback_block, f"fallback chain rule_type '{rule_type}' missing"


def test_gate_6_v8_active_source_path_proof():
    """G1: v8 active source-path proof via get_effective_source (prompt stem-specific) + get_active_version (module-version sanity only).

    Schema stem-specific proof = NEW_DIR/rules_schema.json existence + sha256 (test_gate_2 정합),
    not get_active_version which returns module active-version only (Codex plan amend 1 N-3 정합).
    """
    # Prompt stem-specific source-path proof (system.md)
    src = get_effective_source("visual_world_rules", "system", db=None)
    file_cand = src.get("candidates", {}).get("file")
    assert file_cand is not None
    assert str(file_cand["version"]).startswith("8."), file_cand["version"]
    assert "/visual_world_rules/8." in str(file_cand["path"]), file_cand["path"]

    # Module active-version sanity only (NOT schema stem-specific path proof)
    module_ver = get_active_version("visual_world_rules", "rules_schema", db=None)
    assert module_ver and module_ver.startswith("8."), module_ver

    # Schema stem-specific path proof = NEW_DIR/rules_schema.json existence (test_gate_2 sha256 already verified byte-identical)
    v8 = _v8_dir()
    schema_file = v8 / "rules_schema.json"
    assert schema_file.is_file(), f"schema-specific file existence FAIL: {schema_file}"
    assert "/visual_world_rules/8." in str(schema_file), f"schema-specific path FAIL: {schema_file}"
```

### 4.2 W2 Pre-Commit Verify Gates

**(a) pytest 신규 file ALL PASS**:
```bash
cd backend && .venv/bin/pytest tests/integration/test_carry_a099_director_notes_abstraction.py -v --tb=short && cd ..
# Expected: 6 tests, 6 PASS, 0 FAIL.
```

**(b) targeted regression** (Area #7a inherited 4 file + Carry-A099 신규):
```bash
cd backend && .venv/bin/pytest \
  tests/test_visual_world_rules.py \
  tests/integration/test_area_7a_no_drift.py \
  tests/integration/test_area_7a_residue_gate.py \
  tests/services/test_visual_context_helper.py \
  tests/integration/test_carry_a099_director_notes_abstraction.py \
  -v --tb=short && cd ..
# Expected: ALL PASS.
```

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

```bash
git add backend/tests/integration/test_carry_a099_director_notes_abstraction.py
git status --short
# Expected: 1 file staged.
```

**Commit message format**:
```
W2(carry-a099-vwr-system-md-director-notes-prose-redesign-v1): integrated test atomic — 6 gate verify

- backend/tests/integration/test_carry_a099_director_notes_abstraction.py (file-level new, 1 file)
- Gate 1 (G4): R1-R9 9 strict full-phrase residue absence in v8 system.md
- Gate 2 (G3): rules_schema.json sha256 byte-identical from v7
- Gate 3 (G5): canonical process wording presence (EN or KR) + enumerated output taxonomy absence
- Gate 4 (G6): STEP_MANIFEST['visual_world_rules']['schema_version'] == 1 preserve
- Gate 5 (optional, G7): director_steps.py:122-128 fallback chain source preservation canary (no edit, behavior verify)
- Gate 6 (G1): v8 active source-path proof — get_effective_source for prompt stem-specific (system.md) + get_active_version for module-version sanity only + schema-specific path proof via NEW_DIR/rules_schema.json existence (Codex plan amend 1 N-3 정합)

Targeted pytest (W2 + regression): `backend/.venv/bin/pytest backend/tests/integration/test_carry_a099_director_notes_abstraction.py backend/tests/test_visual_world_rules.py backend/tests/integration/test_area_7a_no_drift.py backend/tests/integration/test_area_7a_residue_gate.py backend/tests/services/test_visual_context_helper.py -v --tb=short` — N tests, N PASS, 0 FAIL.

W1 commit reference: <W1 hash> (2 file / system.md modified + rules_schema.json byte-identical).

NO VLM. no live LLM. closed-world exact phrase membership only. standalone token global ban X. no regex semantic (only fixed-string membership + 1 narrow taxonomy regex for closed-list category enumeration absence verify).
```

### 4.4 W2 Codex per-wave review
- W2 commit 후 즉시 Codex per-wave review 의무.
- Codex verdict 예상 = `APPROVED_FOR_W3_ENTRY` or `NEEDS_REVISION_NARROW`.

## 5. W3 Closure Docs Atomic Wave

### 5.1 W3 File Operations (6 repo-local docs + external memory, spec §6.1 정합)

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

1. **(a) 본 spec** frontmatter status `draft` → `closed` + §10 closure section in-place REPLACE (12 sub-section live content, Carry-D7d-1 W2 패턴 정합).
2. **(b) 본 plan** first commit (drafting closure, frontmatter status narrow update `draft` → `closed`).
3. **(c) `docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md` §5.7** Sub-area (b) Phase 1/Phase 2/post-#7d carry follow-up narrow append `Carry-A099 resolved by W1/W2 + W3 closure-docs — director_notes prose hard-prime examples abstracted` (Codex 7 narrow guard 6 verbatim).
4. **(d) `docs/visual-reliability-audit/2026-05-14-semantic-string-routing-debt-audit/02-prompt-side-hygiene-audit.md`** line 308 A099 row + §11.3 + §13 + §14 narrow update `Carry-A099 resolved by W1/W2 + W3 closure-docs`.
5. **(e) `docs/superpowers/specs/2026-05-18-area-7a-visual-world-rules-sot-v1-design.md`** §1.4 + §11.4 + §12.1 line 72/413 Carry-A099 status `deferred` → `resolved by Carry-A099 W1/W2 + W3 closure-docs` narrow update.
6. **(f) `docs/superpowers/specs/2026-05-19-area-7b-vwr-cascade-downstream-v1-design.md`** §1.3 + §6.2 + §11.6 line 14/109/129/570/715 Carry-A099 status narrow update.

**External memory (non-git, git add 대상 X)**:
- MEMORY.md update — Carry-A099 v1 closure entry 추가 + 카테고리 cross-reference.
- session memo (`memory/session_20260519_carry_a099_v1_closure.md`) 신설.
- Carry priority 정합 update (Carry-A100 / Carry-P021 / Future Carry-A099-structured).

**W0.1 inventory memo + Q1-Q7 outline = untracked reference artifacts** (Codex 7 narrow guard 5 정합 — path-limited add 시 보호).

### 5.2 W3 Pre-Commit Placeholder Substitution Gate (post-Carry-D7d-1 fix-up 1 doctrine 정합)

**Rule**: W3 closure commit 직전, 6 repo-local closure docs 안 live `8.UTC_TIMESTAMP` / `8.UTC` placeholders 모두 actual W1 dir name (`8.ACTUAL_TIMESTAMP` 실 substituted timestamp, underscore-escaped per post-Carry-D7d-1 fix-up 1 doctrine — `never re-emit literal angle-bracketed forms outside marker blocks`) 으로 substitute. HISTORICAL AUDIT TRAIL / TEMPLATE ONLY marker block 안 placeholder = substitute X (marker 보존).

**Substitution mechanism** (Carry-D7d-1 W2 fix-up 1 pattern 정합):
```bash
W1_DIR_NAME=$(ls -1 prompts/_base/visual_world_rules/ | grep -E "^8\\." | sort | tail -n 1)
[ -n "$W1_DIR_NAME" ] || { echo "FAIL: W1 v8 dir missing"; exit 1; }
echo "W3 substitution target W1 dir = $W1_DIR_NAME"

CLOSURE_DOCS=(
  docs/superpowers/specs/2026-05-19-carry-a099-vwr-system-md-director-notes-prose-redesign-v1-design.md
  docs/superpowers/plans/2026-05-19-carry-a099-vwr-system-md-director-notes-prose-redesign-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/02-prompt-side-hygiene-audit.md
  docs/superpowers/specs/2026-05-18-area-7a-visual-world-rules-sot-v1-design.md
  docs/superpowers/specs/2026-05-19-area-7b-vwr-cascade-downstream-v1-design.md
)

for f in "${CLOSURE_DOCS[@]}"; do
  [ -f "$f" ] || { echo "FAIL: closure doc missing: $f"; exit 1; }
  TMP="${f}.tmp.carry-a099"
  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(/8\.UTC_TIMESTAMP/, repl)
        gsub(/8\.UTC/, repl)
      }
      print
    }
  ' "$f" > "$TMP"
  mv "$TMP" "$f"
done

# Verify (Codex fix-up 1 doctrine 정합 — fixed-string check, both forms hit 0 obligatory per Codex plan amend 1 N-2):
TOTAL=0
for f in "${CLOSURE_DOCS[@]}"; do
  body=$(awk '/HISTORICAL AUDIT TRAIL.*TEMPLATE ONLY/{flag=1; next} /end TEMPLATE ONLY/{flag=0; next} !flag' "$f")
  h1=$(echo "$body" | grep -cF '8.UTC_TIMESTAMP')
  h2=$(echo "$body" | grep -cF '8.UTC')
  hits=$((h1+h2))
  TOTAL=$((TOTAL+hits))
done
[ "$TOTAL" -eq 0 ] && echo "OK W3 placeholder substitution gate (marker-excluded hit 0, both 8.UTC_TIMESTAMP + 8.UTC forms)" || { echo "FAIL: placeholder residue $TOTAL hits"; exit 1; }
```

### 5.3 W3 Path-Limited git add + Commit

```bash
git add \
  docs/superpowers/specs/2026-05-19-carry-a099-vwr-system-md-director-notes-prose-redesign-v1-design.md \
  docs/superpowers/plans/2026-05-19-carry-a099-vwr-system-md-director-notes-prose-redesign-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/02-prompt-side-hygiene-audit.md \
  docs/superpowers/specs/2026-05-18-area-7a-visual-world-rules-sot-v1-design.md \
  docs/superpowers/specs/2026-05-19-area-7b-vwr-cascade-downstream-v1-design.md
git status --short
# Expected: 6 file staged.
```

**Commit message format**:
```
W3(carry-a099-vwr-system-md-director-notes-prose-redesign-v1): closure docs atomic — 6 file path-limited

- 본 spec frontmatter status draft → closed + §10 closure section in-place REPLACE (12 sub-section live content)
- 본 plan first commit (drafting closure, frontmatter status narrow update)
- roadmap §5.7 narrow append: Carry-A099 resolved by W1/W2 + W3 closure-docs (director_notes prose hard-prime examples abstracted)
- audit 02 line 308 A099 row + §11.3/§13/§14 narrow update: Carry-A099 resolved
- Area #7a v1 spec §1.4 + §11.4 + §12.1 line 72/413 Carry-A099 status deferred → resolved
- Area #7b v1 spec §1.3 + §6.2 + §11.6 line 14/109/129/570/715 Carry-A099 status narrow

W1 commit reference: <W1 hash> (2 file).
W2 commit reference: <W2 hash> (1 file integrated test).
W3 placeholder substitution gate PASS (marker-excluded hit 0).
Final pushed range/count = external memory only.

Codex iter trace post W2: W2 per-wave APPROVED + W1-W3 range review APPROVED_FOR_PUSH (or NEEDS_REVISION_NARROW with fix-up).

NO VLM. closed-world exact phrase membership only. standalone token global ban X.
```

### 5.4 W3 Range Review + Push Gate

**Codex range review (W1+W2+W3)** 의무:
- live verify: W1 commit 2 file + W2 commit 1 test file + W3 commit 6 closure docs + active source-path proof (`get_effective_source` returns `candidates.file.path` containing `/visual_world_rules/8.` prefix + `candidates.file.version` starts `8.`, underscore-escaped per post-Carry-D7d-1 fix-up 1 doctrine) + targeted pytest re-run ALL PASS + W3 placeholder substitution gate evidence (marker-excluded `8.UTC_TIMESTAMP` + `8.UTC` fixed-string both hit 0).
- Codex verdict 예상 = `APPROVED_FOR_PUSH` (직접 push) or `NEEDS_REVISION_MINOR` (narrow fix-up).

**Push gate** (Codex APPROVED_FOR_PUSH 후 즉시, 사용자 ask 0):
```bash
git push origin main
# Final pushed range external memory: <pre-W1 HEAD>..<W3 HEAD>.
```

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

## 6. Doctrine (spec §8 정합 inline reaffirm)

본 plan = spec §8 doctrine 정합 inline 재반복 X (spec 참조). 본 plan 안 doctrine 적용 정합 의무 site:
- **4-Gate Boundary Doctrine**: §3.2 narrow edit + §4.1 5 Gate + §5 closure docs 안 semantic regex 0 (description literal substitute + plain string membership only + narrow taxonomy regex 1 only).
- **NO VLM hard constraint**: §3.4 + §4.2 targeted pytest 안 VLM 사용 0.
- **standalone token global ban X**: §3.3(d) + §4.1 test 안 single token global ban 0 (R1-R9 full-phrase only).
- **closed-world exact phrase membership only**: §3.3(d) `grep -cF` (fixed string) + spec §G4 정합.
- **TEMPLATE ONLY + W3 self-reference + Substitution self-referential bug + Legacy 본 commit retroactive escape + post-Carry-D7d-1 fix-up 1 강화**: 본 plan §3.5/§4.3/§5.3 commit message body 안 self-reference hash mention 0 + final pushed range/count = external memory only suffix. §5.2 placeholder substitution gate executable.
- **Workflow doctrine**: 본 plan 매 step Codex first 의무.

## 7. References + Carry Follow-up

### 7.1 References (spec §9.5 정합 inline)
- Spec final: `docs/superpowers/specs/2026-05-19-carry-a099-vwr-system-md-director-notes-prose-redesign-v1-design.md` (status closed post-W3, Codex APPROVED_FOR_PLAN after spec quality iter 1 + amend 1 narrow re-review).
- W0.1 inventory memo (untracked): `docs/superpowers/specs/2026-05-19-carry-a099-w0-1-inventory.md`.
- Q1-Q7 outline (untracked): `docs/superpowers/specs/2026-05-19-carry-a099-q1-q7-outline.md`.
- prompt_loader API source-path proof: `backend/app/modules/prompt_loader.py:272 get_effective_source` + `:391 get_active_version`.
- Pre-Carry-A099 closure: [[session_20260519_carry_d7d_1_v1_closure]] (origin/main HEAD `05d5265`).
- Area #7a v1 closure: push `d0410eb`. Area #7b v1 closure: push `e751e72`. Area #7c v1 closure: push `62aa2ef`. Area #7d v1 closure: push `b9c610e`. Carry-D7d-1 v1 closure: push `05d5265`.
- Memory references (spec §9.5 inline list 정합).

### 7.2 Carry Follow-up Post Carry-A099 (spec §9.4 정합)
1. **Carry-A100** — VWR `system.md` t2i_context demonym redesign V8+ (Area #7a 정합 보존, cost medium).
2. **Carry-P021** — scene_consistency 7 enumeration broad, source unresolved low-priority (cost small).
3. **Future Carry-A099-structured** (or Area follow-up) — Option 3 structured emit.

### 7.3 Closure Boundary (spec §9.1-§9.3 정합)
- Allowed claim (Codex Q0-light verbatim): `director_notes prose examples / bad examples were abstracted to remove closed-list semantic hard-prime examples and scenario-summary examples while preserving the existing director_notes carrier contract`.
- Allowed closure-doc wording (Codex 7 narrow guard 6): `director_notes prose hard-prime examples abstracted`.
- Forbidden claims (Codex Q0-light + 7 narrow guard 6): `director_notes structured SOT complete` / `physical-presence routing fixed` / `field-shape migration complete` / `all VWR downstream raw-prose risk fixed`.
