# LLM-structured-SOT Migration Spec — Open-World Heuristic Eradication

**Status**: design v1.2 (H-small B-minus brainstorm carry → Area C pivot). 본 spec 은 **구현 디테일 미포함** — 각 area 의 implementation 은 별도 plan 분리.
**Date**: 2026-05-12
**Scope**: production code 9 area + prompt 4 area + R1 audit addendum (U1-U6) = 16 항목, 10+ area.
**Latest inventory source**: [`docs/superpowers/specs/2026-05-12-open-world-semantic-full-audit.md`](2026-05-12-open-world-semantic-full-audit.md) (R1, 2026-05-12). production `backend/app/` 237 file + `prompts/_base/` 505 file 전수 audit + active prompt pack 분류. 본 spec 의 inventory 가 정합 — 다음 area 진입 시 본 spec ↔ R1 audit 양쪽 확인 의무.
**Origin**: Patch C (S26/6 photo orientation) 초안의 noun-list classifier 접근이 사용자 reject → system-wide audit 결과 production 전체에 같은 brittle 패턴 잔존 발견 → 통합 migration spec 으로 확장 → R1 audit (2026-05-12) 가 6 누락 항목 (U1-U6) 발견 → 본 v1.1 흡수.

---

## 1. 본질 / 원칙

### 1.1 본질

scenario lab pipeline 이 **open-world 환경 (어떤 시나리오가 입력될지 사전에 알 수 없음)** 에서 silently 깨지지 않게 한다. code 가 keyword / regex 로 의미를 추측하면 새 시나리오의 novel 어휘 (snapshot / polaroid / 메모지 / 부적 / 위패 / 칠흑 등) 에 silently 누락 → 다음 시나리오마다 새 시각 결함이 무한 생성. **그 무한 회귀 차단** 이 본 spec 의 목적.

### 1.2 원칙

> **Open-world semantic 판단은 LLM-produced structured SOT.**
> Code 는 enum / ID / bool / object 같은 구조화된 결과만 소비한다.
> Closed-world 기계 contract (`C##` / `P##` ID, status enum, prompt version, schema shape, hash, file path) 는 code regex 가 맞다 — 본 rule 의 적용 대상이 **아님**.

이 원칙은 [[feedback_llm_based_judgment]] 와 동일. 본 spec 은 그 원칙의 **inventory + migration plan + 4 강제 gate** 까지 확장.

### 1.3 적용 / 미적용 경계

| 영역 | LLM SOT 필수 (open-world) | code regex OK (closed-world) |
|---|---|---|
| 의미 카테고리 분류 (story-critical / directional / spatial 등) | ✓ | — |
| 자연어 동작 / 시선 / 자세 / 신체부위 판정 | ✓ | — |
| 시나리오 텍스트 element / character / location 의미 추출 | ✓ | — |
| prop attach / ref binding 의 의미적 매칭 | ✓ | — |
| 예외 처리 (`if "X" in text` 같은 free-text scan 으로 분기) | ✓ | — |
| `C##` / `P##` / `L##` / `O##` / `C##O##` ID 매칭 | — | ✓ |
| status enum / prompt version / schema shape / hash / path | — | ✓ |
| LLM 이 이미 출력한 structured enum 값 비교 | — | ✓ |
| allowlist 가 닫힌 시스템 값일 때 exact match | — | ✓ |

---

## 2. Inventory — 사용자 audit 결과 (2026-05-12)

backend/app/**/*.py + prompts/_base/**/*.{md,json} 전체 audit. 13 영역 식별. 3 type 으로 분류.

### 2.1 Open-world semantic — LLM SOT migration 대상 (12 영역)

