# 초안 ↔ Codex 검토 ↔ 최종안 비교

> 작성: 2026-04-17
> 목적: 세 버전의 차이를 항목별로 비교하여 **변경 근거**를 명시

---

## 0. 세 버전 요약

| 버전 | 위치 | 핵심 접근 |
|---|---|---|
| **A. Claude 초안** | `docs/architecture-refactor/` | 3-agent 병렬 조사 + 코드 직접 검증. 10개 결함, 4 Phase, 2개월 |
| **B. Codex 검토** | `docs/architecture-refactor-codex/` | 초안과 실제 코드 대조. 4가지 누락 지적, 원칙 3건 보정, Phase 0 추가 제안, 일정 보수화 |
| **C. 최종안** | `docs/architecture-refactor-final/` (본 폴더) | A + B 통합 + 코드 재검증. 13개 결함, 6 Phase, 3개월 |

**관계**: A → B는 **비판적 검토**, B → C는 **통합 확정**.

---

## 1. 결함 개수 비교

| 결함 | A (초안) | B (검토) | C (최종) | 변화 |
|---|---|---|---|---|
| #1 진실원 이중화 | Critical | 원칙 보정 | Critical | 내용 확장 |
| #2 `_sync` 722줄 | Critical | 강화 제안 (5-way) | Critical | 분해 방식 확정 |
| #3 하드코딩 downstream | Critical (3곳) | 신규 메타 제안 | Critical (4곳) | 위치 1개 추가 발견 |
| #4 ImageService 비대 | Critical | 강화 제안 (step 경계) | Critical | Phase 3에 경계 재정의 추가 |
| **#5 AnalysisService/StepRunner 이중** | — | **Critical 지적** | **Critical** | **신규** |
| #6 Applicability 미검증 | High | 범위 확장 | High | 4곳 resolver 통합 |
| #7 run-all 재시도 | High | — | High | 유지 |
| #8 detail_steps closure | High | — | High | 유지 |
| #9 API 책임 오염 | High | — | High | 유지 |
| **#10 Image step 경계 붕괴** | — | **High 지적** | **High** | **신규** |
| #11 체크포인트 원자성 | Medium | — | Medium | 유지 |
| #12 Legacy 관리 | Medium | 우선순위 하향 | Medium | Phase 분산 |
| **#13 테스트 baseline 붕괴** | — | **Medium 지적** | **Medium** | **신규** (Phase 0 선결) |
| Frontend 상태 | Medium | 수치 정정 | Phase 5 | 재분류 |
| 에러 처리 | Medium | 분리 (hardening 트랙) | Phase 5 병합 | 재분류 |
| 설정 분산 | Medium | — | Phase 2 | 재분류 |

**합계**:
- A: 10 (Critical 4, High 4, Medium 5 — 중복 포함)
- C: 13 (Critical 5, High 5, Medium 3, + 재분류 3)

신규 3건은 모두 **Codex가 지적**한 항목.

---

## 2. 원칙 비교

| # | A (초안) | B (Codex 지적) | C (최종) |
|---|---|---|---|
| 1 | **DB Primary, 체크포인트 Backup** | "현재 엔진이 checkpoint-first이므로 이르다. 3-class 분류 권고" | **3-tier 진실원** (실행상태 DB / 분석 체크포인트 canonical + DB projection / 이미지 DB+FS) |
| 2 | 명시적 계약 | 수용 | 유지 |
| 3 | 단방향 의존성 | 수용, API private 역의존 구체 지적 | 강화 (역의존 해소 Phase 2) |
| 4 | **Step은 Pure Transformation** | "이미지/세트/검수 step에 부적용. step 유형 분류 권고" | **4-type 분류** (transform/projection/asset/editorial) |
| 5 | **중앙 레지스트리 (Manifest)** | "manifest만이 아니라 catalog 분산. 4곳 통합 권고" | **Step Catalog** (manifest + class + applicability resolver + UI visibility 단일 계약) |
| 6 | 선언적 > 명령적 | 수용 | 유지 |
| 7 | 테스트 가능성 | "테스트 baseline 먼저 복구 권고" | 유지 + Phase 0 선결 |
| 8 | — | (암묵적) | **신설: Step 경계 명시성** (한 step은 자기 책임만) |
| 9 | — | "현행 공식 경로 선언 필요" | **신설: 공식 경로 단일화** (StepRunner) |

