# Phase 전체 감사 — 유효/무력화/충돌 정리

> 작성일: 2026-03-27
> 상태: ✅ 감사 완료 + 정리 실행 완료 (Step B 제거, 죽은 코드 9건 삭제, 미해결 3건 해결)
> Phase A부터 O까지 쌓인 코드를 전수 검사하여 유효/무력화/충돌 항목을 분류한다.

---

## 1. Phase 진화 흐름 요약

```
Phase A~D (초기)
  "Sonnet이 모든 것을 결정"
  → Step B에서 Sonnet이 블록 선택 + zone 배치 + char_guide
  → 실패 시 _fallback_layout()
    ↓
Phase G (Kei API 연결)
  "Kei API 통신 정상화"
  → SSE 스트리밍, Sonnet fallback 제거 시작
    ↓
Phase H (스토리라인)
  "Kei가 콘텐츠를 설계"
  → core_message, purpose, source_hint 도입
    ↓
Phase I (정합성)
  "넘침 처리를 Kei에게"
  → _downgrade_fallback() 비상용으로 분리, Kei overflow 판단 도입
    ↓
Phase J (권한 재정의)
  "Kei 추천 존중, 프롬프트로 강제"
  → STEP_B_PROMPT에 "Opus 추천 존중" 규칙
  → ★ 프롬프트로는 Sonnet을 못 막음 → Phase N에서 코드 강제로 전환
    ↓
Phase K (시각적 위계)
  "purpose별 분량 제약"
  → 문제제기 100자, 핵심전달 200-400자 등 가이드
  → ★ 하드코딩 글자 수 → Phase O에서 동적 계산으로 전환
    ↓
Phase L (렌더링 측정)
  "Selenium + max-height CSS 제약"
  → allocate_height_budget() + _max_height_px + max-height CSS
  → ★ max-height CSS 클리핑 → Phase N에서 제거
  → ★ allocate_height_budget() → Phase O에서 calculate_container_specs()로 교체
    ↓
Phase M (비중 시스템)
  "Kei가 weight 판단, PURPOSE_WEIGHT는 fallback"
  → page_structure + kei_weight_map
  → ★ pipeline.py의 Phase M 코드 → Phase O에서 교체됨
    ↓
Phase N (4대 문제 해결)
  "코드 레벨 강제, fallback 전면 제거"
  → kei_confirmed_blocks 코드 강제, 무한 재시도
  → ★ Step B의 블록 선택이 무력화됨 (Kei 것으로 덮어씌움)
    ↓
Phase O (컨테이너)
  "비중 → px → 블록 제약 → 콘텐츠 제약"
  → container_specs, finalize_block_specs
  → ★ Step B의 char_guide도 무력화됨 (코드 계산으로 덮어씌움)
  → ★ Step B가 완전히 불필요해짐
```

---

## 2. 코드 항목별 유효/무력화 분류

### design_director.py

| 항목 | 행 | 상태 | 이유 |
|------|-----|------|------|
| `BLOCK_SLOTS` | 26~320 | **유효** | 편집자 슬롯 정의에 사용 |
| `LAYOUT_PRESETS` | 322~370 | **유효** | Step A 프리셋 선택에 사용 |
| `select_preset()` | 376~410 | **유효** | 규칙 기반 프리셋 선택 |
| `STEP_B_PROMPT` | 449~550 | **무력화** | Step B가 불필요해짐 |
| `_opus_block_recommendation()` | 560~648 | **유효** | Kei 블록 확정 |
| `create_layout_concept()` 내 Step B Sonnet 호출 | 730~980 | **무력화** | 결과가 전부 덮어씌워짐 |
| `_fallback_layout()` | 990~1028 | **무력화** | Step B 제거 시 불필요 |
| `HEIGHT_COST_PX` | 1030~1036 | **유효** | 블록 높이 추정에 사용 |
| `PURPOSE_FALLBACK` | 1038~1046 | **무력화** | Kei가 블록 확정하므로 불필요 |
| `BODY_FORBIDDEN_MAP` | 1048~1053 | **유효** | body 금지 블록 검증 |
| `DOWNGRADE_MAP` | 1054~1066 | **무력화** | pipeline에서 import 제거됨 |
| `SIDEBAR_FORBIDDEN_BLOCKS` | 1067~1088 | **유효** | sidebar 호환 검증 |
| `_validate_height_budget()` | 1154~1295 | **부분 유효** | overflow 감지는 유효, 내부의 PURPOSE_FALLBACK 사용은 무력화 |
| `_downgrade_fallback()` | 1297~1330 | **무력화** | pipeline에서 미사용 |

### content_editor.py