| ID | 위치 | 형태 | 본 spec area |
|---|---|---|---|
| **C1** | `backend/app/core/steps/render_prompt_card.py:326` `_STORY_CRITICAL_CATEGORY_GROUPS` | noun group dict (photo/photograph/picture/사진, document/paper/letter, map, key) | Area B |
| **C2** | `backend/app/core/steps/render_prompt_card.py:1770` story_critical gate | C1 의 noun list 를 if-in 분기 | Area B |
| **C3** | `backend/app/core/visible_entities_validator.py:230` reproduction_surface_rule.applies_to_surfaces + `backend/app/core/steps/render_prompt_card.py:150` surface list 생산 | photograph/poster/painting/portrait/monitor/TV/mirror/window reflection/projection 노운 리스트 | Area C |
| **C4** | `backend/app/core/steps/render_prompt_card.py:376` spatial rule | low/high/hip/camera/frame-edge/interaction/shared-anchor/close/wide keyword | Area E |
| **C5** | `backend/app/modules/pipeline/shot_visibility.py:36` gaze/off-camera | 한국어 동사 stem + body-part noun + directional tail + close-up marker regex | Area G |
| **C7** | `backend/app/core/ref_contract_validator.py:47` token bucket | character/background/object word lists | Area F |
| **C8** | `backend/app/services/scene_reference_service.py:50` keep_elements live person | role/person token regex | Area D |
| **C9** | `backend/app/services/scene_reference_service.py:549` prop attach legacy | P## / prop name substring + word-boundary | Area D |
| **P1** | `prompts/_base/shot_staging/8.202604201230/schema.json:53` + `system.md:164` directional examples | closed list (monitor, mirror, door, TV, window) | Area A |
| **P2** | `prompts/_base/scene_detail/21.202605062217/system.md:151` close framing keyword | code/RPC contract 와 결합 | **Area E** (P2 는 spatial rule 연결) |
| **P3** | `prompts/_base/shot_validator/5.202605081700/system.md:157` visible-human-action 어휘 | body part / action / type descriptor 예시 (단 :111 에 완화 문구 존재) | **Area H** (prompt hygiene) |
| **P4** | `prompts/_base/t2i_review/3.202605121200/scene_system.md:34` 검출 패턴 | LLM judge prompt 의 closed-list 형 예시 | **Area H** (prompt hygiene) |

### 2.2 Special migration (1 영역) — 즉시 제거 X, 별도 의사결정

| ID | 위치 | 형태 | 처리 |
|---|---|---|---|
| **C10** | `backend/app/modules/llm/safety.py:26` 안전 치환 | KO/EN token replacement list | **Area I (SPECIAL)**: semantic judgment 아님, policy rewrite. 즉시 제거 시 moderation 비용 / 실패율 ↑ — 별도 의사결정 / 측정 기반 마이그레이션 |

### 2.3 Scenario residue (1 영역) — 단순 cleanup

| ID | 위치 | 형태 | 처리 |
|---|---|---|---|
| **C6** | `backend/app/modules/pipeline/shot_visibility.py:54` 주석 작품 캐릭터명 잔재 | 작품 고유명사 (Patch A OOS cleanup 미수렴 잔재) | **Area J**: 단순 정리 |

### 2.4 Area 분류 정리

| Area | 영역 | 우선순위 | 의존성 |
|---|---|---|---|
| **A** | shot_staging `directionality_class` + `orientation` enum SOT 신설 (P1 fix) | 1st | base SOT, Area C/F 가 재사용 |
| **B** | render_prompt_card `story_critical_prop_filter` 폐기 (C1 + C2) | 2nd | upstream entity_canon 또는 shot SOT 신규 field 필요 |
| **C** | visible_entities_validator reproduction_surface_rule (C3) | 3rd | Area A SOT 재사용 |
| **D** | scene_reference_service (C8 + C9) | 4th | Area B 의 required_refs SOT 의존 |
| **E** | render_prompt_card spatial rule (C4) + scene_detail close framing (P2) | 5th | G4.5a 영역, 크기 큼 |
| **F** | ref_contract_validator token bucket (C7) | 6th | 보조 guard, 후순위 |
| **G** | shot_visibility regex (C5) | 7th | 운영 guard, 순차 migration, 가장 위험 |
| **H** | prompt hygiene — P3 closed-list 금지 문구 보강 + P4 검출 패턴 예시로만 제한 | 8th | code 무관, 작은 patch |
| **I** | safety.py SPECIAL MIGRATION (C10) | 별도 의사결정 | 즉시 제거 X — 측정 기반 |
| **J** | scenario residue cleanup (C6) | 작음, 언제든 | 독립 |

