# Phase S: 검증 기반 확정 — Claude HTML 생성 + 검증된 프롬프트 규칙

> 작성일: 2026-03-31
> 상태: 설계 확정 + 문제 발견 → 5단계 프로세스로 재정리
> 근거: 영역별 검증 합격 결과물 존재. 자동화 전환 시 품질 저하 문제 발견.
> 최종 실행 환경: localhost:8001 (Design Agent 서버, pipeline.py 경유)

---

## 1. 역할 분리 (확정)

```
Kei (1단계):        콘텐츠 분석 → topics, relation_type, expression_hint, source_hint, page_structure
                    Kei는 HTML을 만들지 않는다. 콘텐츠를 분석하고 판단한다.
                    source_data에는 Kei 메모가 포함될 수 있으므로, 슬라이드 텍스트로 직접 사용하지 않는다.

Claude Sonnet:      원본 MDX 텍스트(Kei가 매핑한) + 검증된 디자인 규칙
                    → 각 영역(body, sidebar, footer)의 HTML을 직접 생성

코드:               원본 텍스트 매핑, 프롬프트 조립, HTML 검증, 슬라이드 조립, Selenium 측정
```

---

## 2. 5단계 프로세스

### Step 1: 원본 텍스트 매핑

Kei 분석 결과에 따라 **원본 MDX에서 해당 텍스트를 정확히 매핑**한다.

- MDX를 `##` 기준으로 섹션 슬라이싱
- Kei가 판단한 topics의 `source_hint`로 섹션 매칭
- **source_data는 사용하지 않는다** — Kei 메모("간결한 문제 제기용 핵심 메시지만 추출" 등)가 포함되어 있으므로
- **원본 MDX 텍스트만 가져온다** — 80-95% 보존
- 매핑 결과를 JSON으로 저장하여 검증 가능하게

매핑 규칙:
```
page_structure의 각 역할 → topics → source_hint → 원본 MDX 섹션 매칭

배경 역할의 topics → "용어의 혼용" 섹션 + "혼용 대표 사례" 섹션
본심 역할의 topics → "DX와 핵심기술의 올바른 관계" 섹션
첨부 역할의 topics → "용어별 정의" 섹션
결론 역할의 topics → "핵심 요약" 섹션
```

### Step 2: 검증 합격 프롬프트와 결합

검증에서 합격한 프롬프트의 **디자인/구조 부분은 고정**, Step 1에서 매핑한 **원본 텍스트를 동적으로 삽입**.
영역별 Claude Sonnet 개별 호출.

| 영역 | 디자인 규칙 (고정) | 텍스트 (동적) |
|------|-----------------|------------|
| 배경 | verify_claude_1_2.py prompt_1의 디자인 지시 (다크 박스, 사례 카드, 색상, 폰트) | Step 1에서 매핑한 "용어의 혼용" + "혼용 대표 사례" 원본 텍스트 |
| 본심 | core_c_fix.py의 CSS 구조 (float 이미지, 들여쓰기, 핵심 메시지 박스) | Step 1에서 매핑한 "DX와 핵심기술" 원본 텍스트 |
| sidebar | verify_definitions_v2.py prompt_a의 디자인 지시 (카드, 부제, 불릿, 출처) | Step 1에서 매핑한 "용어별 정의" 원본 텍스트 |
| footer | 배너 디자인 | Step 1에서 매핑한 "핵심 요약" 원본 텍스트 |

프롬프트 구성 원칙:
- 디자인 규칙은 CSS 수치(px, 색상코드)까지 명시적으로 포함
- 텍스트는 원본을 따옴표로 감싸서 "이 텍스트를 그대로 사용하라" 명시
- 들여쓰기 CSS 코드를 프롬프트에 직접 포함
- "축약/요약/재작성 금지" 명시

### Step 3: Claude 생성 HTML 자체 검증 (제출 전)

Claude가 생성한 HTML을 **사용자에게 제출하기 전에** 자동 검증.

검증 항목:
1. 원본 텍스트가 축약/변형 없이 들어갔는가 (원본과 비교)
2. 들여쓰기 CSS(padding-left + text-indent)가 HTML에 존재하는가
3. 이미지 태그(id="slide-img-*")가 존재하는가 (이미지가 있을 때)
4. Kei 메모("간결한 문제 제기용", "핵심 메시지만 추출" 등)가 HTML에 포함되지 않았는가
5. 각 영역의 HTML이 비어있지 않은가

**검증 실패 시 사용자에게 제출하지 않고 재생성.**
**검증 통과 시에만 다음 단계로 진행.**

### Step 4: 전체 슬라이드 조립 + 전체 균형 검증

