---
title: C5 — Action segment / still-moment prompt hygiene v1 implementation plan
date: 2026-05-20+
status: closed (C5 v1 plan — W1-W4 실행 완료, Codex per-wave 전수 APPROVED. closure 종합 = spec §10.)
spec_ref: docs/superpowers/specs/2026-05-20-c5-action-segment-sot-v1-design.md
fix_critical_doc_ref: docs/fix-critical-1/index.html C5 section
head_anchor: origin/main HEAD `5f6b68b` (C4 v1 closed)
---

# C5 — Action segment / still-moment prompt hygiene v1 implementation plan

## 1. Purpose + Spec Reference

spec `docs/superpowers/specs/2026-05-20-c5-action-segment-sot-v1-design.md` 의 W1-W4 4-wave 실행 계획. **옵션 B narrow** (Codex C5 entry sanity) — closed list → generic semantic principle, 신규 `action_segment[]` schema 0. 5 audit row 해소 (A064/A068 `shot_extract` / A082/A083 `shot_validator` / A042 `scene_detail`). A069 = C8 carry.

**Codex review trace (plan 진입 전)**:
- C5 entry sanity → `APPROVED_FOR_SPEC_DRAFTING_WITH_NARROW_GUARDS` (옵션 B 확정 + 4-wave + version_registry sync + boundary).
- C5 spec v1 review → `APPROVED_FOR_PLAN` — OQ-C5-A APPROVED (active contact `:113-115` lexical bullet 만 collapse), OQ-C5-B APPROVED WITH PLAN NOTE (config_hash mechanism 미도입 + plan note 의무), NO BLOCKING / NO SPEC REVISION.

**Codex spec review 흡수 — non-blocking plan guards**:
- (G-1) W1/W2 loader/source proof — `load_schema()` 호출만으로 schema source version 증명 금지. v13/v6 sibling file existence + sha256 + `_list_module_versions()`/explicit path check 병용.
- (G-2) W3 occurrence inventory — spec 예시보다 넓게: `31.202605200805` / `31.` / `scene_detail/v31` / `1.31.0` / `latest_major == "31"` / `!= '31'` 류 모두 enumerate 후 실제 hit list 를 SSOT 로. (§5.2)
- (G-3) `shot_validator` W2 residue gate — `scene_detail` 예시·old history·docs global grep 금지, latest active pack path-scoped slice 만 판정.

**Plan note (OQ-C5-B 의무)**: `ShotExtractStep`/`ShotValidatorStep` 는 `_config_hash()` / `PROMPT_VERSION` code 상수 부재 — config_hash = `compute_config_hash(project_config)` fallback. **W1/W2 prompt-pack bump 는 기존 `shot_extract`/`shot_validator` checkpoint 를 자동 stale 처리하지 않는다** — 기존 episode 에 C5 prompt 를 적용하려면 operator force/rerun 필요. 추상화는 출력 shape/consumer contract 관점에서 안전 (intent-preserve) 이나, 자동 cp 무효화는 일어나지 않음. closure docs 에 동일 1줄 명시.

## 2. Plan Iter Trace

- plan v1 draft → Codex plan review iter 1 `NEEDS_REVISION_NARROW_1` (BLOCKING — 교체 wording 4곳 §4.3(b/c/d)·§5.4(b) 가 old lexicon 을 한국어 mini-list 로 재도입 / IMPORTANT — residue gate 한국어 needle 누락 + §5.2 W3 per-wave report 의무).
- amend 1 (narrow) — §4.3(b/c/d)+§5.4(b) wording 을 Codex 제시 category-free 추상화로 정정 / Gate W1.3·W2.3·W3.3 한국어 split-string absence needle 추가 / §5.2 W3 per-wave report 의무 1문장 추가. → Codex re-review → `APPROVED_FOR_EXECUTION`.
- W1 execution-time amend (Codex `OPTION_1_APPROVED`, spec §3.7) — `shot_schema.json` v13 통합이 `test_prompt_schema_openai_strict` 의 pre-existing dormant 위반 (`characters` required 누락) 을 노출 → schema 미통합 (v13 = system.md+user.md only, v10 per-stem fallback) 으로 정정. spec §1.2/§1.3/§3.7/§4.4/§6/§7 + plan §3.2/§3.3/§3.4/Gate W1.3/§3.7/§7 narrow amend. `test_area_7b_no_drift.py` (alignment pin, plan W0 미열거) W1 plan-gap 흡수.
- W1-W4 실행 완료 — W1 `cfb9184` / W2 `086ab0a` / W3 `2f41467` + W3 fix-up 1 `3d901cc` / W4 closure docs (본 commit). W1 per-wave `NEEDS_REVISION_NARROW_1`(spec §5.1)→re-review APPROVED / W2 per-wave APPROVED / W3 per-wave `NEEDS_REVISION_NARROW_1`(version_registry comment)→fix-up 1→re-review APPROVED. closure 종합 + 함정 = spec §10.