### 2.5 R1 audit addendum — U1-U6

R1 full audit ([`open-world-semantic-full-audit.md`](2026-05-12-open-world-semantic-full-audit.md), 2026-05-12) 가 §2.1~§2.3 inventory 에 누락 항목 6 개 발견. 본 spec 에 편입 (audit-local `U*` ID — 기존 `C*/P*` 와 충돌 X):

| ID | 위치 | 형태 | 본 spec area |
|---|---|---|---|
| **U1** | `backend/app/core/steps/scene_consistency_step.py:65-120` | element-id 접미 + description keyword 로 close/full fixed-element framing 분류 | **Area E** (또는 신규 Area K — spec 발전 시 결정) |
| **U2** | `backend/app/core/steps/location_consistency_step.py:70-106` | `scene_director.present_entity_ids` 누락 시 name substring fallback (ID path 있으나 fallback silent mis-map 위험) | **Area D 확장** 또는 별도 — fail-fast 우선 |
| **U3** | `backend/app/modules/pipeline/scene_extractor_v2.py:130-136, 242-247, 363-365` + `backend/app/core/steps/scene_steps.py:60-111` | scene segmentation regex fallback + LLM-generated regex | **원칙 안, 별도 실행 트랙** (2026-05-12 사용자 의결) — semantic 분할이므로 "무조건 LLM SOT" 적용. 단 visual QA migration (Area C/B/D 흐름) 과 분리한 global segmentation track. Area H-small 이후 timing 미정 |
| **U4** | `prompts/_base/shot_director/4.202605121200/system.md:15-32` | active prompt 의 off-camera / gaze-target / blocking / reaction-only "pattern" rules — `shot_visibility.py` (C5) 의 prompt counterpart | **Area G** (code C5 와 pair migration) |
| **U5** | `prompts/_base/entity_extractor_v2/8.202605121200/system.md:20-30`, `turn2.md`, `turn4.md`, `turn1_7_detail_batch.md` | list-like inclusion/exclusion + photo/painting/poster inner-person 예시 (entity SOT 정의 단계에 영향) | **Area H** (P-E — entity extraction SOT 확장) |
| **U6** | `prompts/_base/shot_staging/9.202605121441/system.md:22, 82-92, 145-150, 188-196` | Area A directionality block 외 잔존 example lists (physical element, body pose, framing, scale) | **Area H-small** (P-F — prompt hygiene) |

R1 audit §3 / §4 / §6 는 본 spec inventory 의 detailed evidence (file:line + classification) source.

---

## 3. 4 강제 Gate

각 gate 는 본 spec 의 모든 implementation patch (Area A~J) 에 적용. CI / review / pre-commit 으로 다단계 enforcement.

### 3.1 Gate 1 — Semantic Regex Ban

production diff (`backend/app/**/*.py`) 에서 **open-world visual / story semantic classifier 목적의 `_NOUNS / _TOKENS / _KEYWORDS / _PHRASES` 식별자 신규 추가 금지**.

**Allowlist** (closed-world — 허용):
- ID regex (`C##` / `P##` / `L##` / `O##` / `C##O##`)
- status enum 상수
- schema / version / hash / path / safety / closed system enum
- 기존 area 안의 이미 존재하는 legacy 패턴 (migration 대상 — 본 gate 의 "신규 추가" 금지는 새 코드 한정)

**Suffix coverage** (Codex review iter 후 확장):
`_NOUNS / _TOKENS / _KEYWORDS / _PHRASES / _PATTERNS / _STEMS / _TAILS / _MARKERS`. R1 audit §6.3 가 본 8 suffix 외 inline local list (예: `keywords = [...]`) 는 미검출 명시.

