# 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 유효/무력화 표시 ```