## 3. W1 — `shot_extract` v13 prompt-pack (1 atomic commit)

### 3.1 Pre-W1 Entry Sanity

- Codex `APPROVED_FOR_EXECUTION` 후 진입. HEAD `5f6b68b` 확인. `W1_UTC = $(date -u +%Y%m%d%H%M)` 1회 생성.

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

| file | op |
|------|-----|
| `prompts/_base/shot_extract/13.<W1_UTC>/system.md` | 신규 (v12 cp + A068 추상화) |
| `prompts/_base/shot_extract/13.<W1_UTC>/user.md` | 신규 (v12 cp + A064 추상화) |
| `backend/app/core/version_registry.py` | modify (`shot_extractor` 2-point) |
| `backend/tests/prompts/test_c5_action_segment_sot.py` | 신규 (W1 gate) |
| `backend/tests/integration/test_area_7b_no_drift.py` | modify (plan-gap absorb — `NEW_DIR_EXPECTED["shot_extract"]` `12.`→`13.` latest-activation canary) |

> **W1 OQ blocker (Codex `OPTION_1_APPROVED`, spec §3.7)**: `shot_schema.json` 은 v13 에 통합하지 않음 — v13 = `system.md` + `user.md` only. v10 schema 통합 시 `test_prompt_schema_openai_strict.py` 가 pre-existing dormant 위반 (`characters` required 누락) 을 노출 → schema 미통합 + v10 per-stem fallback 유지. `test_area_7b_no_drift.py` 는 plan W0 미열거 alignment pin — W1 plan-gap 흡수 (per-wave report 명시).

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

```bash
# repo-root cwd. W1_UTC = W1 실행 시점 1회 생성. shot_schema.json 은 cp 안 함 (W1 OQ blocker — 미통합).
cp -r prompts/_base/shot_extract/12.202605181937 prompts/_base/shot_extract/13.${W1_UTC}
```

**user.md 추상화** — `[절대 규칙 — 단일 정지 순간]` 블록 내 2개 닫힌 목록 줄 (`- 시간 연결어 절대 금지: "~하자" / …` + `- 영어 금지: "and then", …`) → generic principle 1줄:

```
- 시간적으로 분리된 두 개 이상의 동작·순간을 한 description에 잇지 마세요 — 순차·전후·동시진행·인과 등 시간 흐름을 나타내는 표현(언어·형태 불문)은 한 찰나 원칙 위반입니다
```

블록 header (`[절대 규칙 — 단일 정지 순간]`) + `한 Shot의 description에는…` + `진행형 묘사 금지` 줄 + `한 프레임에 담길 수 있는…` 줄 보존.

**system.md 추상화** — `## 시간 연결어 절대 금지` 섹션의 WHY 줄 + 3개 닫힌 목록 bullet (`:16-18`) → generic principle. header `## 시간 연결어 절대 금지` 보존, body 치환:

```
## 시간 연결어 절대 금지
description이 시간적으로 분리된 두 개 이상의 동작·순간을 잇고 있으면 **두 개 이상의 순간이 섞인 것**입니다 — 순차·전후·동시진행·인과 등 시간 흐름을 나타내는 표현(언어·형태 불문)은 한 찰나 원칙 위반이므로 절대 사용 금지.

하나의 Shot description은 **단일 동사/상태**로만 표현되어야 합니다.
```

`## 분해 기준` 이하 섹션 + `## 변형 기준` (A069 — 외모·연령 변화, **byte-for-byte 불변, C5 scope 외**) 보존.

### 3.4 version_registry sync (W1.2)

`MODULE_VERSIONS["shot_extractor"]`:
```
# before
    "shot_extractor": "2.1.0",            # 2026-04-20 — v11 prompt: 시나리오 의존 예시 범용화 ...
# after
    "shot_extractor": "2.2.0",            # 2026-05-20 — C5 v1: v13 prompt — 시간 연결어 닫힌 목록 추상화 (generic still-moment principle, A064/A068). v13 = system.md+user.md only; shot_schema.json 은 v10 per-stem fallback 유지. 이전: 2.1.0 v11.
```
`_MODULE_INFO["shot_extractor"]` — `prompt_dependency` `"shot_extract/v11"`→`"shot_extract/v13"`, `updated_at` → `"2026-05-20"`.

### 3.5 C5 regression test 신설 (W1.3)