**Known limitations** (R1 audit §6.3):
- `backend/app/**/*.py` **changed lines only** — legacy 제거 미증명. 새 코드 한정 enforcement.
- **Prompt 파일 미스캔** — `prompts/_base/**` 안 closed-list 잔존은 Gate 2 + reviewer 책임.
- 8 suffix 외 식별자 (예: bare `KEYWORDS = [...]` 또는 함수 내부 list literal) 미검출.
- Follow-up gates (audit R1 §6.3 권장):
  - (a) **Active Prompt Closed-List Gate** — **active prompt pack 만** resolve 후 changed prompt lines 에서 `검출 패턴 / 판정 기준 / 키워드 / 다음 패턴` 같은 heading 차단 (인접 라인 non-exhaustive 명시 시 exempt). archive 전체를 blocker 로 만들지 말 것 — runtime priming 영역 한정 (2026-05-12 사용자 의결). 본 gate 초안은 **Area H-small Task 0** 에서 작성.
  - (b) **Full Legacy Audit Gate** — non-blocking report mode 로 production 전체 audit. 마이그레이션 inventory drift 방지.

**위반 시**: review blocker. PR 머지 차단.

### 3.2 Gate 2 — Prompt Closed-List Ban

`prompts/_base/**` diff 에서 `"directional objects (A, B, C)"`, `"검출 패턴: X, Y, Z"`, `"판정 키워드: ..."` 같은 **closed-list 형 예시 신규 추가 금지**.

**Exception**: 명시적 phrase `"non-exhaustive examples, do not classify by this list"` (또는 한국어 대응) 가 인접 라인에 있을 때만 허용.

**위반 시**: review blocker.

### 3.3 Gate 3 — Structured SOT Required

새 예외 / 분류 처리 추가 시 반드시 **upstream LLM output schema 에 enum / bool / object field** 추가. downstream code 는 그 field 만 소비.

**위반 시**: review blocker. plan 단계에서 "어떤 LLM step 의 schema 에 어떤 field 가 신설되는가" 명시 의무.

### 3.4 Gate 4 — No Silent Fallback

structured field 가 없거나 빈 경우 **임시 regex / substring / noun list fallback 금지**. 다음 둘 중 하나:
- fail-fast (`ContractError` / `AppError` raise, HTTP 422)
- legacy pass-through (해당 patch scope 에서 변경 없이 통과 — 회귀 0)

**위반 시**: review blocker.

### 3.5 CI 통합 순서

1. **pytest custom static gate** (1차) — `tests/_gate/test_semantic_regex_ban.py` 등 신규 테스트. `git diff main...HEAD` 의 **changed lines only** scan — legacy 전체 회귀 차단.
2. **review checklist** (2차) — PR 템플릿에 4 gate 체크박스 추가.
3. **pre-commit hook** (나중) — 1차 / 2차 가 안정화된 후 도입.

**우선순위**: 1차 (pytest changed-lines) 부터 Area A 안에서 동시 도입.

---

## 4. Patch Ordering — 의존성 기반

```
Area A (shot_staging directionality_class + orientation SOT)
   │
   ├── Area C (reproduction_surface_rule, Area A SOT 재사용)
   │
   └── Area F (ref_contract token bucket, Area A SOT 의 일부 재사용 가능)

Area B (story_critical_prop_filter 폐기 — upstream SOT 신설)
   │
   └── Area D (scene_reference_service — required_refs SOT 의존)

Area E (spatial rule + close framing keyword) — 독립, 크기 큼

Area G (shot_visibility regex) — 가장 위험, 순차 migration, Area A 이후

Area H (prompt hygiene) — code 무관, 독립

Area I (safety.py SPECIAL) — 별도 의사결정 트랙

Area J (scenario residue) — cleanup, 독립
```

### 4.1 진행 권장 순서 (R1 audit 반영)

R1 audit §7 권고 흡수 — Area H-small (active prompt hygiene) 을 Area D 직후, E 직전에 배치. cheap 한 작업으로 LLM priming 차단 후 큰 작업 (Area E) 진입.

