Files
C.E.L_Slide_test2/PHASE-W.md
kyeongmin 1f7579cf64 Phase W + V' 완료: before→filled→after 파이프라인 + 조립 로직 수정
Phase W:
- weight 비율 초기 배정 (space_allocator header 높이 반영)
- block_assembler 공통 조립 함수 (filled/assembled 통합)
- filled → Selenium 측정 → context 저장
- sidebar overflow 확장 + body 재배분
- sub_layouts 사전 계산 (이미지 누락 해결)

Phase V':
- 팝업 링크 우측상단 배치 (인라인 → position:absolute)
- 표 내용 Kei 판단 (공란 크기 계산 → 행/열 산출 → Kei 요약)
- 출처 라벨 삭제 + 이미지 아래 캡션 배치
- after 공란 제거 (결론 바로 위까지 body/sidebar 채움)

추가:
- V-10 bold 키워드: 기계적 추출 → Kei 문맥 판단
- ** 마크다운 → <strong> 변환
- [이미지:] 마커 제거 (bold 변환 전 처리)
- grid-template-rows AFTER 크기 반영 (Sonnet final)
- assemble_stage2 CSS font-size override, white-space fix
- 하드코딩 전수 검토 완료
- 본심 여러 topic 텍스트 합침

Phase X 계획 문서 작성 (동적 역할 구조)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 05:00:52 +09:00

