---
title: C9 — scene_detail Rule B body-light verb forbidden list 추상화 v1 implementation plan (fix-critical-1 Tier β #6)
date: 2026-05-20+
status: closed (C9 v1 — W1-W2 atomic execution 완료, Codex W1 per-wave APPROVED_FOR_W2_ENTRY. W1 commit 04016da. §5 Closure 참조.)
spec_ref: docs/superpowers/specs/2026-05-20-c9-scene-detail-body-light-verb-v1-design.md (status APPROVED_FOR_PLAN)
roadmap_ref: docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md (Track B §5.16 신설 예정 — C9)
fix_critical_doc_ref: docs/fix-critical-1/index.html C9 section
prerequisites:
  - C9 spec v1 APPROVED_FOR_PLAN (Codex spec review NEEDS_REVISION_NARROW → amend 1 → NEEDS_REVISION_NARROW_2 → amend 2 → APPROVED_FOR_PLAN; status closed only at W2 closure-docs commit).
  - C1 / C2 / C3 / C6 / C7 v1 (closed + pushed, origin/main HEAD `81bde22`) — HEAD anchor. 변경 0.
non_supersedes:
  - C4 #8 / C5 #9 / C8 #7 / C10 (fix-critical-1 잔여 area).
---

# C9 — scene_detail Rule B body-light verb forbidden list 추상화 v1 implementation plan

## 1. Purpose + Spec Reference

C9 = `prompts/_base/scene_detail/<latest>/system.md` 의 `## 조명·색조가 신체를 변형하지 않게 (Rule B)` 섹션 (`:70-96`) 안 **4개 닫힌 enumeration** (closed verb list `cut/slice/split/carve/bisect` `:74`/`:95` + forbidden 예시 5건 `:78-82` + recommended 예시 5건 `:86-90` + recommended verb list `:94`) 을 단일 generic semantic principle 로 추상화. header `:70` + WHY `:72` 보존. prompt-pack 파일 편집 → v31 신규 디렉토리 + version cascade.

- spec: `docs/superpowers/specs/2026-05-20-c9-scene-detail-body-light-verb-v1-design.md` §1-§10.
- 2-wave: **W1** = v31 prompt-pack 신설 + version cascade + alignment test 갱신 + C9 regression test (1 atomic commit) / **W2** = closure docs atomic.
- HEAD anchor = `81bde22` (origin/main, C6 v1 closed).
- `detail_schema.json` 내용 / `SCENE_DETAIL_SCHEMA_VERSION` / `STEP_MANIFEST` schema_version (12) — 변경 0 (spec §1.3 / §4.5 / §4.8).

## 2. Plan Iter Trace

- iter 0 (2026-05-20+): plan v1 drafting.

## 3. W1 — v31 prompt-pack rewrite + version cascade + test (1 atomic commit)

### 3.1 Pre-W1 Entry Sanity

- W1 진입 전 Codex W1 entry sanity 받을 것 (file edit 0 상태에서 송신).
- 진입 직전 read: 승인된 spec + 본 plan + `prompts/_base/scene_detail/30.202605200303/system.md` 현재 상태 (Rule B `:70-96` anchor 가 현 HEAD `81bde22` 와 일치하는지 line drift 확인) + version cascade 4 site + alignment test 5 file.
- HEAD = `81bde22` verify.

### 3.2 W1 File Operations (2 신규 prompt + 2 code + 5 test modify + 1 신규 test = 10 file, 1 atomic commit)

| op | file |
|----|------|
| new | `prompts/_base/scene_detail/31.<W1_UTC>/system.md` |
| new | `prompts/_base/scene_detail/31.<W1_UTC>/detail_schema.json` (v30 byte-identical sibling) |
| modify | `backend/app/core/steps/detail_steps.py` (`SCENE_DETAIL_PROMPT_VERSION`) |
| modify | `backend/app/core/version_registry.py` (`MODULE_VERSIONS` + `prompt_dependency`) |
| modify | `backend/tests/prompts/test_scene_detail_continuity_alignment.py` |
| modify | `backend/tests/prompts/test_scene_detail_spatial_alignment.py` |
| modify | `backend/tests/integration/test_g4_5a_spatial_integration.py` |
| modify | `backend/tests/test_prompt_versions.py` |
| modify | `backend/tests/integration/test_area_7b_no_drift.py` |
| new | `backend/tests/prompts/test_c9_scene_detail_body_light_verb.py` |

prompt-pack rewrite + version cascade + test 갱신/신설을 **단일 atomic commit**. `git add` 명시 경로만 (global add 금지).

### 3.3 v31 prompt-pack 신설 (W1.1)

**W1.1a — v31 디렉토리 생성 (v30 전체 복사)**:

```bash
# repo-root cwd. W1_UTC 는 W1 실행 시점 1회 생성 후 dir명·SCENE_DETAIL_PROMPT_VERSION 에 동일 적용 (Carry-P021 N-exec-2 정합).
W1_UTC=$(date -u +%Y%m%d%H%M)
cp -r prompts/_base/scene_detail/30.202605200303 "prompts/_base/scene_detail/31.${W1_UTC}"
echo "v31 dir = 31.${W1_UTC}"
```

- `cp -r` 로 v30 전체 (`system.md` + `detail_schema.json`) 복사 → `detail_schema.json` 은 자동 byte-identical (별도 편집 0, G5 sha256 동일 보장).

**W1.1b — v31 `system.md` Rule B 섹션 rewrite**: `prompts/_base/scene_detail/31.<W1_UTC>/system.md` 안 Rule B 섹션 `:74-96` 치환. old_string (v30 복사본의 `:74-96` 23줄 — header `:70` + 빈줄 `:71` + WHY `:72` + 빈줄 `:73` 은 제외):

```
조명·색조 효과는 반드시 **표면**(피부 일부, 옷, 벽, 가구)에만 한정한 표현으로 적는다. 빛이 신체에 직접 작용하는 동사("cut", "slice", "split", "carve", "bisect")를 신체 부위와 결합하지 마라.

### 절대 금지 표현 — 빛/색이 신체를 자르듯이

- ✗ `red light cuts across her eyes`
- ✗ `crimson spill cuts across her features`
- ✗ `a beam slicing through his face`
- ✗ `colored light splits her cheek in half`
- ✗ `shadow carving across the mouth`

### 권장 표현 — 빛이 표면에 닿는 묘사

- ✓ `red light reflects on her cheek and jacket`
- ✓ `cool red ambient washes the side of her face`
- ✓ `warm orange glow falling on her shoulder and the wall behind`
- ✓ `crimson light pooling on her hand and the table surface`
- ✓ `a strip of cool light falling across the wall just past her shoulder`

### 핵심 원칙

- 조명은 **표면에 닿는 것** — `falls on`, `washes`, `reflects on`, `catches on`, `pools on`, `glows across <surface>`
- **`cut / slice / split / carve / bisect` + 신체 부위** 조합 절대 금지
- 색감의 강도는 형용사로 (`deep crimson`, `cool blue cast`) — 동사로 신체를 자르지 마라
```

new_string (generic semantic principle 1 문단 — spec §3.2):

```
조명·색조 효과는 빛이 닿거나 비치는 **표면**(눈에 보이는 표면·재질·영역)에 머무는 묘사로 적는다. 빛이나 색이 신체 부위를 물리적으로 변형하거나 절단하는 행위처럼 작용한다고 쓰지 마라 — 그런 표현은 표면에 닿는 빛이 아니라 신체 변형으로 해석된다. 색감의 강도는 형용사로 조절하고, 동사로 신체를 자르듯 쓰지 마라.
```

- 결과 v31 Rule B 섹션 = header (`## 조명·색조가 신체를 변형하지 않게 (Rule B)`) + 빈줄 + WHY 문단 + 빈줄 + generic principle 문단 + 빈줄 + 다음 섹션 `## 크기·치수 — 실 수치 금지, 상대 비율만`.
- header `:70` / WHY `:72` byte-for-byte 보존. Rule B 섹션 외 system.md 전체 byte-for-byte 보존 (`:240` 실루엣 cutout / `:439` windshield slice 포함).
- v30 원본 디렉토리 (`30.202605200303/`) 변경 0.

### 3.4 version cascade 4-point sync (W1.2)

W1_UTC 동일 값 사용.

**W1.2a — `detail_steps.py`** (`SCENE_DETAIL_PROMPT_VERSION`, 현 `:107`):
```python
# before
SCENE_DETAIL_PROMPT_VERSION = "30.202605200303"  # 2026-05-20 (C2 v1) ...
# after
SCENE_DETAIL_PROMPT_VERSION = "31.<W1_UTC>"  # 2026-05-20 (C9 v1) — v31 prompt: Rule B body-light verb closed list + 예시 목록 추상화 (generic semantic principle). cp config_hash invalidation (prompt text change, schema/output shape 변경 0). 이전: 30.202605200303 C2 (owned_object_usage echo). ...
```

**W1.2b — `version_registry.py`** (`MODULE_VERSIONS["scene_detail_composer"]`, 현 `:34`):
```python
# before
"scene_detail_composer": "1.30.0",    # 2026-05-20 — C2 v1: v30 prompt ...
# after
"scene_detail_composer": "1.31.0",    # 2026-05-20 — C9 v1: v31 prompt — Rule B body-light verb closed list 추상화 (generic semantic principle, prompt-only; schema_version 12 유지). 이전: 1.30.0 C2 (v30 owned_object_usage echo). ...
```

**W1.2c — `version_registry.py`** (`_MODULE_INFO["scene_detail_composer"]["prompt_dependency"]`, 현 `:126`):
```python
# before
"prompt_dependency": "scene_detail/v30",  # major suffix only — alignment test enforces "v##" suffix matching latest
# after
"prompt_dependency": "scene_detail/v31",  # major suffix only — alignment test enforces "v##" suffix matching latest (C9 v1)
```

- `SCENE_DETAIL_SCHEMA_VERSION` / `STEP_MANIFEST["scene_detail"]["schema_version"]` (12) — 변경 0.

### 3.5 alignment / version test 5 file v30→v31 갱신 (W1.3)

**W1.3a — grep enumerate (SSOT)**: W1 실행 시 5 file 안 모든 occurrence 를 `rg -n` 으로 전수 확인 (spec §2.3 표는 W0 스냅샷 — 비권위, 신뢰 금지):

```bash
rg -n 'scene_detail/v30|"1\.30\.0"|startswith\("30\."\)|NEW_DIR_EXPECTED|"scene_detail": "30\."' \
  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/test_prompt_versions.py \
  backend/tests/integration/test_area_7b_no_drift.py
```

**W1.3b — occurrence 갱신** (W0 스냅샷 14 assert/occurrence — W1 `rg` 결과로 재확인 후 빠짐없이):

| file | 갱신 (assert literal + stale 오류 메시지 + docstring/history 주석) |
|------|------------------------------------------------------------------|
| `test_scene_detail_continuity_alignment.py` | `1.30.0`→`1.31.0` / `scene_detail/v30`→`/v31` / `startswith("30.")`→`("31.")` (3 assert) + module docstring `:15-23` + per-test docstring + stale 메시지 (`!= '1.28.0'`/`!= 'scene_detail/v28'`) v31 동기 |
| `test_scene_detail_spatial_alignment.py` | `1.30.0`→`1.31.0` / `scene_detail/v30`→`/v31` / `startswith("30.")`→`("31.")` **2회** (4 assert) + module docstring `:15-23` + per-test docstring + stale 메시지 동기 |
| `test_g4_5a_spatial_integration.py` | `Test4WayAlignment` `startswith("30.")`→`("31.")` / `"1.30.0"`→`"1.31.0"` / `scene_detail/v30`→`/v31` + docstring `:562-568` / config_hash surrogate test `startswith("30.")`→`("31.")` `:771` + message (4 assert / 2 test) |
| `test_prompt_versions.py` | `:216` `startswith("30.")`→`("31.")` / `:227` `"1.30.0"`→`"1.31.0"` (2 assert) + history 주석 동기 (함수명 `..._1_28_0` 미개명 — rename out-of-scope) |
| `test_area_7b_no_drift.py` | `:50` `NEW_DIR_EXPECTED["scene_detail"]` `"30."`→`"31."` + 주석 `:47-49` (C1/C2 → C9 v31 추가 반영) |

- occurrence 누락 = W1 regression — Gate W1.4 (5 file 전수 pytest) 가 잡는다.

### 3.6 C9 regression test 신설 (W1.4)

**대상**: `backend/tests/prompts/test_c9_scene_detail_body_light_verb.py` (신규). spec §7 Gate G1-G7. 파일 read + 문자열 검사 + sha256 only — no live LLM, NO VLM.

설계:
- `from app.core.steps.detail_steps import SCENE_DETAIL_PROMPT_VERSION` 으로 latest 디렉토리 resolve → `prompts/_base/scene_detail/<SCENE_DETAIL_PROMPT_VERSION>/system.md` (W1 후 v31).
- `_rule_b_section(system_md_text)` helper — `## 조명·색조가 신체를 변형하지 않게 (Rule B)` 부터 다음 `## ` (line-start) 직전까지 slice. residue gate 는 이 slice 에만 적용 (`:240`/`:439` 등 섹션 밖 제외 — spec §3.3 path-scoped).
- 닫힌-form literal 검사: G1 은 `'"cut", "slice"'` (quoted-comma form 안정 substring) + `'cut / slice / split / carve / bisect'` (slash form) 검사 — bare `cut`/`slice` 토큰 grep 금지. test 파일 자체 self-hit 방지 위해 search needle 은 split-string 상수 (`'"cut"' + ', "slice"'`) 로 구성 (C6 N-2 precedent — 단 C9 residue gate 는 v31 system.md 만 read 하므로 test 파일은 어떤 gate 도 스캔 X, 방어적 적용).
- Gate G1-G7 = spec §7 표.

**Gate 매핑**:
| Gate | assertion |
|------|-----------|
| G1 | Rule B slice 에 closed verb list 닫힌-form literal 0 (quoted-comma + slash form) |
| G2 | Rule B slice 에 forbidden/recommended 예문 marker (`cuts across her eyes` / `slicing through his face` / `pools on` / `glows across` 등) 0 |
| G3 | Rule B slice 에 generic principle marker (`눈에 보이는 표면·재질·영역` + `신체 변형으로 해석된다`) 포함 |
| G4 | v31 system.md 에 Rule B header + WHY marker (`물리적 절단` 으로 해석) 포함 |
| G5 | v31 `detail_schema.json` sha256 == v30 `detail_schema.json` sha256 |
| G6 | `SCENE_DETAIL_PROMPT_VERSION.startswith("31.")` + `MODULE_VERSIONS["scene_detail_composer"] == "1.31.0"` + `_MODULE_INFO[...]["prompt_dependency"] == "scene_detail/v31"` + v31 디렉토리 존재 |
| G7 | v31 system.md 에 `## 실루엣 묘사 규칙 — 평면 cutout 금지` + `a slice of the windshield visible` + `## 크기·치수` 그대로 존재 (boundary preserve) |

### 3.7 W1 Pre-commit Gate

repo-root cwd (`/Users/manta/Documents/Projects/TheRoad-I1`). 모든 gate venv python + `PYTHONPATH=backend` (system python app import fail — C1/C2/C3/C6 N-exec 정합). `cd backend` cwd drift 금지 (Carry-P021 N-exec-1 정합).

```bash
# Gate W1.1: C9 신규 test PASS (G1-G7)
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests/prompts/test_c9_scene_detail_body_light_verb.py -q

# Gate W1.2: alignment/version test 5 file 전수 PASS
PYTHONPATH=backend backend/.venv/bin/python -m pytest \
  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/test_prompt_versions.py \
  backend/tests/integration/test_area_7b_no_drift.py -q

# Gate W1.3: scene_detail / detail_steps 관련 regression (자동 latest-pick test 포함 — test_scene_detail_id_policy_alignment.py)
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests -k "scene_detail or detail_steps" -q

# Gate W1.4: residue 증명 — executable assertion (v31 Rule B 섹션 path-scoped, split-string self-hit 방지)
PYTHONPATH=backend backend/.venv/bin/python - <<'PY'
from pathlib import Path
from app.core.steps.detail_steps import SCENE_DETAIL_PROMPT_VERSION
sysmd = Path(f"prompts/_base/scene_detail/{SCENE_DETAIL_PROMPT_VERSION}/system.md").read_text(encoding="utf-8")
assert SCENE_DETAIL_PROMPT_VERSION.startswith("31."), f"SCENE_DETAIL_PROMPT_VERSION not v31: {SCENE_DETAIL_PROMPT_VERSION}"
hdr = "## 조명·색조가 신체를 변형하지 않게 (Rule B)"
assert hdr in sysmd, "Rule B header 손실"
start = sysmd.index(hdr)
nxt = sysmd.index("\n## ", start + len(hdr))
rule_b = sysmd[start:nxt]
# closed-form literal 부재 (split-string self-hit 방지)
assert ('"cut"' + ', "slice"') not in rule_b, "closed verb list (quoted-comma form) 잔존"
assert ('cut / slice' + ' / split / carve / bisect') not in rule_b, "closed verb list (slash form) 잔존"
assert ('cuts across' + ' her eyes') not in rule_b, "forbidden 예문 잔존"
assert ('glows ' + 'across') not in rule_b, "recommended verb list 잔존"
# generic principle 존재
assert "눈에 보이는 표면·재질·영역" in rule_b, "generic principle marker 부재"
assert "신체 변형으로 해석된다" in rule_b, "generic principle marker 부재"
# WHY 보존
assert "물리적 절단" in rule_b, "WHY 문단 손실"
# boundary preserve (섹션 밖)
assert "평면 cutout 금지" in sysmd, "boundary :240 손실"
assert "a slice of the windshield visible" in sysmd, "boundary :439 손실"
print("Gate W1.4 OK")
PY

# Gate W1.5: 백엔드 전체 회귀 (pre-existing failure 제외 동일 — C6 closure 기록 baseline)
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests -q
```

- Gate W1.4 가 AssertionError 없이 `Gate W1.4 OK` 출력해야 W1 commit 가능.
- Gate W1.5 신규 failure 가 C9 변경 기인이면 commit 금지 → 원인 수정. pre-existing 여부는 clean HEAD `81bde22` git stash 대조로 확정.

### 3.8 W1 Commit + per-wave Codex review

- commit message: `W1(c9-scene-detail-body-light-verb-v1): scene_detail v31 prompt-pack — Rule B body-light verb closed list + 예시 목록 추상화 (generic semantic principle) + version cascade 4-point + alignment test 5 file + C9 regression test (10 file)`
- staged: 위 §3.2 표 10 file 만 (`git add` 명시 경로 — global add 금지). v31 신규 디렉토리 2 file 포함.
- commit 후 Codex W1 per-wave review 송신 → APPROVED_FOR_W2_ENTRY 받고 W2 진입.

## 4. W2 — Closure docs atomic

### 4.1 Pre-W2 Entry Sanity

- W1 per-wave APPROVED_FOR_W2_ENTRY 후 진입.
- W2 = closure docs only — code/test/prompt 변경 0.

### 4.2 W2 File Operations (5 docs, path-limited)

| op | file |
|----|------|
| modify | `docs/superpowers/specs/2026-05-20-c9-scene-detail-body-light-verb-v1-design.md` |
| modify | `docs/superpowers/plans/2026-05-20-c9-scene-detail-body-light-verb-v1-implementation.md` |
| modify | `docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md` |
| modify | `docs/fix-critical-1/index.html` |
| modify | `docs/visual-reliability-audit/2026-05-14-semantic-string-routing-debt-audit/03-llm-side-heuristic-audit.md` |

audit `01-`/`02-` 에는 L-7 row 부재 — marker 대상 아님 (audit 03 단독 finding). generated audit-output (`triage_report.md`) / untracked artifact 미포함.

### 4.3 W2 closure docs 내용

1. **spec** — frontmatter `status` → closed + §10 Closure (commit chain / Gate result / Codex review trace / 함정).
2. **plan** — frontmatter `status` → closed + §5 Closure.
3. **roadmap** — **§5.16 신설** — C9 closed entry (인접 C6 §5.10 / C7 §5.12 의 Status / Fix applied / Boundary preserve / Cost / Closure verify 형식 정합).
4. **fix-critical-1 index.html** — C9 marker: badge `✓ CLOSED` + priority list `C9 → CLOSED` / `C4 → NEXT` + priority matrix row 6 status + **stale 정정** (현재 site row `scene_detail/28...` → v30 active / v31 신규, "4 forbidden phrasing" → 5건, `:78-81` → `:78-82`).
5. **audit 03** (`03-llm-side-heuristic-audit.md`) — L-7 row 에 closure marker + §8 Fix 방향 / carry follow-up line (`:218`) 의 C9 항목 갱신 (C9 closed 반영).

- **W2 self-hash 금지** — closure docs 안 W2 자체 commit hash literal 없음. "W1-W2" / "W2 closure commit" wording. W1 hash 는 W1 commit 후 확정 — closure docs 에 기재 가능. W2 hash 는 push 후 external memory 기록.

### 4.4 W2 Pre-commit Gate

```bash
# Gate W2.1: closure docs 5 file staged 만 (code/test/prompt 변경 0)
git diff --cached --name-only   # 위 5 docs 만

# Gate W2.2: W2 self-hash 부재 — closure docs 안 W2 commit hash literal 0 (wording "W1-W2"/"W2 closure commit")

# Gate W2.3: backend 무변경 재확인 (venv python + PYTHONPATH)
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests/prompts/test_c9_scene_detail_body_light_verb.py -q
```

### 4.5 W2 Commit + W1-W2 range review + push

- commit message: `W2(c9-scene-detail-body-light-verb-v1): closure docs atomic — spec/plan status closed + roadmap §5.16 + fix-critical-1 C9 marker + audit 03 L-7 closure (5 docs path-limited)`
- commit 후 Codex W1-W2 range review 송신 → APPROVED_FOR_PUSH.
- APPROVED_FOR_PUSH 시 사용자 ask 0 즉시 push ([[feedback_push_no_user_ask]]).
- push 후 §5 Closure / external memory 기록 + Codex pane `clear` 요청 (controller(claude %1) 세션 대상 — claude 는 자기 세션만 담당, [[feedback_never_clear_codex_session]]).

## 5. Closure (2026-05-20+)

**Status: closed** — C9 v1 W1-W2 atomic execution 완료. 종합 closure 는 spec §10.

- W1 `04016da` — 10 file (v31 prompt-pack 2 + code 2 + test 6), 963+/80-. Gate W1.1-W1.5 PASS (W1.5 5 failures = clean HEAD `81bde22` baseline 동일, C9 신규 0).
- W2 closure commit — closure docs atomic (path-limited 5 docs: 본 plan + spec + roadmap §5.16 + index.html C9 marker + audit 03 L-7). W2 self-hash 금지 — push 후 external memory.
- Codex — W1 entry sanity `APPROVED_TO_ENTER_W1` / W1 per-wave `APPROVED_FOR_W2_ENTRY` / W1-W2 range review (W2 후).
- 함정 — alignment occurrence 실제 16 (§2.3 의 14 는 `latest_major == "30"` assert 2건 누락, W1 broad scan 보정) / boundary preserve string 기준 (Rule B 축약으로 줄번호 이동) / version_registry `updated_at` 주석 동기. spec §10.4 참조.

## 6. Doctrine references

- [[feedback_llm_based_judgment]] — 4-Gate (Prompt Closed-List Ban). C9 = Rule B body-light closed verb list + 예문 목록 + recommended verb list 폐기.
- [[feedback_no_vlm_dependency]] — NO VLM. C9 코드·테스트 VLM 의존 0.
- [[feedback_codex_mcp_discussion_workflow]] / [[feedback_codex_mcp_claude_mcp_response_trigger]] — 매 wave Codex per-wave review, tmux-bridge raw typing + prefix/suffix.
- [[feedback_no_user_ask_codex_only]] — OQ·결정 사용자 ask 0, Codex MCP 의논.
- [[feedback_push_no_user_ask]] — APPROVED_FOR_PUSH 즉시 push.
- [[feedback_channel_separation_4way]] — 4채널 fact source 구분.
- [[project_fix_critical_1_persistent]] — fix-critical-1 Tier β #6, C9 → C4 priority.