| 순서 | Area | 이유 |
|---|---|---|
| **0** | **Audit freeze** (본 v1.1 + R1 audit) | 다음 area 진입 전 baseline 고정. "we did not know this existed" loop 차단 — R1 audit §7 권고 |
| **1** | **A** (완료, 9 commits push `1d7bfb2..bdb4ca0`) | S26/6 directionality SOT closure + Gate 1~4 도입. reference implementation 패턴. 단 image-level canary Step 4~7 은 Area G 후 회복 — §7 참조 |
| 2 | **C** (reproduction surface — audit C3) | Area A SOT 재사용, 작은 변경 |
| 3 | **B** (story_critical_prop_filter 폐기 — audit C1+C2) | upstream entity_canon 또는 shot SOT 신설 |
| 4 | **D** (scene_reference_service — audit C8+C9 + U2) | Area B required_refs SOT 의존 |
| **5 (보류)** | **H-small** (active prompt hygiene — audit P-A~P-F + U4+U5+U6) — **Task 0 = active-prompt gate 초안** (§3.1 follow-up gate (a)) | code 무관, cheap, LLM priming 차단. **Scope freeze (2026-05-12 사용자 의결)**: shot_director / shot_validator / t2i_review / shot_staging active prompt 4 pack 의 hygiene + active-prompt gate 초안 만. **code semantic migration 0** (다음 area C 가 처리). **2026-05-12 (v1.2) — 본 area 보류**: brainstorming 결과 "legacy hardcoding 제거가 prompt hygiene 보다 시급" 판단 → Area C 우선. B-minus 설계 carry note 는 §10 보존, 재진입 시 brainstorm skip 가능 |
| 6 | **E** (spatial/close framing — audit C4 + P-B + U1) | G4.5a 영역, 크기 큼 |
| 7 | **F** (ref_contract token bucket — audit C7) | 보조 guard, 후순위 |
| 8 | **G** (shot_visibility — audit C5 + U4 prompt pair) | 운영 guard, 가장 위험. **Area A image canary Step 4~7 회복 시점** |
| 별도 | **I** (safety.py SPECIAL — audit C11) | 측정 기반, 즉시 제거 X |
| 언제든 | **J** (scenario residue — audit C6 + archive) | 단순 cleanup |
| **별도 트랙** | **U3** (scene segmentation regex — global segmentation track) | "무조건 LLM SOT" 원칙 **안** (2026-05-12 사용자 의결). visual QA migration 흐름 (Area C/B/D) **과 분리**. timing = Area H-small 이후 미정 |

---

## 5. 모델 선택 정책

LLM 사용은 무조건. 모델 선택은 **테스팅 영역** — spec 에는 가설만, 확정은 micro-benchmark 결과로.

### 5.1 Area 별 모델 가설

| Area | LLM 책임 step | 우선 모델 가설 | 비고 |
|---|---|---|---|
| A | shot_staging (이미 gemini-pro 사용) | **gemini-pro** | 현재 step 역할 / 입력 컨텍스트 정합 |
| B | entity_extractor / shot SOT 신규 field | gemini-pro 또는 gpt-5.5 | story_critical 판단은 시나리오 컨텍스트 강함 — entity_extractor 가 자연 |
| C | (Area A SOT 재사용) | — | 자체 LLM step 없음 |
| D | shot SOT (Area B) 재사용 + scene_reference 가 LLM step 거치지 않으면 신규 step 필요 | TBD | micro-benchmark 후 결정 |
| E | shot_staging 또는 scene_camera_flow | gemini-pro | spatial 판단은 visual 영역 |
| F | (Area A/B SOT 재사용) | — | 자체 LLM step 없음 |
| G | shot_staging.character_angles 확장 | gemini-pro | 현재 step 안에서 확장 |
| H | (prompt 자체 — LLM 모델은 기존 그대로) | — | code 변경 없음 |
| I | safety.py 의 policy rewrite 영역 | TBD | moderation 영역, 별도 측정 |
| J | (단순 cleanup) | — | — |

### 5.2 Micro-benchmark 책임

각 Area 의 implementation plan 작성 시 다음 명시:
- LLM 책임 step / schema field
- 우선 모델 (가설)
- 측정 방식 (sample shot N=10 이상, 정확도 측정)
- 확정 후 plan 업데이트

---

## 6. Patch C 자산 흡수

Patch C 의 spec v1.0 ~ v1.3 (`e024792` ~ `a4de278`) 와 plan v1.0 (`c1cb853`) 는 본 migration spec 으로 흡수.