`backend/tests/prompts/test_c5_action_segment_sot.py` 신설 — W1 gate (G1-G3 + G_reg_W1 + G_loader_W1, §7).

### 3.6 W1 Pre-commit Gate

```bash
# Gate W1.1: C5 test (W1 gate) PASS
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests/prompts/test_c5_action_segment_sot.py -q

# Gate W1.2: shot_extract step/pipeline regression
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests -k "shot_extract or beat_shot or shot_extractor" -q

# Gate W1.3: residue 증명 — v13 prompt-pack path-scoped (split-string self-hit 방지)
PYTHONPATH=backend backend/.venv/bin/python - <<'PY'
from pathlib import Path
import glob
d = sorted(glob.glob("prompts/_base/shot_extract/13.*"))[-1]
sysmd = Path(f"{d}/system.md").read_text(encoding="utf-8")
usermd = Path(f"{d}/user.md").read_text(encoding="utf-8")
assert ('"and then", ' + '"while ~ing"') not in sysmd, "A068 영어 시간 연결어 목록 잔존(system)"
assert ('"and then", ' + '"while ~ing"') not in usermd, "A064 영어 시간 연결어 목록 잔존(user)"
assert ('"~하자" / ' + '"~하면서"') not in usermd, "A064 한국어 시간 연결어 목록 잔존(user)"
assert ('"~하자", ' + '"~하면서"') not in sysmd, "A068 한국어 시간 연결어 목록 잔존(system)"
assert ('"~하려는 ' + '찰나"') not in sysmd, "A068 찰나형 시간 연결어 잔존(system)"
assert "단일 동사/상태" in sysmd, "still-moment 원칙 손실(system)"
assert "단일 정지 순간" in usermd, "still-moment 원칙 손실(user)"
# W1 OQ blocker — shot_schema.json 은 v13 에 미통합 (v10 per-stem fallback 유지)
assert not Path(f"{d}/shot_schema.json").exists(), "v13 에 shot_schema.json 통합 — OQ blocker 옵션 1 위반"
print("Gate W1.3 OK")
PY

# Gate W1.4: 백엔드 전체 회귀 (pre-existing failure 는 clean HEAD 5f6b68b git stash 대조)
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests -q
```

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

- commit message: `W1(c5-action-segment-sot-v1): shot_extract v13 prompt-pack — 시간 연결어 닫힌 목록 추상화 (A064/A068, generic still-moment principle) + version_registry sync + C5 test + area_7b no-drift canary sync (5 file)`
- staged: §3.2 표 5 file. cwd = repo root 확인 후 `git add` (path 명시).
- commit 후 Codex W1 per-wave review → `APPROVED_FOR_W2_ENTRY`.

## 4. W2 — `shot_validator` v6 prompt-pack (1 atomic commit)

### 4.1 Pre-W2 Entry Sanity

- W1 per-wave `APPROVED_FOR_W2_ENTRY` 후 진입. `W2_UTC` 1회 생성.

### 4.2 W2 File Operations (2 신규 prompt + 1 code + 1 test modify = 4 file, 1 atomic commit)

| file | op |
|------|-----|
| `prompts/_base/shot_validator/6.<W2_UTC>/system.md` | 신규 (v5 cp + A082/A083 추상화) |
| `prompts/_base/shot_validator/6.<W2_UTC>/validator_schema.json` | 신규 (v5 cp, byte-identical) |
| `backend/app/core/version_registry.py` | modify (`shot_validator` 2-point) |
| `backend/tests/prompts/test_c5_action_segment_sot.py` | modify (W2 gate append) |

### 4.3 v6 prompt-pack 신설 (W2.1)

```bash
cp -r prompts/_base/shot_validator/5.202605081700 prompts/_base/shot_validator/6.${W2_UTC}
```

**system.md 추상화 4개 site** (`6.<W2_UTC>/system.md`):

**(a) `## 시간 연결어 절대 금지 (순차 동작 연결)` 섹션** — header 보존, WHY + 3 닫힌 목록 bullet 치환:
```
## 시간 연결어 절대 금지 (순차 동작 연결)
description이 **두 동작 사이의 시간 순서**(순차·전후·동시진행·인과)를 나타내고 있으면 위반 — 재작성 대상. 시간 흐름을 잇는 표현은 언어·형태 불문하고 두 순간이 섞인 것으로 판정한다.
```
`## 결과 상태 묘사는 허용` 섹션 (`~한 채` OK/NG 판단기준) 보존.

**(b) `## 동적 동사 freeze 규칙` 섹션** — header + WHY paragraph 보존, `대상 동작 카테고리 (어휘는 다양 …)` disclaimer + 5 카테고리 lexicon bullet 치환:
```
대상은 인물이 공간을 가로지르거나 몸을 추진하는 모든 이동·추진 동작입니다. 특정 동사나 교통/지형/매체별 목록이 아니라 원문 의미로 판정합니다.
```
`### 금지` / `### 권장` freeze 예시 (mid-action) 보존.