각 영역 HTML을 슬라이드 프레임에 조립한 후 전체 검증.

검증 항목:
1. 배경이 본심보다 시각적으로 강조되지 않는가
2. 영역 간 간격/여백이 적절한가
3. 본심의 가로 크기가 배경과 동일한가 (같은 body 영역)
4. 전체 720px 안에 들어가는가 (Selenium 측정)
5. sidebar가 overflow 없이 맞는가
6. 핵심 메시지 박스가 잘리지 않는가
7. 시각적 비중이 page_structure의 비중과 맞는가

### Step 5: 결과물 저장

runs 폴더에 스텝별로 정리하여 저장.

```
{run_id}_phaseS_{timestamp}/
├── step1_text_mapping/
│   ├── mdx_sections.json      ← 원본 MDX 섹션 슬라이싱 결과
│   ├── topic_mapping.json     ← topic → 섹션 매핑 결과
│   └── mapped_texts.json      ← 각 영역에 들어갈 텍스트
├── step2_html_generation/
│   ├── bg_prompt.txt          ← 배경 프롬프트 (검증용)
│   ├── bg.html + bg.png       ← 배경 결과
│   ├── core_prompt.txt        ← 본심 프롬프트
│   ├── core.html + core.png   ← 본심 결과
│   ├── sidebar_prompt.txt     ← sidebar 프롬프트
│   ├── sidebar.html + sidebar.png
│   ├── footer.html + footer.png
│   └── generation_meta.json
├── step3_validation/
│   ├── validation_result.json ← 각 항목 PASS/FAIL
│   └── issues.json            ← 실패 항목 상세
├── step4_assembly/
│   ├── slide.html + slide.png ← 전체 슬라이드
│   ├── measurement.json       ← Selenium 측정
│   └── balance_check.json     ← 균형 검증 결과
├── final.html                 ← 최종 결과물
└── screenshot.png             ← 최종 스크린샷
```

---

## 3. 최종 실행 환경

지금 테스트는 `scripts/test_phase_s.py`로 직접 실행하지만,
**최종적으로는 localhost:8001 (Design Agent 서버)에서 pipeline.py를 통해 실행.**

```
사용자 → localhost:8001 POST /api/generate
       → pipeline.py generate_slide()
       → html_generator.py generate_slide_html() (Phase S)
       → render_slide_from_html()
       → Selenium 측정 + 품질 게이트
       → SSE로 결과 전달
```

pipeline.py의 2-3단계가 html_generator로 교체된 상태.
테스트 완료 후 서버에서 동일하게 작동해야 함.

---

## 4. 검증 합격 결과물 참조

| 영역 | 합격 결과물 | 합격 프롬프트 위치 | 합격 방식 |
|------|-----------|-----------------|---------|
| 배경 | verify_claude_20260330_212019/verify1.png | scripts/verify_claude_1_2.py prompt_1 | Claude Sonnet, 수동 텍스트 |
| 용어 정의 | verify_v2_20260331_003421/A_definitions.png | scripts/verify_definitions_v2.py prompt_a | Claude Sonnet, 수동 텍스트 |
| 본심 | core_c_fix_20260331_015828/core_c_fix.png | scripts/verify_core_c_fix.py (직접 작성 HTML) | 하드코딩 HTML |
| footer | 이전부터 OK | 간단 프롬프트 | Claude Sonnet |

---

## 5. 절대 규칙

1. **하드코딩 금지** — 이 콘텐츠에만 작동하는 코드 금지. 어떤 MDX가 와도 동일 프로세스.
2. **회귀 금지** — block_selector, fill_candidates, fill_content 호출 금지.
3. **source_data를 슬라이드 텍스트로 직접 사용 금지** — Kei 메모 포함 가능성.
4. **실행은 사용자 요청 시에만**.
5. **제출 전 자체 검증 필수** — 검증 실패 시 사용자에게 제출하지 않음.

---

## 6. 자기 검증 체크리스트

구현 완료 후, 테스트 실행 전 반드시 확인:

- [ ] source_data를 프롬프트에 직접 넣고 있지 않은가?
- [ ] 원본 MDX 텍스트를 매핑하여 넣고 있는가?
- [ ] 프롬프트에 디자인 규칙이 CSS 수치까지 명시적으로 포함되어 있는가?
- [ ] 들여쓰기 CSS 코드가 프롬프트에 포함되어 있는가?
- [ ] 각 영역이 개별 Claude 호출인가?
- [ ] block_selector, fill_candidates를 호출하지 않는가?
- [ ] Step 3 자체 검증이 구현되어 있는가?
- [ ] 결과물이 하드코딩이 아니라 범용적인가?