| 자산 | 처리 |
|---|---|
| `docs/superpowers/specs/2026-05-12-patch-c-photo-orientation-design.md` v1.3 | SUPERSEDED — header note 추가. Area A 의 schema / validator / consumer 명세는 본 spec 의 Area A reference 로 carry |
| `docs/superpowers/plans/2026-05-12-patch-c-photo-orientation-implementation.md` v1.0 | SUPERSEDED — header note 추가. 폐기 (Area A 새 plan 으로 대체) |
| commit `8d7d195` (flat_directional_classifier impl) | 이미 `c631231` 으로 revert. git history 만 남김 |
| commit `e024792` ~ `a4de278` (spec/plan/revert) | git history 보존 — 본 spec 의 진화 흔적 |

Area A 의 새 implementation plan 파일명: `docs/superpowers/plans/2026-05-12-patch-c-directionality-sot-implementation.md`.

---

## 7. Out of scope — 별도 영역

- **Patch D** (S28/3 boat SOT + L17 negation) — visual_qa series carry. 본 migration 영역 영역 밖.
- **S11/14 T2I prompt-following posture** — B-next, subject state enum. 본 migration 과 별개.
- **analysis_dispatch pre-existing fail** — baseline cleanup. 본 migration 과 직교.
- **기존 closed-world regex** (ID matching / status enum / schema / hash / path) — 본 spec 적용 안 함.
- **micro-benchmark 결과 / 모델 확정** — 각 area plan 에서 처리.
- **Area A image canary Step 4~7** (운영 manual canary, plan §Task 7) — scene_detail S26/6 redo + still image regenerate. 새 shot_staging.camera_direction LLM 출력에 `off-screen` / `off-camera` 영어 phrase 가 등장하면 `shot_visibility._OFFSCREEN_PHRASES` regex (audit C5) 의 proximity-window false-positive 가 `VisibleStagingDriftError` raise → scene_detail 의 context loader pre-check 가 redo endpoint 차단 (2026-05-12 canary 검증, S12/4 + S16/2). 즉 Area A core 자체는 닫혔지만 image-level end-to-end 는 **Area G migration 의 후행 의존**. Area G closure 시 자동 회복. cp-level 검증 (directionality_class + orientation emit, 위반 0) 은 통과 ([commit `9ca1b1c..bdb4ca0`]).
- **U3 — scene segmentation regex** (`scene_extractor_v2.py` + `scene_steps.py`) — "무조건 LLM SOT" 원칙 **안** (2026-05-12 사용자 의결), 하지만 visual QA migration 흐름 (Area C/B/D) **과 분리**된 global segmentation track 으로 처리. Area H-small 이후 timing 미정. 본 §7 은 "visual QA scope 밖" 의미 — 원칙은 동일 적용.

---

## 8. Self-review (spec writing skill)

### 8.1 placeholder scan

- §5 의 일부 "TBD" (Area D / I 의 모델) — 가설 형태로 명시. micro-benchmark 후 확정 영역. 의도된 미정.
- 외 placeholder 0.

### 8.2 내부 일관성

- §1 (원칙) ↔ §2 (inventory) ↔ §3 (gate) ↔ §4 (ordering) — 모두 같은 framework.
- closed-world / open-world 경계 §1.3 / §3.1 (Allowlist) 일관.

### 8.3 scope

- spec = 원칙 + inventory + gate + ordering 만. 구현 디테일 0 (각 area plan 분리).
- 사용자 framing 정확히 반영.

### 8.4 ambiguity

- gate 1 의 "open-world visual/story semantic classifier 목적" 의 판단 기준 — `_NOUNS / _TOKENS / _KEYWORDS / _PHRASES` 식별자 검출 + reviewer 의 의미적 판단 결합. ID/status/path 와 명확히 구분.
- gate 3 의 "새 예외 / 분류 처리" 의 정의 — plan 단계에서 "어떤 LLM step 의 schema field 신설" 명시 의무로 강제.

---

## 9. 함정 carry (Patch C v1.3 § 11 + 본 spec 신규)