163 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase W — Stage 1.8 before→filled→after 파이프라인 완성
> 작성일: 2026-04-03
> 근거: Phase V 이후 코드 조립/연결 과정에서 발견된 문제 8건
> 선행: Phase V (적합성 검증 + Kei 에스컬레이션)
---
## 배경
Phase V에서 설계한 before→filled→after 프로세스가 실제로 동작하지 않음.
코드는 부분적으로 존재하지만 연결이 안 되어 있고, 각 단계가 따로 놀고 있음.
### 발견된 문제 8건
1. **before→filled→after 파이프라인 연결 안 됨** — filled Selenium 측정 실패, 판단 미동작
2. **space_allocator 불안정** — weight 비율로 전체 공간 100% 사용해야 하는데 안 됨
3. **공통 조립 함수 불완전** — filled/assembled/stage_2가 각각 다른 코드 사용
4. **Kei 에스컬레이션 결정 미반영** — trim/popup/restructure 결정이 컨테이너에 반영 안 됨
5. **본심 OVERFLOW 미해소** — 재배분이 충분하지 않음
6. **filled 시각화 품질** — font_hierarchy, 카드 간격, 팝업 링크 등 미반영
7. **이미지 SVG 샘플 사용** — 실제 이미지(samples/images/) 대신 하드코딩 샘플
8. **Sonnet/코드 조립 경로 분리** — 두 경로가 각각 존재. Phase W 완성 후 판단
---
## 핵심 프로세스
```
before: weight 비중대로 전체 가용 공간 100% 배정 (초기 컨테이너)
filled: before 컨테이너에 블록+텍스트 채움 (block_assembler 공통 함수)
측정: Selenium으로 실제 넘침 확인
판단:
1. 다른 블록으로 바꿀 수 있나? (font_hierarchy 유지)
2. sidebar 넘침 → 세로 확장 (예외)
3. body 넘침 → 배경↔본심 재배분
4. 그래도 안 되면 → Kei 에스컬레이션 (trim/popup/restructure)
5. Kei 결정을 컨테이너에 실제 반영
6. 텍스트 85% 보존 우선
after: 조정된 컨테이너
assembled = after 기준으로 block_assembler 공통 함수로 최종 조립
```
---
## 절대 원칙
1. **하드코딩 금지** — 어떤 MDX가 들어와도 동일하게 동작
2. **결과물 HTML 직접 수정 안 함** — 파이프라인 프로세스를 수정
3. **이미지는 실제 파일만** — samples/images/에서 가져옴. SVG 샘플 금지
4. **텍스트 85% 보존** — 공간 부족 시 컨테이너를 늘림. 그래도 안 되면 Kei가 팝업 분리
5. **weight = 초기 배정 비율 + 충돌 시 우선순위** — 최종 높이가 아님
6. **배치는 시선 흐름** — 좌→우, 상→하 (배경 상단좌, 본심 중앙좌, 첨부 우측, 결론 하단)
7. **font_hierarchy 준수** — 핵심 14px, 본심 12px, 배경 10-12px, 첨부 9-11px
8. **조립 로직은 한 곳** — block_assembler.py. filled/assembled/stage_2 모두 이 함수 사용
9. **임의로 코드 되돌리지 않음** — 이해 안 되면 물어보고, 제안하고, 허락받고 실행
---
## W-1: space_allocator — weight 비율 초기 배정
> 파일: `src/space_allocator.py`
| Task | 완료 기준 |
|------|-----------|
| W-1-1 | `calculate_container_specs()`에서 zone_budget을 `전체가용 × zone_weight_sum / all_weight_sum`으로 계산하는 코드가 있음 |
| W-1-2 | weight 합 1.0일 때 모든 컨테이너 높이 합 ≥ 전체 가용 공간의 95% |
| W-1-3 | 배경이 본심보다 위에, 첨부가 우측에, 결론이 하단에 배치되는 좌표 계산이 `_calc_coords()`에서 동작함 |
---
## W-2: block_assembler — 공통 조립 함수 완성
> 파일: `src/block_assembler.py`
| Task | 완료 기준 |
|------|-----------|
| W-2-1 | `assemble_role_html()`이 블록 CSS의 font-size를 font_hierarchy 값으로 override한 HTML을 반환함 |
| W-2-2 | 팝업 `[팝업: 제목]` 마커가 별도 줄이 아니라 이전 불릿 텍스트 옆에 `[제목→]` 형태로 붙어있음 |
| W-2-3 | sidebar 역할일 때 상단에 꼭지 title 라벨이 있음 |
| W-2-4 | card-numbered에서 주불릿(indent=0)만 카드 제목, 하위불릿(indent=1)은 카드 설명으로 분리됨 |
| W-2-5 | 카드 내 불릿 사이에 빈 줄(엔터) 없음 — white-space: normal 적용 |
| W-2-6 | 이미지는 `ctx.slide_images`의 실제 파일(base64)만 사용, design_reference_html의 SVG 샘플 미사용 |
| W-2-7 | `_gen_stage_1_8_filled()`와 assembled가 모두 `assemble_slide_html()`을 호출함 |
| W-2-8 | Stage 0에서 팝업 콘텐츠의 마크다운 테이블이 HTML `<table>`로 변환되어 `stage_0_context.json`의 popups에 저장됨 |
---
## W-3: filled → Selenium 측정 연결
> 파일: `src/block_assembler.py`, `src/pipeline.py`
| Task | 완료 기준 |
|------|-----------|
| W-3-1 | `assemble_slide_html()` 출력 HTML에 `.slide` 클래스가 최외곽 div에 있음 |
| W-3-2 | 각 역할 컨테이너에 `.area-body`, `.area-sidebar`, `.area-footer` 클래스가 있음 |
| W-3-3 | filled HTML을 `measure_rendered_heights()`에 넣으면 `{'error': 'slide not found'}`가 아닌 정상 측정 결과가 반환됨 |
| W-3-4 | steps 폴더에 `stage_1_8_fit_before.html``stage_1_8_filled.html``stage_1_8_fit_after.html` 순서로 생성되고, before의 컨테이너 크기 → filled의 넘침 → after의 조정된 크기가 시각적으로 확인 가능 |
---
## W-4: 측정 결과 기반 조정 판단
> 파일: `src/pipeline.py`, `src/fit_verifier.py`, `src/kei_client.py`
| Task | 완료 기준 |
|------|-----------|
| W-4-1 | pipeline.py Stage 1.8에서 filled 측정 후 sidebar overflow 감지 시 해당 role의 컨테이너 height_px가 scrollHeight로 확장됨 |
| W-4-2 | body overflow 감지 시 `redistribute()`가 호출되어 배경↔본심 간 높이가 재배분됨 |
| W-4-3 | 재배분 후에도 overflow이면 `call_kei_fit_escalation()`이 호출됨 |
| W-4-4 | Kei가 trim 결정 시 해당 role의 structured_text가 축약되거나, popup 결정 시 해당 콘텐츠가 팝업으로 분리됨 |
| W-4-5 | Kei가 restructure 결정 시 해당 role의 컨테이너 height_px가 변경됨 |
| W-4-6 | after의 컨테이너 크기가 stage_1_8_context.json에 저장됨 |
| W-4-7 | Stage 1.8에서 `call_kei_enhancement_review()`가 호출되고, Kei 응답이 `enhancement_result`에 저장됨 |
---
## W-5: after 기반 최종 조립 + 검증
> 파일: `src/pipeline.py`, `src/block_assembler.py`
| Task | 완료 기준 |
|------|-----------|
| W-5-1 | stage_2의 `generated_html`이 after 컨테이너 크기를 기준으로 생성됨 (stage_2_context.json의 containers == stage_1_8_context.json의 containers) |
| W-5-2 | stage_3_rendered.html에서 overflow가 없음 (Stage 4 측정에서 모든 zone excess ≤ 0) |
| W-5-3 | final.html에 모든 역할의 structured_text가 85% 이상 포함됨 |
---
## 의존 관계
```
W-1 (weight 초기 배정)
W-2 (공통 조립 함수) ← 독립적으로 병행 가능
W-3 (filled → Selenium 측정) ← W-1 + W-2 필요
W-4 (측정 기반 판단) ← W-3 필요
W-5 (after 기반 최종) ← W-4 필요
```
---
## 미결정 사항
- **Sonnet vs 코드 조립**: Stage 2를 Sonnet으로 유지할지 block_assembler 코드 조립으로 교체할지는 W-1~W-5 완성 후 결과를 보고 판단.
---
## 입력 데이터
- MDX 파일: `samples/mdx/01. 건설산업 DX의 올바른 이해(0127).mdx`
- 이미지: `samples/images/` (DX1.png 등)
- 테스트: `scripts/run_from_stage1b.py` — Stage 1B 데이터 고정 실행
- 좋았던 Kei 데이터: `data/runs/20260403_133746` (또는 `20260403_163508`)