**(c) `## Active contact freeze rule` `### 카테고리` 블록** (OQ-C5-A) — `:111` disclaimer header 보존, lexical bullet 3개 (찌르기/타격/제압) → 기존 generic 4번째 bullet 로 collapse:
```
### 카테고리 (가이드일 뿐, 어휘 매트릭스에 hardcode 의존하지 말고 의미 기반으로 판정)

- 능동적 신체 접촉 일반: 원문에 능동 동작, 신체 접촉 지점, 힘의 방향 또는 영향받은 자세/불균형이 함께 드러나는 표현. 특정 폭력 유형이나 어휘 목록이 아니라 의미로 판정합니다.
```
`### 사용 가능한 시각 단서` / `### 금지` / `### 권장` / `### 추가 금지` / `### 적용 조건` / `### 예외` (force/contact-point/imbalance/단서-발명-금지/`character_ids` 양쪽) contract **변경 0**.

**(d) `### visible-human-action 판정 기준` 블록** — 닫힌 lexicon 3 bullet (신체 부위 / 동작 동사 / type descriptor) 치환:
```
### visible-human-action 판정 기준

description이 사람의 신체적 행동·존재를 시각적으로 묘사하면 visible-human-action으로 판정합니다. 특정 신체 부위명, 동작 동사, 상호작용 유형 목록이 아니라 프레임 안에서 사람의 몸/행위/자세/존재가 의미상 드러나는지로 판정합니다.
```
`### 처리 절차` + `### fail-fast 조건` + `## Type descriptor → entity ID 매핑` contract **변경 0**. `visible-human-action` 개념명 보존 (다운스트림 참조).

### 4.4 version_registry sync (W2.2)

`MODULE_VERSIONS["shot_validator"]`:
```
# after
    "shot_validator": "1.5.0",            # 2026-05-20 — C5 v1: v6 prompt — 시간 연결어·locomotion·active-contact·visible-human-action 닫힌 lexicon 추상화 (generic semantic principle, A082/A083). contract 변경 0. 이전: 1.4.0 v4.
```
`_MODULE_INFO["shot_validator"]` — `prompt_dependency` `"shot_validator/v4"`→`"shot_validator/v6"`, `updated_at` → `"2026-05-20"`.

### 4.5 C5 test W2 gate append (W2.3)

`test_c5_action_segment_sot.py` — W2 gate (G4-G8, §7) append.

### 4.6 W2 Pre-commit Gate

```bash
# Gate W2.1: C5 test (W1+W2 gate) PASS
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests/prompts/test_c5_action_segment_sot.py -q

# Gate W2.2: shot_validator step/pipeline regression
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests -k "shot_validator" -q

# Gate W2.3: residue 증명 — v6 prompt-pack path-scoped only (G-3: scene_detail 예시·history global grep 금지)
PYTHONPATH=backend backend/.venv/bin/python - <<'PY'
from pathlib import Path
import glob, hashlib
d = sorted(glob.glob("prompts/_base/shot_validator/6.*"))[-1]
sysmd = Path(f"{d}/system.md").read_text(encoding="utf-8")
assert ('"~하자", ' + '"~하면서"') not in sysmd, "A082 시간 연결어 목록 잔존"
assert ("running / sprinting" + " / walking") not in sysmd, "A082 locomotion 카테고리 lexicon 잔존(영문)"
assert ("stabbing, slashing" + ", piercing") not in sysmd, "A082 active contact 찌르기 lexicon 잔존(영문)"
assert ("punching, striking" + ", slamming") not in sysmd, "A082 active contact 타격 lexicon 잔존(영문)"
assert ("face, hand, leg" + ", arm") not in sysmd, "A083 visible-human-action 신체부위 lexicon 잔존(영문)"
assert ("hold, look, talk" + ", embrace") not in sysmd, "A083 visible-human-action 동작 lexicon 잔존(영문)"
# 한국어 needle — old lexicon 한국어 잔존 + plan §4.3 fix wording 의 mini-list 재도입 둘 다 차단
assert ("찌름, " + "베기, 칼날") not in sysmd, "A082 active contact 한국어 lexicon 잔존(찌름/베기/칼날)"
assert ("제압, 목" + "조름") not in sysmd, "A082 active contact 한국어 lexicon 잔존(제압/목조름)"
assert ("얼굴, 손, " + "다리, 팔") not in sysmd, "A083 visible-human-action 신체부위 한국어 lexicon 잔존"
assert ("잡기, 보기, " + "말하기") not in sysmd, "A083 visible-human-action 동작 한국어 lexicon 잔존"
assert ("걷기·" + "달리기") not in sysmd, "locomotion 한국어 mini-list 재도입 (plan §4.3(b) fix 위반)"
assert ("찌르기·" + "베기·타격") not in sysmd, "active contact 한국어 mini-list 재도입 (plan §4.3(c) fix 위반)"
assert ("폭력·친밀·" + "대화·응시") not in sysmd, "visible-human-action 한국어 mini-list 재도입 (plan §4.3(d) fix 위반)"
# contract canary — 보존 확인
for k in ["force direction".replace(" direction",""), "Active contact freeze rule", "fail-fast", "visible-human-action", "결과 상태 묘사는 허용"]:
    assert k in sysmd, f"contract/canary 손실: {k}"
v5 = Path("prompts/_base/shot_validator/5.202605081700/validator_schema.json").read_bytes()
v6 = Path(f"{d}/validator_schema.json").read_bytes()
assert hashlib.sha256(v5).hexdigest() == hashlib.sha256(v6).hexdigest(), "validator_schema.json byte-identical 위반"
print("Gate W2.3 OK")
PY

# Gate W2.4: 백엔드 전체 회귀
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests -q
```