1. **사용자 합의 ≠ architectural soundness** — Patch C v1.0 에서 사용자가 noun list 명시까지 줬어도 brittle heuristic 임을 책임 있게 escalate 해야 했음.
2. **subagent 가 잘못된 architecture lock-in** — Task 1 의 73 PASS 가 architecture 결함을 가림. code reviewer 가 APPROVED 줘도 architecture 문제는 안 잡힘.
3. **revert > reset** — `git revert` 로 새 commit 추가. history 보존.
4. **noun list 패턴은 system-wide** — Patch C 만 좁게 고치면 같은 패턴이 다른 area 에서 새 결함 생성. 사용자 audit 으로 13 영역 발견.
5. **open-world vs closed-world 경계 명확화 필수** — "모든 의미 판단 LLM" 만 외치면 ID regex 까지 의심 → 작업 멈춤. 본 spec §1.3 가 그 경계.
6. **Gate 1 신규 추가 vs legacy** — gate 는 "신규 추가" 만 차단. legacy 는 area 별 plan 으로 순차 migration. changed-lines only 가 핵심.
7. **Special migration (Area I safety.py)** — 즉시 제거 비용 / 실패율 trade-off. 측정 기반. 같은 원칙 적용하되 다른 트랙.
8. **모델 선택은 spec 영역 아님** — 가설만, micro-benchmark 후 plan 에서 확정.
9. **prompt closed-list 의 exception 문구** — `"non-exhaustive examples"` 명시 시 허용. 단순 금지가 아닌 의미 기반 gate.
10. **CI gate 도입 순서** — pre-commit 부터 도입 시 legacy 회귀 → 흐름 막힘. pytest changed-lines 부터.
11. **closed-world contract 의 가치 인정** — `C##` ID / status enum / hash 같은 regex 는 시스템 안정성의 핵심. 본 spec 이 보호.
12. **brainstorming pivot 패턴 (v1.2 신규)** — H-small B-minus brainstorm 중 사용자가 "B-minus 설계는 맞지만 우선순위는 Area C 가 시급" 결정. spec §4.1 ordering 은 가이드 — 사용자 결정이 final. v1.2 가 그 pivot 보존 (carry note §10).
13. **gate scope inflation 자가 차단 (v1.2 신규)** — gate 가 bullet enumeration / noun phrase 자체 / 동사 부재 까지 잡으려 하면 자연어 의미 판단 흉내내는 쪽으로 감 = 본 spec 원칙 자가 모순. gate 는 작고 닫힌 contract 만 — heading + inline closed-list (괄호 안 3+) 까지가 한계. 자가 인지 룰.

---

## 10. Area H-small B-minus Carry Note (2026-05-12, v1.2)

**Status**: deferred (사용자 결정 — Area C 우선). 본 carry note 는 H-small 재진입 시 brainstorm 단계 skip 용. 모든 design decision 이 §10 안에 lock-in.

### 10.1 Gate (Task 0) — B-minus 설계

**Scope**: active prompt pack 의 `git diff main...HEAD --unified=0` changed lines 만. archive 미스캔. active pack resolve = `prompt_loader._resolve_stem_in_pack` 의 numeric desc 으로 자동 (CLAUDE.md "프롬프트 파일 덮어쓰기 금지" 규칙 정합).

**BAD pattern**:
1. **Classifier heading** — `검출 패턴`, `판정 기준`, `판정 키워드`, `다음 패턴`, `검출 키워드`, `detection patterns`, `classification keywords` 등 enumeration heading. **marker exempt 불가** (heading 자체는 prompt rewrite 원칙 적용).
2. **Inline closed-list** — 괄호 안 comma / pipe 구분 **3개 이상** noun + 분류 함의. **±2 lines 안 exact marker** 있을 때 exempt.

**Bullet enumeration / noun phrase 판정 제외** — false-positive 위험 큼 (정상 출력 규칙도 bullet, "noun only / 동사 부재" 는 gate 가 자연어 의미 판단 흉내내는 회귀 위험, §9 함정 13). 대신 Task 1~4 코드리뷰 수동 체크리스트로 carry.

**Exempt marker — 단일 고정**: `[non-exhaustive: do not classify by this list]` (영어 exact substring). 한국어 paraphrase / multi-form 허용 X — gate 가 다시 어휘 allowlist 가 되는 회귀 차단.