| 항목 | 행 | 상태 | 이유 |
|------|-----|------|------|
| `EDITOR_PROMPT` | 26~71 | **유효** | 편집자 시스템 프롬프트 |
| `fill_content()` | 74~217 | **유효** | 텍스트 편집 핵심 |
| `_call_kei_editor_with_retry()` | 220~263 | **유효** | 무한 재시도 |
| `_apply_defaults()` | 267~311 | **무력화** | 호출하는 곳 없음 (죽은 코드) |

### pipeline.py

| 항목 | 행 | 상태 | 이유 |
|------|-----|------|------|
| `_retry_kei()` | 35~54 | **유효** | 무한 재시도 |
| Phase O 컨테이너 계산 | 105~127 | **유효** | Phase O |
| Phase O 블록 스펙 | 131~151 | **유효** | Phase O |
| Phase L 피드백 루프 | 215~295 | **유효** | 측정 → 재편집 |

### space_allocator.py

| 항목 | 상태 | 이유 |
|------|------|------|
| 전체 (Phase O 재작성) | **유효** | ContainerSpec, finalize_block_specs |

### kei_client.py

| 항목 | 행 | 상태 | 이유 |
|------|-----|------|------|
| `call_kei_overflow_judgment()` docstring | 447 | **문구 오류** | "fallback: None → DOWNGRADE 비상" 옛날 문구 |
| `# manual_classify 삭제됨` 주석 | 551 | **정리 필요** | 주석만 남음 |

---

## 3. 삭제 대상 (죽은 코드)

| 파일 | 항목 | 행 | 이유 |
|------|------|-----|------|
| `design_director.py` | `STEP_B_PROMPT` | 449~550 | Step B 제거 |
| `design_director.py` | Step B Sonnet 호출 코드 | 730~980 내 Sonnet 부분 | Step B 제거 |
| `design_director.py` | `_fallback_layout()` | 990~1028 | Step B 제거 |
| `design_director.py` | `PURPOSE_FALLBACK` | 1038~1046 | Kei 확정으로 불필요 |
| `design_director.py` | `DOWNGRADE_MAP` | 1054~1066 | 미사용 |
| `design_director.py` | `_downgrade_fallback()` | 1297~1330 | 미사용 |
| `content_editor.py` | `_apply_defaults()` | 267~311 | 미호출 |
| `kei_client.py` | 447행 docstring fallback 문구 | 447 | 옛날 문구 |
| `kei_client.py` | 551행 삭제 주석 | 551 | 불필요 주석 |

---

## 4. 유효한 핵심 코드 (현재 아키텍처)

```
[유효] pipeline.py
  └── _retry_kei() 무한 재시도
  └── Phase O 컨테이너 계산 + 블록 스펙
  └── Phase L 측정 루프
  └── Stage 5 스크린샷 검수

[유효] kei_client.py
  └── classify_content() → Kei API 1A
  └── refine_concepts() → Kei API 1B (무한 재시도)
  └── call_kei_final_review() → Opus 멀티모달 5단계
  └── call_kei_overflow_judgment() → Kei API 넘침 판단

[유효] design_director.py
  └── LAYOUT_PRESETS, select_preset() → Step A
  └── BLOCK_SLOTS → 편집자 슬롯 정의
  └── _opus_block_recommendation() → Kei A-2 블록 확정
  └── BODY_FORBIDDEN_MAP, SIDEBAR_FORBIDDEN_BLOCKS → 블록 검증
  └── _validate_height_budget() → overflow 감지 (PURPOSE_FALLBACK 부분 제거 필요)

[유효] space_allocator.py → 전체 (Phase O)
[유효] content_editor.py → fill_content(), _call_kei_editor_with_retry()
[유효] renderer.py → 전체 (Phase O 컨테이너 그룹핑 포함)
[유효] slide_measurer.py → 전체
[유효] block_search.py → 전체
```

---

## 5. 문서 정리 필요 사항

| 문서 | 상태 | 필요 조치 |
|------|------|---------|
| `IMPROVEMENT.md` | Phase A~O 전체 나열 | 유효/무력화 표시 추가 |
| `IMPROVEMENT-PHASE-A.md` ~ `M.md` | 역사 기록 | "이 Phase의 일부는 후속 Phase에서 대체됨" 주석 추가 |
| `README.md` | Phase O 반영 완료 | Step B 제거 반영 필요 |
| `PROGRESS.md` | 현재 상태 | Step B 제거 + 죽은 코드 정리 반영 필요 |

---

## 6. 정리 실행 순서

```
1. design_director.py 죽은 코드 제거 (STEP_B_PROMPT, _fallback_layout, PURPOSE_FALLBACK, DOWNGRADE_MAP, _downgrade_fallback)
2. design_director.py Step B Sonnet 호출 제거 → Kei 확정 블록 + 코드 검증만으로 layout_concept 생성
3. content_editor.py _apply_defaults() 제거
4. kei_client.py docstring/주석 정리
5. README.md Step B 제거 반영
6. IMPROVEMENT.md 유효/무력화 표시
```
