# IDS Phase 1 재작업 — satori 한글 폰트 임베드 fix ★ Lv.3 critical

## 작업 레벨: Lv.3 critical (silent corruption 재발 차단)

## 회장 명시 (2026-05-03)
1. "다 제대로 해야지? 대충 만들고 퀄리티 거지같은거면 왜 일을하냐"
2. "구현완료된 기능 있으면 e2e테스트까지 실제로 진행!!!!"

## 배경 (silent corruption 사례)
- task-2389 (1차)는 commit `bd9428a5`로 산출물 존재
- 그러나 L1 evidence PNG (`memory/reports/task-2389-evidence/l1_smoke_supabase_h4.png`) 시각 검증:
  - **한글 글리프 □□□ 깨짐** (tofu/사각형) — Pretendard/Noto Sans KR 폰트 미임베드
  - 그라데이션/배경/레이아웃 일체 부재 — 빈 검은 화면
  - **IDS §0.1 (한글 100%) 명백 위반**
- pytest "L1 PASS"는 "파일 생성 + string match"만 체크 → silent pass

## 작업 범위 (재작업)

### Fix 1 — satori 한글 폰트 명시 로드
**대상**: `skills/satori-cardnews/_satori.py` (또는 동등 파일)

- Pretendard 폰트 파일 경로 명시 로드 (예: `/usr/share/fonts/.../Pretendard-Regular.otf`)
- Noto Sans KR fallback
- satori `fonts=[{...}]` 옵션에 명시 주입
- 폰트 파일 부재 시 FileNotFoundError raise (silent fallback 금지)

### Fix 2 — 시각 + OCR 통합 검증 게이트
**대상**: `skills/satori-cardnews/scripts/verify_korean.py` (신규 또는 기존 보강)

- 렌더 결과 PNG → pytesseract `--lang=kor` OCR
- 입력 한글과 string match **100%** 의무
- 추가: pixel 검사 (빈 화면 비율, 색상 다양성, 텍스트 영역 OCR confidence)
- silent pass 차단: "파일 존재" 단독 PASS 금지

### Fix 3 — 924 조합 stratified 25장 재렌더 + OCR
- 카테고리별 5장: 보험/금융, SaaS, 소비자, 럭셔리, 기술/미니멀
- 패턴별 5장: H1~H5 hybrid
- 사이즈별 5장: 인스타 1080×1080, 1080×1350, 페북 1200×630, X, 스레드
- **모든 25장 OCR 100% PASS** + 시각 thumbnail 첨부

### Fix 4 — task-2389 escalate 정리
- `cp memory/events/task-2389.escalate memory/events/task-2389.escalate.acked`
- 회장 승인 명시 (2026-05-03)
- finish-task.sh 정상 호출

### Fix 5 — git commit + push
- `git add skills/satori-cardnews/`
- `git commit -m "[task-2401] design팀 (재작업): satori 한글 폰트 임베드 fix + 25장 OCR 100%"`
- `git push origin main`

## 회귀 테스트 (15+ 시나리오)
**파일**: `tests/design-team/test_ids_phase1_korean_font_embed.py`

1. Pretendard 폰트 파일 명시 로드 검증
2. 폰트 파일 부재 시 FileNotFoundError (silent fallback 금지)
3. 25장 stratified 샘플 모두 OCR 100%
4. tofu 글리프 (□) 검출 = FAIL 반환
5. 빈 화면 비율 80% 이상 = FAIL 반환
6. supabase H4 그라데이션 픽셀 검사
7. linear corporate 레이아웃 검사
8. ferrari colorful 색상 다양성 검사
9. apple minimal 타이포그래피 hierarchy
10. 5 사이즈 dimension 정확
11. silent pass 차단 mock (파일 존재 + string match만으로 PASS 안 됨)
12. 외부 API 직접 호출 mock 차단
13. design-md inject 정확도
14. 회귀 0: 다른 skill 영역 무변경
15. **L1 회장님 직접 확인 가능 thumbnail 보고서 첨부**

## 검증 시나리오 (silent corruption 재발 0)
1. 15+/PASS
2. **L1 실 렌더 25장**: 회장님 직접 확인 가능 PNG thumbnail
3. 회귀 0 (다른 IDS Phase 영역 무변경)
4. mypy/pyright 0
5. **task-2389 1차 PNG (한글 □□□)와 비교 보고서** 의무

## affected_files

### 수정
- `skills/satori-cardnews/_satori.py` (또는 폰트 로드 부분)
- `skills/satori-cardnews/scripts/verify_korean.py` (신규/보강)