**Self-test 8 항목** (silent disarm 차단, R1 audit Gate 신뢰성 정책):
- T-A: classifier heading → fail
- T-B: heading + marker 인접 → still fail (heading 무효)
- T-C: inline list (괄호 안 3+) → fail
- T-D: inline list + 인접 marker → exempt pass
- T-E: archive 디렉토리 diff → 무시 pass
- T-F: git error (`bad ref` / pathspec error) → `pytest.fail` (silent skip 금지)
- T-G: removed `-` line 안 BAD pattern → 무시 pass
- T-H: active pack path resolution — `_resolve_stem_in_pack` 의존, 신규 numeric desc 디렉토리 자동 active

**Silent disarm 차단**: magic pathspec `:(glob)prompts/_base/**/*.md`, git error 시 `pytest.fail`.

### 10.2 Task 1~4 — 4 prompt pack hygiene 방향

| Pack | 위치 | R1 audit | Hygiene 방향 |
|---|---|---|---|
| shot_director | `prompts/_base/shot_director/4.202605121200/system.md:15-32` | P-A BLOCKING / U4 | gaze-target close-up / off-camera phrase / blocking / reaction-only 의 **pattern 형 prose 폐기**. 의미 기반 원칙 + LLM 자율 판단 요구. shot_visibility (C5) production code 와의 pair migration 은 Area G — 본 area = prompt hygiene 만 |
| shot_validator | `prompts/_base/shot_validator/5.202605081700/system.md:36-41, 111-116, 157-161` | P-D IMPORTANT | locomotion / contact 카테고리 (이미 disambiguator) → exempt marker 단일 통일. visible-human-action body parts list → marker 또는 의미 정의 1-line 으로 대체 |
| t2i_review | `prompts/_base/t2i_review/3.202605121200/scene_system.md:31-39, 49-74` | P-C IMPORTANT | close_framing_existing_ref / physical_inconsistency / unshared_fg_bg `#### 검출 패턴` heading → 의미 기반 원칙 + LLM judge prompt 의 closed-list 형 예시 제거 |
| shot_staging | `prompts/_base/shot_staging/9.202605121441/system.md:22, 82-92, 145-150, 188-196` | P-F MINOR / U6 | line 22 noun list (`커튼, 창문, 거울, TV, 가구, 문, 계단 등`) → 의미 정의 1-line. line 82-92 body_pose 카테고리 + line 145-150 창의적 프레이밍 예시 → exempt marker 통일. line 188-196 = 수치 룰 (40% / 80%) 로 closed-list 아님 — touch X |

### 10.3 Task 순서

- Task 0 (gate) → Task 1 (**shot_director canary** — P-A BLOCKING, 4 pack 중 결함 가장 강함) → Tasks 2~4 (shot_validator / t2i_review / shot_staging — gate 감도 안정화 후 dispatch).
- **병렬 4 dispatch 금지** — gate 규칙 해석 흔들림 위험. canary 1 → 나머지 3 으로 (2026-05-12 사용자 결정).

### 10.4 코드 runtime 무관

본 area = **prompt authoring contract** 만. `shot_visibility.py` / `render_prompt_card.py` / `visible_entities_validator.py` 의 production semantic migration 은 Area C / B / D / G 의 영역 — 본 area 와 무관 (umbrella v1.1.1 scope freeze 정합).

### 10.5 재진입 절차

1. 본 §10 carry note 가 모든 design decision 보존.
2. 재진입 시 brainstorm skip → 바로 plan 작성 진입.
3. plan 파일명: `docs/superpowers/plans/YYYY-MM-DD-area-h-small-active-prompt-hygiene-implementation.md`.
4. plan 의 Task 0 ~ Task 4 = 위 §10.1 ~ §10.3 의 fixed scope.

### 10.6 Pivot 사유

H-small (cheap, hygiene) vs Area C (legacy hardcoded list 제거 첫걸음). 사용자 판단: "기존 audit 된 hardcoded regex / 리스트를 빨리 제거" 가 우선 — prompt hygiene 은 carry. 본 결정의 reasoning 은 §9 함정 12 carry.