**변경 비율**: 7원칙 중 3건(#1, #4, #5) 재정의, 2건(#8, #9) 신설.

---

## 3. Phase 구성 비교

### A (초안) — 4 Phase, 2개월

```
Phase 1 (1~2일)   — 빠른 승리: 하드코딩/유틸/validator
Phase 2 (1주)     — Service 레이어: _sync 분해
Phase 3 (2주)     — ImageService 분할 + detail_steps DTO
Phase 4 (2~4주)   — Frontend + 진실원 계층화
```

### B (Codex 제안) — 6 Phase, 일정 미명시

```
Phase 0 — 현행 계약 정리 (테스트, 경로 선언)
Phase 1 — Step catalog 통합
Phase 2 — Checkpoint projection 분해
Phase 3 — Image domain 재구성
Phase 4 — Legacy analysis convergence (AnalysisService 폐기)
Phase 5 — Frontend 서버 상태 재구성
```

### C (최종) — 6 Phase, 3개월

```
Phase 0 (3~5일)  — 현행 계약 정리 🆕 (Codex 제안 수용)
Phase 1 (3~5일)  — Step Catalog 통합 (A의 Phase 1 + B의 catalog 개념)
Phase 2 (1~2주)  — Sync 분해 + Service (A의 Phase 2 확장, 5-way 분해)
Phase 3 (2~3주)  — Image 도메인 재구성 (A의 Phase 3 + 경계 재정의)
Phase 4 (1~2주)  — Legacy Analysis Convergence 🆕 (Codex 제안 수용)
Phase 5 (2~4주)  — Frontend 서버 상태 (A의 Phase 4를 분리)
```

### 변경 근거

| 변경 | 근거 |
|---|---|
| Phase 0 추가 | Codex: "테스트가 현행과 어긋남. baseline 없이 리팩토링 금지" |
| Phase 4 신설 (AnalysisService 제거) | Codex: "이중 실행 경로의 공식 경로 선언 필요" |
| A의 Phase 4를 Phase 5로 분리 | Codex: "Frontend는 상태 계약 먼저, React Query는 그 다음" |
| 각 Phase 일정 확대 | Codex: "초안 일정은 낙관적" |

---

## 4. 작업 항목 상세 비교

### Phase 1 (빠른 승리)

| 작업 | A (초안) | B (Codex) | C (최종) |
|---|---|---|---|
| 하드코딩 downstream 제거 | 3곳 (toggle, resume_sensitive, 기타) | 메타 필드 추가 제안 (`resume_sensitive`) | **4곳 + `resume_sensitive` 필드** |
| Applicability validator | `if_planning_doc`, `if_has_outlooks` 2개 | 4곳 resolver 통합 필요 | **Step Catalog 안에서 공용 resolver** |
| `set_design` applicability | `"always"` → `"if_set_design_enabled"` | 수용 | 유지 |
| 체크포인트 원자 쓰기 유틸 | `app/core/checkpoint_io.py` | — | 유지 |
| Step lifecycle 필드 | manifest에 `lifecycle` | 수용 | + `step_type`, `resume_sensitive` 3개 |
| legacy 파일 이동 | `analysis_steps_legacy.py` → `legacy/` | 후순위 (실행경로가 우선) | **Phase 4로 이동** |
| 번역 warning 전파 | Phase 1 | "bugfix 트랙으로 분리" | **Phase 5 병합** |

### Phase 2 (Service 레이어)

| 작업 | A | B | C |
|---|---|---|---|
| Sync Service 분해 | `CheckpointSyncService` 1개 | "5개 도메인 Service로" | **5-way 분해** (Entity/Relation/SceneStill/Outlook/EpisodeProjection) |
| DELETE→INSERT 전환 | relations, outlooks (2건) | — | **relations + outlooks + outlook_dedup 6건(Phase 4)** |
| ShotSelectionService | O | — | 유지 |
| SnapshotService | O | — | 유지 |
| SettingsRegistry | O | — | 유지 |
| `@api_endpoint` 데코레이터 | O | — | 유지 |
| API private 역의존 해소 | — | 지적 | **Phase 2에 포함** |

### Phase 3 (Image 도메인)

| 작업 | A | B | C |
|---|---|---|---|
| ImageService 3-way 분할 | O | "step 경계 먼저" | **step 경계 재정의 → 3-way 분할** |
| Image step 경계 재정의 | 언급 없음 | `ref_image_gen` vs `composite_image_gen` 경계 붕괴 지적 | **Phase 3.1로 선행** |
| `SceneAnalysisContext` DTO | O | — | 유지 |
| `_analyze_one` 리팩토링 | O | — | 유지 |

### Phase 4 (신설)

| 작업 | A | B | C |
|---|---|---|---|
| AnalysisService 제거 | — | "공식 경로 선언 + legacy convergence" | **1,137줄 제거** |
| `/episodes/{id}/analyze` 교체 | — | 수용 | **StepRunner run-all 래퍼** |
| outlook_dedup DELETE 재설계 | — | — | **신규** (Agent 조사로 발견) |

### Phase 5 (Frontend)

| 작업 | A (Phase 4에 병합) | B | C |
|---|---|---|---|
| React Query 도입 | O | "API 상태 모델 먼저 안정" | **Phase 2 완료 후 시작** |
| `EpisodeDetail.tsx` 분할 | O | — | 유지 |
| `except: pass` 교체 | 12건 | 37건 지적 | **37건** |
| `data-contracts.md` 작성 | O | — | Phase 0에서 갱신 + 유지 |

---

## 5. 주요 수치 정정

| 수치 | A (초안) | B (Codex) | C (재측정) | 차이 |
|---|---|---|---|---|
| 총 step 수 | 33 active | — | **48** (active ~40) | A 오산 |
| `EpisodeDetail.tsx` useState | 51 | 15 | **13~34** (방식 의존) | A 과대, B 과소 |
| `except: pass` 건수 | 12 | — | **37** | A 과소 |
| 하드코딩 downstream 위치 | 3곳 | — | **4곳** | A에 누락 1건 |
| DELETE→INSERT 위반 | 5+곳 | — | **12곳 이상** | A 과소 |
| `_sync` 함수 라인 | 722 | 확인 | 722 | 일치 |
| `api/v1/steps.py` | 1,518 | 확인 | 1,518 | 일치 |
| `image_service.py` | 5,281 | 확인 | 5,281 | 일치 |
| `analysis_service.py` | 미언급 | 1,137 | **1,137** | **B에서 신규 관찰** |
| 테스트 파일 현황 | 미언급 | v3/26단계 낡음 | **완전 낡음** | **B에서 신규 관찰** |

---

## 6. 일정 비교

| Phase | A (초안) | C (최종) | 변화 |
|---|---|---|---|
| 0 — 현행 계약 | — | 3~5일 | +3~5일 |
| 1 — Quick wins | 1~2일 | 3~5일 | +2~3일 |
| 2 — Service | 1주 | 1~2주 | +0~1주 |
| 3 — Image | 2주 | 2~3주 | +0~1주 |
| 4 — Legacy convergence | — | 1~2주 | +1~2주 |
| 5 — Frontend | 2~4주 | 2~4주 | 유지 |
| **합계** | **~2개월** | **~3개월** | **+30%** |

**일정 보수화 근거** (Codex):
- Applicability 중앙화는 StepRunner + 3개 API + UI + 테스트 동시 수정
- Sync 분해는 5가지 호출 목적 분리까지
- Image는 Service 분할 전 step 경계 재정의
- Legacy convergence는 API contract 조정 포함

---

## 7. 핵심 결정의 변화

| 결정 | A | B | C |
|---|---|---|---|
| 공식 경로 | 묵시적으로 StepRunner | "명시 선언 필요" | **Phase 0에서 명시, Phase 4에서 제거** |
| 진실원 원칙 | DB Primary | 3-class 권고 | **3-tier 최종 확정** |
| Step 동질성 | Pure Transformation 일괄 | "유형별 규칙" | **4-type 분류 확정** |
| 레지스트리 | Manifest | Catalog (4곳 통합) | **Step Catalog 모듈 신설** |
| 테스트 우선순위 | Phase 4 | "Phase 0 선결" | **Phase 0 첫 작업** |
| bugfix 분리 | Phase 1에 포함 | "별도 트랙" | **Phase 5 병합** |

---

## 8. 이번 통합에서 재확인된 사실들

### 변경 없이 유지된 초안의 강점

- 결함 축 분류 (데이터/제어/책임) — 유용. 최종안은 여기에 "실행경로" 축 추가
- 수정 난이도 vs 효과 매트릭스 — 유용. 최종안은 Phase 매핑으로 발전
- DTO (`SceneAnalysisContext`) 설계 — 유효. 유지
- Service 분리 전략 (ImageService 3분할) — 유효. 경계 재정의 후 실행

### Codex가 지적한 초안의 약점 — 모두 수용

- 이중 실행 경로 누락 → Phase 4 신설
- Image step 경계 붕괴 누락 → Phase 3.1 추가
- 테스트 baseline 붕괴 누락 → Phase 0 신설
- "DB Primary" 원칙 과감성 → 3-tier로 분해
- "Pure Transformation" 과잉 → 4-type 분류
- Manifest ≠ 단일 registry → Step Catalog 개념

### 최종안에서 새로 확인된 것

- 하드코딩 downstream 위치 **4곳** (Agent 전수 조사)
- `except: pass` **37건** (초안 12건보다 3배)
- `DELETE→INSERT` 위반 **12건 이상** (초안 5+건보다 2배)
- API private 역의존 **2건** (image_steps + entities)
- outlook_dedup의 6-way 연쇄 DELETE (신규 발견)
- `step_manifest.py` 주석 "33단계"도 낡음 (실제 48)

---

## 9. 통합 과정의 교훈

### 무엇을 신뢰할 것인가

| 신뢰도 | 출처 | 이유 |
|---|---|---|
| ★★★ | 실제 코드 `grep`, `wc -l`, `pytest` | 사실 |
| ★★ | Codex 검토 | 초안과 코드 대조하여 사실 검증 |
| ★ | 내 초안 분석 | 3-agent 조사지만 일부 수치 오산 |
| 권고 | 문서(`docs/architecture/`) | 아키텍처 의도이나 실제와 괴리 가능 |
| 경고 | 테스트 (`test_step_manifest_v3.py`) | 현재 완전 낡음 |

### 통합 원칙

- 수치는 항상 **재측정**. 전 세션 수치 재사용 금지
- Codex가 지적한 4건은 **구체 파일:라인 증거** 있음 → 전부 수용
- 초안의 원칙이 현재 엔진과 어긋나면 **엔진을 바꾸지 말고 원칙을 조정**
- Phase 0에서 **안전망(테스트)을 먼저**. 리팩토링 중 회귀 감지 필수
- 일정은 **실제 위험 기반**으로 보수화. 낙관 일정은 재작업 비용 유발

---

## 10. 다음에 할 일

이 비교 문서는 **기록용**이다. 실제 실행은 다음 순서로:

1. [`04-next-session-brief.md`](04-next-session-brief.md) 읽기
2. Phase 0 작업 시작
3. 매 Phase 완료 후 `baseline.md` 지표 갱신
4. 결과에 따라 후속 Phase 조정 (단, Phase 순서 변경 금지)
