# 소식지 표 육안확인 신호 본문마커→메타데이터 이전 (#task-2924, dev1/헤르메스·불칸, 260807) push·머지HOLD

- **문제(Codex 확정 배포블로커)**: task-2921의 `[[TABLE_REVIEW page=N]]` 마커가 `pdf_extract.py:576-578`에서 본문 마크다운(full_markdown)에 prepend → `main.py`가 `newsletters.extracted_text`로 저장 → newsletter_chat(Q&A)·발행물 컨텍스트로 그대로 노출. 내부 육안확인 신호가 최종 발행물/Q&A에 문자열로 새어나감. **묶음배포 반증검토 NO-GO** → 배포 선결.
- **해결(surgical, 허용 3파일만)**:
  - `server/pdf_extract.py`(+9/-3): `_page_markdown` 끝 마커 삽입 블록 **완전 제거**(page_md에 마커 안 섞임). 페이지 dict에 `needs_table_review: bool` 키 추가(3곳=OCR/정상/예외폴백, 하위호환 기본 False, 기존 `table_review` 키 유지). top-level `table_review_pages: list[int]`(0-idx)는 기존 유지·docstring 명시. 저신뢰 표는 여전히 `_region_to_markdown` 줄바꿈 보존(마커만 제거).
  - `server/main.py`(+31/-2): `_try_text_layer_extract` 반환에 `table_review_pages` 추가(힌트 `dict[str,Any]|None`). 두 호출부(`parse_premium_file`·`upload_to_drive`)서 `_table_review_pages` 캡처→`_run_newsletter_review_bg`로 스레딩. bg에서 `run_review_pipeline` 반환 캡처 후 table_review_pages 있으면 `{"rule":"table_review_needed","level":"MED","field":"body","detail":{"pages":[...]}}`를 validation_flags에 병합→`newsletters` update. **newsletter_review.py/validation.py 불변**(forbidden)—파이프라인이 기록한 flags를 배선부에서 병합. MED라 **HIGH-ack 발행게이트(fail-closed) 무영향**. codex `structure_broken`과 공존.
  - `server/tests/test_pdf_extract.py`(+50/-13): 마커 assertion→메타데이터 계약. byte-identical 테스트는 marker strip 제거(본문=baseline 직접 동일). 신규 `TestTableReviewMetadataContract`.
- **검증**: 전체 회귀 **1299 passed·0 failed**(clean env, CORS 오탐 없음, CI parity). test_pdf_extract 22 passed. **★ L1 실데이터**: 실 `DB생명 위드유매거진 26.08.pdf`(19p, text_based) 추출→extracted_text에 `TABLE_REVIEW`/`[[` **0건**(이전 11페이지 마커 삽입), 메타로만 `table_review_pages`(0-idx)=[1,2,3,4,7,9,10,14,15,17,18]·페이지별 `needs_table_review=True` 동일집합, **회장 지적 p16(idx15)=needs_table_review True로 메타에만 표시**.
- **커밋**: 브랜치 `task/task-2924-dev1` 원격 head **7aaf375**(base=origin/main f3e801b, task 지시 명시). scope-guard PASS(정확히 3파일). FINALIZE_ONLY=1 머지스킵. **.done gate 전부 PASS**(impact_scanner/ci_preflight/l1_smoketest/goal_assertions/unresolved). goal_assertions `pytest server/tests/`는 GOAL_CMD_TIMEOUT=600+worktree cwd로 통과. result.json owner_pickup_required=true·authoritative=false·raw ANU key 0·relay_hints 부재(green 결정론 closeout). **worktree cwd 함정 재현**—result.json이 프로젝트경로만 생성→canonical `/home/jay/workspace/memory/events/p0b_inbox/`로 cp 보정([[feedback_finish_task_worktree_cwd_p0b_result_path_260806]]).
- **★ HOLD (ANU 후속)**: ① **머지**(merge_policy=none, 순서 B) ② Codex 재확인(본문오염 0건 실증) ③ **소식지 스택(2916 8e2c17e·2921 f26e50b·2918·2914/15·2923 eaad4c3 등)과 coordinated 단일 재배포**(systemd insuro-api) 회장 go. 이 fix가 2921 마커 블로커 해소=스택 배포 선결조건.
- 관련: [[project_insuro_newsletter_table_grid_restore_task2921_260806]](마커 원인) · [[project_insuro_newsletter_pdf_textlayer_region_extract_task2916_260806]] · [[project_insuro_newsletter_detect_company_life_nonlife_fix_task2923_verified_260806]]
