# [Lv.1 fix] 소식지 교차검증 — 원본 이미지 렌더를 파일명 확장자 대신 내용(매직바이트)으로 감지

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "server/main.py"
    - "server/tests/**"
  forbidden_paths:
    - ".github/**"
    - "extension/**"
    - "src/**"
    - "server/migrations/**"
    - "server/newsletter_review.py"
    - "server/newsletter_cross_verify.py"
    - "server/newsletter_validation.py"
  commands: ["pytest","python3","git"]
  merge_policy: "none"
  ttl_hours: 8
```
> ★ base=현 origin/main. 라이브 버그. 근거: 회장이 올린 PDF 소식지가 codex 교차검증을 못 돌리고 `cross_model_unavailable` 로 빠짐.

## 배경 (ANU 실증 확정)
`_render_source_page_images(file_bytes, filename)` (server/main.py:5305) 가 **파일명이 `.pdf` 로 끝날 때만** 렌더한다(`ext != ".pdf": return []`). 그런데 업로드 경로에서 넘어오는 filename 이 **확장자 없이**(예: 소식지 제목 "KB금융그룹") 오면 → PDF 인데도 **0장 렌더 → source_images 빈 리스트 → codex 교차검증이 `cross_model_unavailable` 로 스킵**. 실증: fitz 렌더 엔진 자체는 정상(정상 filename 이면 렌더됨), filename 확장자 없으면 0장.

## 작업 (surgical)
`_render_source_page_images` 를 **파일 내용(매직바이트)으로 형식 감지**하도록 수정(filename 확장자 의존 제거):
- **PDF**: `file_bytes[:5] == b"%PDF-"` (또는 `b"%PDF"`) → 기존 fitz 렌더 로직 그대로.
- **이미지**: PNG(`\x89PNG`)·JPEG(`\xff\xd8\xff`)·GIF(`GIF8`)·WEBP(RIFF....WEBP) → **원본 이미지를 그대로 임시파일로 저장해 그 경로 1건 반환**(이미지 소식지의 원본 = 그 이미지 자체. codex 가 -i 로 직접 읽음).
- **그 외/PPTX**: 기존처럼 graceful `[]`(codex 가 cross_model_unavailable 흡수). PPTX 변환은 범위 밖.
- filename 은 참고용으로만(로그/디버그), 형식 판정 근거로 쓰지 말 것.
- 기존 graceful(예외 삼키고 []·부분 실패 허용)·임시파일 정리 계약 유지.

## 제약
- server/main.py 의 이 함수 + 테스트만. cross_verify·review·validation 불변. 기존 업로드/추출/파이프라인 회귀 0. 호출부(source_images 전달) 는 그대로 동작.

## 검증
- `pytest server/tests/` 회귀 0. 신규: **PDF 바이트 + 확장자 없는 filename → 렌더 성공(≥1장)** / PDF + 정상 filename → 성공 / PNG·JPEG 바이트 → 이미지 경로 1건 반환 / 비지원 바이트(예: PPTX/zip) → [] graceful / 손상 바이트 → [] 예외없음.
- ★ L1: 실제 PDF 바이트로 함수 호출 → ≥1 PNG 생성 확인, 보고서 기록.

## 완료 (★ 순서 B)
- server/main.py + 테스트만. **dev6 금지** — dev1(헤르메스). 커밋 → push → **★ push 확인** → finish-task foreground 1회 → .done. ANU 독립검증·머지·재배포는 ANU.

## goal_assertions (auto-generated)
- `pytest server/tests/`