### 4.7 W2 Commit + per-wave Codex review

- commit message: `W2(c5-action-segment-sot-v1): shot_validator v6 prompt-pack — 시간 연결어·locomotion·active-contact·visible-human-action 닫힌 lexicon 추상화 (A082/A083, generic semantic principle, contract 보존) + version_registry sync + C5 test (4 file)`
- staged: §4.2 표 4 file.
- commit 후 Codex W2 per-wave review → `APPROVED_FOR_W3_ENTRY`.

## 5. W3 — `scene_detail` v32 prompt-pack (1 atomic commit)

### 5.1 Pre-W3 Entry Sanity

- W2 per-wave `APPROVED_FOR_W3_ENTRY` 후 진입. `W3_UTC` 1회 생성.

### 5.2 W3 occurrence inventory SSOT (G-2 — C9 trap N-1 재발 방지)

W3 실행 시점에 broad grep 으로 실제 hit list 확정 후 SSOT 로:
```bash
grep -rn "scene_detail_composer\|scene_detail/v31\|1\.31\.0\|31\.202605200805\|latest_major\|SCENE_DETAIL_PROMPT_VERSION" backend/tests backend/app | grep -v pycache
```
**분류 규칙**: (i) **alignment pin** (latest 추종 — `1.31.0` / `scene_detail/v31` / `latest_major == "31"` / `SCENE_DETAIL_PROMPT_VERSION` 상수) → v32 갱신. (ii) **historical pin** (`_resolve_latest_major_pack("scene_detail","29"/"30")` 등 특정 major 고정) → **변경 0** (해당 버전 dir 존속). (iii) **dynamic** (`_list_module_versions()[0]` 로 latest 산출 — `test_scene_detail_id_policy_alignment.py`) → 변경 0.

plan W0 (HEAD `5f6b68b`) 확정 alignment-pin 파일 **7개**:

| file | 갱신 대상 |
|------|-----------|
| `backend/app/core/version_registry.py` | `MODULE_VERSIONS["scene_detail_composer"]` `1.31.0`→`1.32.0` + comment / `_MODULE_INFO` `prompt_dependency` `scene_detail/v31`→`v32` |
| `backend/app/core/steps/detail_steps.py` | `:107` `SCENE_DETAIL_PROMPT_VERSION` `"31.202605200805"`→`"32.<W3_UTC>"` + comment. `:106` `SCENE_DETAIL_SCHEMA_VERSION=12` **불변** |
| `backend/tests/test_prompt_versions.py` | `1.31.0`→`1.32.0` assert + comment |
| `backend/tests/integration/test_g4_5a_spatial_integration.py` | `1.31.0`/`scene_detail/v31` assert + docstring + f-msg |
| `backend/tests/prompts/test_c9_scene_detail_body_light_verb.py` | `1.31.0`/`scene_detail/v31` alignment assert + f-msg → v32. **`v30_hash == v31_hash` (`:132`) 는 historical fact — 변경 0** |
| `backend/tests/prompts/test_scene_detail_spatial_alignment.py` | `1.31.0`/`scene_detail/v31`/`latest_major == "31"` assert + docstring + f-msg |
| `backend/tests/prompts/test_scene_detail_continuity_alignment.py` | 동일 |