### 신규
- `tests/design-team/test_ids_phase1_korean_font_embed.py`
- `memory/events/task-2389.escalate.acked`
- `memory/reports/task-XXXX-ids-phase1-redo.md`
- `memory/reports/task-XXXX-evidence-25-stratified/` (25 PNG + 비교 보고서)

### 변경 금지
- `skills/hybrid-image/**`, `skills/magazine-ppt-ko/**`, `skills/mobile-prototype-ko/**`, `skills/motion-cardnews-ko/**`
- `skills/frontend-design/**`, `skills/insane-design/**`
- `skills/ids-router/**` 또는 `scripts/ids_natural_routing.py`
- `resources/design-md/**`
- `dispatch.py`, `scripts/auto_merge.py`, `scripts/done-watcher.py`, `scripts/finish-task.sh`
- `scripts/whisper-compile.py`, `scripts/session-watchdog.sh`, `scripts/bot_status_resolver.py`
- `scripts/worktree_manager.py`, `scripts/cleanup_stale_task_counter.py`
- `scripts/auto_e2e_gate.py`, `scripts/motion_render_queue.py`, `scripts/ids_phase_monitor.py`
- `teams/shared/**`, `CLAUDE.md`
- `memory/capabilities/**`, `memory/audit/**`, `memory/state/**`, `.github/**`

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "skills/satori-cardnews/**"
    - "tests/design-team/test_ids_phase1_korean_font_embed.py"
    - "memory/events/task-2389.escalate.acked"
    - "memory/plans/tasks/task-XXXX/**"
    - "memory/reports/task-XXXX-ids-phase1-redo.md"
    - "memory/reports/task-XXXX-evidence-25-stratified/**"
  forbidden_paths:
    - "skills/hybrid-image/**"
    - "skills/magazine-ppt-ko/**"
    - "skills/mobile-prototype-ko/**"
    - "skills/motion-cardnews-ko/**"
    - "skills/frontend-design/**"
    - "skills/insane-design/**"
    - "skills/ids-router/**"
    - "resources/design-md/**"
    - "dispatch.py"
    - "scripts/auto_merge.py"
    - "scripts/done-watcher.py"
    - "scripts/finish-task.sh"
    - "scripts/whisper-compile.py"
    - "scripts/session-watchdog.sh"
    - "scripts/bot_status_resolver.py"
    - "scripts/worktree_manager.py"
    - "scripts/cleanup_stale_task_counter.py"
    - "scripts/auto_e2e_gate.py"
    - "scripts/motion_render_queue.py"
    - "scripts/ids_phase_monitor.py"
    - "scripts/ids_natural_routing.py"
    - "teams/shared/**"
    - "CLAUDE.md"
    - "memory/capabilities/**"
    - "memory/audit/**"
    - "memory/state/**"
    - ".github/**"
  commands:
    - "pytest"
    - "python3 -m py_compile"
    - "python3"
    - "tesseract"
    - "git add"
    - "git commit"
    - "git push"
    - "git log"
    - "git diff"
  merge_policy: "tiered"
  ttl_hours: 24
```

## 작업 원칙
- **Devil's Advocate**: 1차 silent pass 패턴 학습. PASS 단정 금지. tofu 글리프 가능성부터 확인.
- **시각 검증 의무**: 25 PNG 모두 OCR + 시각 검사 통과
- **3 Step Why**:
  - 1st Why: 왜 1차에 한글 깨졌나? → satori 폰트 미임베드
  - 2nd Why: 왜 미임베드 됐나? → satori `fonts=[]` 옵션 부재 또는 경로 누락
  - 3rd Why: 왜 회귀 테스트가 못 잡았나? → string match만 체크, 시각 OCR 부재
- **Surgical**: skills/satori-cardnews/ 영역만 수정. 다른 IDS Phase 영역 무변경
- **재발 방지**: 회귀 테스트 15개로 silent corruption 영구 차단

## 운영
- ★ Lv.3 critical (회장 명시: "다 제대로 해야지?")
- TTL 24h
- 위임 후보: design-team (점유 시) 또는 dev5-team (라우, 14h 유휴)
- finish-task.sh 누락 금지
- 보고서에 1차 PNG vs 재작업 PNG 비교 thumbnail 의무

## 참조
- 회장 명시 2026-05-03 "다 제대로 해야지? / e2e테스트까지 실제로 진행"
- task-2389 silent corruption: `memory/reports/task-2389-evidence/l1_smoke_supabase_h4.png` (한글 □□□)
- 회장 메모리 `feedback_cardnews_dq_mandatory.md`, `feedback_verification_scenarios.md`
- IDS plan v1.2 §0.1 (한글 100%), §0.5 (외부 API 차단)