- 루트의 IMPROVEMENT-PHASE-*.md, PHASE-*.md 등 45개 → docs/history/로 이동 - docs/block-tests/ 오래된 블록 테스트 HTML 삭제 (figma_to_html_agent로 대체) - docs/figma-analysis/, docs/figma-assets/, docs/figma-screenshots/ 정리 - docs/test-*.html 등 초기 테스트 파일 정리 - 참고 페이지/ 스크린샷 정리 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.4 KiB
7.4 KiB
Phase W — Stage 1.8 before→filled→after 파이프라인 완성
작성일: 2026-04-03 근거: Phase V 이후 코드 조립/연결 과정에서 발견된 문제 8건 선행: Phase V (적합성 검증 + Kei 에스컬레이션)
배경
Phase V에서 설계한 before→filled→after 프로세스가 실제로 동작하지 않음. 코드는 부분적으로 존재하지만 연결이 안 되어 있고, 각 단계가 따로 놀고 있음.
발견된 문제 8건
- before→filled→after 파이프라인 연결 안 됨 — filled Selenium 측정 실패, 판단 미동작
- space_allocator 불안정 — weight 비율로 전체 공간 100% 사용해야 하는데 안 됨
- 공통 조립 함수 불완전 — filled/assembled/stage_2가 각각 다른 코드 사용
- Kei 에스컬레이션 결정 미반영 — trim/popup/restructure 결정이 컨테이너에 반영 안 됨
- 본심 OVERFLOW 미해소 — 재배분이 충분하지 않음
- filled 시각화 품질 — font_hierarchy, 카드 간격, 팝업 링크 등 미반영
- 이미지 SVG 샘플 사용 — 실제 이미지(samples/images/) 대신 하드코딩 샘플
- 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 공통 함수로 최종 조립
절대 원칙
- 하드코딩 금지 — 어떤 MDX가 들어와도 동일하게 동작
- 결과물 HTML 직접 수정 안 함 — 파이프라인 프로세스를 수정
- 이미지는 실제 파일만 — samples/images/에서 가져옴. SVG 샘플 금지
- 텍스트 85% 보존 — 공간 부족 시 컨테이너를 늘림. 그래도 안 되면 Kei가 팝업 분리
- weight = 초기 배정 비율 + 충돌 시 우선순위 — 최종 높이가 아님
- 배치는 시선 흐름 — 좌→우, 상→하 (배경 상단좌, 본심 중앙좌, 첨부 우측, 결론 하단)
- font_hierarchy 준수 — 핵심 14px, 본심 12px, 배경 10-12px, 첨부 9-11px
- 조립 로직은 한 곳 — block_assembler.py. filled/assembled/stage_2 모두 이 함수 사용
- 임의로 코드 되돌리지 않음 — 이해 안 되면 물어보고, 제안하고, 허락받고 실행
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)