> 변경 0 확인된 파일 (schema_version=12 만 참조, alignment pin 부재): `test_consumer_verify_completion.py` / `test_d6_consumer_hash_stamps.py` / `test_g4_1_card_consumer_wiring.py` / `test_g4_2_bg_binding_integration.py` / `test_scene_detail_verify_origin.py` / `step_manifest.py` / `test_c1_*` / `test_c2_*` (historical major pin) / `test_scene_detail_id_policy_alignment.py` (dynamic). W3 실행 시 broad grep 재확인.

**W3 entry sanity / per-wave report 의무**: W3 실행 시 위 broad grep 결과를 파일별로 저장·요약하고, 각 hit 의 `alignment pin / historical pin / dynamic` 분류 결과를 W3 per-wave Codex report 에 포함한다 — plan 표 7개 파일만 신뢰하지 말고 실행 시점 hit list 를 SSOT 로 재확정 (C9 trap N-1 재발 방지).

### 5.3 W3 File Operations (2 신규 prompt + 2 code + 6 test = 10 file, 1 atomic commit)

`prompts/_base/scene_detail/32.<W3_UTC>/{system.md,detail_schema.json}` 신규 + §5.2 표 7 alignment 파일 (그 중 `test_c5_action_segment_sot.py` 는 §5.2 표 외 — W3 gate append) = prompt 2 + code 2 (`version_registry.py`, `detail_steps.py`) + test 6 (`test_prompt_versions.py`, `test_g4_5a_spatial_integration.py`, `test_c9_*`, `test_scene_detail_spatial_alignment.py`, `test_scene_detail_continuity_alignment.py`, `test_c5_action_segment_sot.py`).

### 5.4 v32 prompt-pack 신설 (W3.1)

```bash
cp -r prompts/_base/scene_detail/31.202605200805 prompts/_base/scene_detail/32.${W3_UTC}
```

**system.md 추상화 2개 site** (`32.<W3_UTC>/system.md`):

**(a) `**회피 원칙**` 줄 (`:373`)** — `(running / riding / walking / swimming 류)` lexical 괄호 제거:
```
**회피 원칙**: 입력 description이 인물의 이동·추진 동작이나 "동작A하며 동작B" 같은 두 동작 합성 표현을 묘사하면, 그 상태의 **mid-action 정지** (motion direction 보존) 또는 **인물의 반응**으로 re-frame 가능. 단, 입력이 동적 동작을 묘사하면 freeze 시 motion direction을 보존하도록 — `mid-stride`, `mid-pedal`, `hair flowing in the direction opposite to motion` 등의 표현으로.
```

**(b) `## 동작 동사 freeze` 섹션 (`:543`)** — header 보존, dynamic verb backtick 7종 닫힌 목록 제거:
```
shot description이 인물의 이동·추진 동작을 명시한 인물의 freeze 순간을 묘사할 때, 정지 자세로 변환하더라도 **motion direction**을 자세 묘사에 포함한다.
```
`### 금지` / `### 권장` / `### 핵심 원칙` (mid-stride/mid-pedal/mid-row freeze 예시) **보존** — illustrative 예시, 닫힌 분류 목록 아님.

`detail_schema.json` byte-identical (cp 후 sha256 == v31 확인).

### 5.5 4-point cascade (W3.2)

§5.2 표 7 파일 alignment pin v32 갱신. `detail_steps.py:107` `SCENE_DETAIL_PROMPT_VERSION = "32.<W3_UTC>"`, `:106` `SCENE_DETAIL_SCHEMA_VERSION = 12` 불변. `version_registry` `scene_detail_composer` `1.32.0` + comment (`C5 v1: v32 — dynamic verb 닫힌 목록 추상화. schema_version 12 유지. 이전: 1.31.0 C9`) + `prompt_dependency scene_detail/v32`.

### 5.6 C5 test W3 gate append (W3.3)

`test_c5_action_segment_sot.py` — W3 gate (G9-G10, §7) append.

### 5.7 W3 Pre-commit Gate

```bash
# Gate W3.1: C5 test (W1+W2+W3 gate) PASS
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests/prompts/test_c5_action_segment_sot.py -q

# Gate W3.2: scene_detail alignment + step regression
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests/prompts/test_scene_detail_spatial_alignment.py backend/tests/prompts/test_scene_detail_continuity_alignment.py backend/tests/prompts/test_scene_detail_id_policy_alignment.py backend/tests/test_prompt_versions.py backend/tests/integration/test_g4_5a_spatial_integration.py backend/tests/prompts/test_c9_scene_detail_body_light_verb.py -q

# Gate W3.3: residue 증명 — v32 prompt-pack path-scoped (bare `running` global grep 금지)
PYTHONPATH=backend backend/.venv/bin/python - <<'PY'
from pathlib import Path
import glob, hashlib
d = sorted(glob.glob("prompts/_base/scene_detail/32.*"))[-1]
sysmd = Path(f"{d}/system.md").read_text(encoding="utf-8")
assert ("`running`, " + "`riding`") not in sysmd, "A042 dynamic verb backtick 목록 잔존 (:543)"
assert ("running / riding " + "/ walking") not in sysmd, "A042 dynamic verb slash 목록 잔존 (:373)"
assert ("걷기·달리기·" + "탈것") not in sysmd, "A042 이동 동작 한국어 mini-list 재도입 (plan §5.4(b) fix 위반)"
assert "motion direction" in sysmd and "mid-stride" in sysmd, "motion-freeze 원칙/예시 손실"
v31 = Path("prompts/_base/scene_detail/31.202605200805/detail_schema.json").read_bytes()
v32 = Path(f"{d}/detail_schema.json").read_bytes()
assert hashlib.sha256(v31).hexdigest() == hashlib.sha256(v32).hexdigest(), "detail_schema.json byte-identical 위반"
from app.core.steps.detail_steps import SCENE_DETAIL_PROMPT_VERSION, SCENE_DETAIL_SCHEMA_VERSION
assert SCENE_DETAIL_PROMPT_VERSION.startswith("32."), "SCENE_DETAIL_PROMPT_VERSION v32 미갱신"
assert SCENE_DETAIL_SCHEMA_VERSION == 12, "SCENE_DETAIL_SCHEMA_VERSION 불변 위반"
print("Gate W3.3 OK")
PY

# Gate W3.4: 백엔드 전체 회귀
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests -q
```

### 5.8 W3 Commit + per-wave Codex review

- commit message: `W3(c5-action-segment-sot-v1): scene_detail v32 prompt-pack — dynamic verb 닫힌 목록 추상화 (A042, generic motion principle) + 4-point version cascade (7 alignment 파일) + C5 test (10 file)`
- staged: §5.3 10 file.
- commit 후 Codex W3 per-wave review → `APPROVED_FOR_W4_ENTRY`.

## 6. W4 — integrated gate + closure docs atomic (1 atomic commit, path-limited)

### 6.1 Pre-W4 Entry Sanity

- W3 per-wave `APPROVED_FOR_W4_ENTRY` 후 진입.

### 6.2 W4 File Operations (4 docs, 1 atomic commit)

| file | op |
|------|-----|
| `docs/superpowers/specs/2026-05-20-c5-action-segment-sot-v1-design.md` | status `closed` + §10 Closure |
| `docs/superpowers/plans/2026-05-20-c5-action-segment-sot-v1-implementation.md` | status `closed` + §2 iter trace |
| `docs/superpowers/specs/2026-05-16-track-b-semantic-debt-roadmap-design.md` | §5.9 closed entry |
| `docs/fix-critical-1/index.html` | C5 section closed marker (`action_segment[]` 원안 superseded 명시) |

### 6.3 W4 Pre-commit Gate

```bash
# Gate W4.1: C5 test 전체 PASS
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests/prompts/test_c5_action_segment_sot.py -q

# Gate W4.2: 백엔드 전체 회귀 — C5 신규 failure 0 (clean HEAD 5f6b68b baseline 대조)
PYTHONPATH=backend backend/.venv/bin/python -m pytest backend/tests -q

# Gate W4.3: closure docs staged scope — 4 docs only
git -c core.pager=cat diff --cached --name-only
```

### 6.4 W4 Commit + range review + push

- commit message: `W4(c5-action-segment-sot-v1): closure docs atomic — spec/plan status closed + roadmap §5.9 + fix-critical-1 C5 marker (4 docs path-limited)`
- W4 commit 후 Codex W1-W4 range review → `APPROVED_FOR_PUSH`.
- `APPROVED_FOR_PUSH` 시 사용자 ask 0 즉시 `git push` ([[feedback_push_no_user_ask]]).
- push 후 closure memory + Codex memory parallel update + Codex pane clear 요청.

## 7. Test Gates — `test_c5_action_segment_sot.py` (G1-G10)

전부 static (NO VLM, no live LLM). W1-W3 commit 분산 동승.

**W1 (shot_extract v13)**
- **G1** — `13.*/user.md`: 시간 연결어 닫힌 목록 (한국어 `"~하자" / "~하면서"` + 영어 `"and then", "while ~ing"`) absent, `단일 정지 순간` 원칙 present. (path-scoped, split-string)
- **G2** — `13.*/system.md`: 시간 연결어 닫힌 목록 absent, `## 시간 연결어 절대 금지` header + `단일 동사/상태` 원칙 present.
- **G3** — `13.*/` = `system.md` + `user.md` only; `shot_schema.json` v13 미통합 (W1 OQ blocker 옵션 1 — explicit absence check).
- **G_reg_W1** — `version_registry` `MODULE_VERSIONS["shot_extractor"]=="2.2.0"`, `_MODULE_INFO["shot_extractor"]["prompt_dependency"]=="shot_extract/v13"`.
- **G_loader_W1** — `system`/`user` stem v13 + `shot_schema` stem v10 per-stem fallback resolve (`_resolve_stem_in_pack`); `load_prompt`/`load_schema` RuntimeError 0; `_list_module_versions("shot_extract")[0]` major == `13`.

**W2 (shot_validator v6)**
- **G4** — `6.*/system.md`: 시간 연결어 닫힌 목록 absent, `## 시간 연결어 절대 금지 (순차 동작 연결)` header + `결과 상태 묘사는 허용` 섹션 present.
- **G5** — locomotion 5 카테고리 lexicon absent, `이동·추진 동작` generic principle + `## 동적 동사 freeze 규칙` header present.
- **G6** — active contact lexical bullet (`stabbing, slashing` / `punching, striking` / `pinning, choking`) absent; `:111` disclaimer + active contact contract canary (`Active contact freeze rule`, force/contact-point/imbalance) present.
- **G7** — visible-human-action 신체 부위·동작 동사 lexicon absent; `visible-human-action` 개념명 + fail-fast/repair contract canary present.
- **G8** — `6.*/validator_schema.json` sha256 == v5; `version_registry` `shot_validator=="1.5.0"` + `prompt_dependency=="shot_validator/v6"`; `load_prompt("shot_validator","system")` + `load_schema("shot_validator","validator_schema")` resolve; `_list_module_versions("shot_validator")[0]` major == `6`.

**W3 (scene_detail v32)**
- **G9** — `32.*/system.md`: dynamic verb backtick 목록 (`` `running`, `riding` ``) + slash 목록 (`running / riding / walking`) absent (path-scoped — bare `running` global grep 금지); `motion direction` 원칙 + mid-action freeze 예시 (`mid-stride`) canary present.
- **G10** — `32.*/detail_schema.json` sha256 == v31; `SCENE_DETAIL_PROMPT_VERSION` major `32` + `SCENE_DETAIL_SCHEMA_VERSION==12`; `version_registry` `scene_detail_composer=="1.32.0"` + `prompt_dependency=="scene_detail/v32"`; `_list_module_versions("scene_detail")[0]` major == `32`; `load_prompt`/`load_schema` v32 resolve.

**Integrated (W4)** — 백엔드 전체 회귀 C5 신규 failure 0. pre-existing failure 는 clean HEAD `5f6b68b` git stash baseline 대조 확정.

## 8. Doctrine references + 함정 주의

- [[feedback_llm_based_judgment]] — Prompt Closed-List Ban. C5 = closed-list-in-prompt 단독.
- [[feedback_no_vlm_dependency]] — 모든 gate static.
- [[feedback_codex_mcp_discussion_workflow]] / [[feedback_codex_mcp_claude_mcp_response_trigger]] — per-wave + range review Codex MCP 의논, 송신 prefix/suffix 의무.
- **함정 N-1 (residue split-string self-hit)**: residue gate assertion 의 literal 은 `("A" + "B")` 분할 — assertion 파일 자체가 residue 토큰 보유 시 self-hit. §3.6/§4.6/§5.7 적용.
- **함정 N-2 (gate bare python)**: 모든 gate `PYTHONPATH=backend backend/.venv/bin/python` — bare `python` 금지.
- **함정 N-3 (cwd drift)**: prompt-pack `cp` + `git add` 전 cwd = repo root 확인. `cd backend && pytest` 후 `git add` 시 `cd` 복귀.
- **함정 N-4 (W3 occurrence 누락 — C9 trap N-1)**: §5.2 broad grep SSOT 의무. spec 예시 line number 에 의존 X — 실 hit list.
- **함정 N-5 (prompt-pack cp 후 version-stamped self-description)**: `shot_extract`/`shot_validator`/`scene_detail` system.md header 에 version stamp 부재 확인됨 (C4 N-1 재발 risk 낮음) — 단 cp 후 새 dir 의 자기서술 문구 잔존 시 동기.
- **함정 N-6 (config_hash 무자동무효화)**: §1 plan note — W1/W2 prompt-pack bump 는 cp resume 자동 무효화 X. closure docs 명시.
- **함정 N-7 (alignment vs historical pin 혼동)**: §5.2 분류 규칙 — `_resolve_latest_major_pack(...,"29"/"30")` historical pin 은 변경 0. alignment pin 만 v32.
