# task-3005 — 종합형 실손 증권 E2E 검증 + 회귀 픽스처 봉인

**레벨**: Lv.2 · **팀**: dev7-team (이참나) · **회장 승인 완료** (2026-08-24)

## 왜 이 태스크가 필요한가 — 검증에 빈틈이 있다

task-3004(PR #249, main=`a0bf0c9`)로 **담보명에 '실손'이 있으면 실손으로 판정**하는 경로를 넣었다.
ANU 가 회장 제공 증권으로 대조 프로브를 돌려 `main=false → PR=true` 를 확인했다.

**그러나 그 프로브는 담보명을 손으로 넣은 것이다.**
```python
{"name": "종합입원형(질병)실손의료비(갱신형)", "category": "특약"}   ← ANU 가 직접 타이핑
```

실제 경로는 **PDF → LLM 파싱 → coverages[].name** 이다.
**LLM 이 담보명을 정규화해서 '실손'을 지워버리면 이 경로는 무용해진다.**
예: `종합입원형(질병)실손의료비(갱신형)` → `질병입원의료비` 로 축약하면 미탐.

★ **이 태스크의 핵심 질문은 하나다: LLM 이 담보명의 '실손' 문자열을 보존하는가?**

## 표본 실태 (ANU 실측 2026-08-24)
```
프로덕션 policy_analyses = 12 item · coverage 112행 · 상품 2종
  상품명'실손' O / 담보명'실손' . / category'실손' O  →  8건 (삼성화재 실손의료보험(2019) = 단독실손)
  전부 .                                            →  4건 (현대해상 종합보장보험(2022) = 실손 없음. 정상)
→ category 만 매칭되는 건 0건 (category 는 순수 중복)
→ ★ 종합형 표본이 0건이다. 담보명 경로는 프로덕션 데이터로 검증된 적이 없다.
```

## 검증 대상 증권 (회장 제공 · 2026-08-24)
```
파일: /home/jay/workspace/memory/fixtures/silson/jonghap-sample-260824.pdf
sha256(앞16): dbfed99c0d3b836f   크기: 271,953 bytes   5페이지 전부 스캔 이미지(텍스트 레이어 0자)
상품명: (무)LIG닥터플러스Ⅵ 건강보험(L12.04)   ← '실손' 없음
계약일: 2012-10-29 (2세대)   갱신: 3년
담보명(3페이지)에 '실손' 포함 5건:
  종합입원형(질병)실손의료비(갱신형)      5,000만원
  상해통원형(외래)실손의료비(갱신형)        25만원
  상해통원형(약제)실손의료비(갱신형)         5만원
  질병통원형(외래)실손의료비(갱신형)        25만원
  질병통원형(약제)실손의료비(갱신형)         5만원
```

### ★★★ 개인정보 취급 (엄수)
이 PDF 에는 **실명 · 주민등록번호 앞 7자리 · 주소 · 증권번호**가 있다.
- **저장소(git)에 PDF 를 넣지 마라.** 커밋·푸시 금지. `.gitignore` 확인 후 작업하라
- 보고서·로그·테스트 픽스처에 **실명·주민번호·주소·증권번호를 남기지 마라**
- 픽스처에는 **담보명·상품명·가입금액·계약일만** 쓴다(이들은 PII 가 아니다)
- 중간 산출물(추출 이미지·OCR 텍스트)도 작업 후 정리하라

---

## 할 일

### ① E2E 실행 — 실제 파이프라인으로 파싱
`/api/insuro/analyze-policy` 경로(= `policy_analyzer.run_policy_analysis`)로 위 PDF 를 처리한다.
★ 스캔 이미지 PDF 이므로 **vision/image 경로**를 타야 한다(`doc_format` 이 `image`).
텍스트 레이어가 0자임을 먼저 확인하고, 어느 경로로 들어가는지 로그로 밝혀라.

★ **main(`a0bf0c9`) 코드로 실행하라.** 라이브 API 는 서빙 sha 가 `eadd0c9` 로 **미배포**여서
구버전이 응답한다. 라이브로 찌르면 "미탐"이 나오는데 그건 배포 지연 때문이지 코드 결함이 아니다.
오판하지 마라.

### ② 핵심 확인 — 담보명 '실손' 보존 여부
LLM 이 산출한 `coverages[].name` 을 **원문과 나란히 대조**해 표로 제시하라.
```
증권 원문                              LLM 추출 결과            '실손' 보존
종합입원형(질병)실손의료비(갱신형)   →  ?                        ?
```
- **보존됨** → 담보명 경로가 실효 있음. ③으로 진행
- **유실됨**(정규화·축약으로 '실손' 사라짐) → **담보명 경로는 무용하다.**
  고치려 하지 말고 **즉시 ANU 에 보고**하라. 대안(정규식 등) 판단은 ANU 영역이다

### ③ 판정 결과 확인
`silson_relevance()` 가 이 증권을 `matched=True` 로 잡는지, `basis` 에 무엇이 담기는지 제시하라.
`coverage_name` 이 들어가야 정상이다(상품명에 '실손'이 없으므로).

### ④ 회귀 픽스처 봉인
이 증권 유형이 다시 미탐되지 않도록 회귀 테스트를 추가한다.
- **PDF 를 픽스처로 쓰지 마라.** ①에서 얻은 **파싱 결과(담보명 문자열)** 로 구성하라
- PII 없이 구성 가능하다(담보명·상품명·계약일만 사용)
- ★ **변이 테스트로 봉인을 실증하라**: `coverages[].name` 검사 로직을 제거했을 때
  이 테스트가 **실제로 FAIL 하는지** 확인하고 복원하라. "N passed" 재현만으론 이빨을 증명 못 한다

### ⑤ 세대 판정 확인 (경계 준수)
이 증권은 계약일 2012-10-29 → **2세대**다. 세대가 올바르게 산출되는지 확인하라.
★ **담보명·가입형태로 세대를 추정하는 코드를 넣지 마라**(계약서 §1-3). 세대는 계약일로만 판정한다.
★ **시기로 종합형/단독형을 가르는 분기도 넣지 마라** — 회장 확정: 단독 실손 판매는 **2013년 1월** 개시,
  **2013.1~2017.3 은 병행 구간**이라 계약일로 가입형태를 추론하면 오분류가 난다.
  판정은 **'실손' 문자열이 상품명 또는 담보명에 있는지**로만 한다.

---

## 범위 · 금지
**수정 허용**: `server/tests/**`(회귀 픽스처·테스트) · `server/silson/__tests__/**`

**금지**:
- `server/silson/analysis_summary.py` **로직 변경** — 이 태스크는 **검증**이다.
  결함을 찾으면 고치지 말고 보고하라
- `server/policy_analyzer.py` LLM 프롬프트 변경 — 파급이 크다. 보고만 하라
- **PDF 를 git 에 추가** · PII 를 보고서/로그/픽스처에 기록
- 시기 기반 분기 추가 · 담보명으로 세대 추정
- `supabase/functions/send-push/**` (task-3003 영역) · `scripts/youtube-pipeline/**` (타 저장소)

## allowed_resources

```yaml
allowed_resources:
  paths:
    - "server/tests/**"
    - "server/silson/__tests__/**"
    - "memory/reports/task-3005.md"
  forbidden_paths:
    - "server/silson/analysis_summary.py"
    - "server/policy_analyzer.py"
    - "src/**"
    - "supabase/**"
    - "ops/**"
    - ".github/**"
  commands:
    - "pytest"
    - "python3"
  merge_policy: "tiered"
  ttl_hours: 48
```

## 운영 계약
- `origin/main`(=`a0bf0c9`) 기준 `git pull --ff-only` 후 시작
- ★ `gh` 호출 시 `GH_TOKEN="$BOT_GITHUB_TOKEN"` 주입 필수 (회장 개인 PAT 금지 — 감사기록 오염)
- 워크플로우 `/home/jay/workspace/prompts/DIRECT-WORKFLOW.md` · QC `/home/jay/workspace/teams/shared/QC-RULES.md`
- `WORKSPACE_ROOT=/home/jay/workspace` · `CHAT_ID=6937032012` · 수집자 key `ANU_KEY=c119085addb0f8b7`
- 완료 경로는 `finish-task.sh` 실행이 유일하다. 수동 `.done` 금지.
- **명세와 실측이 다르면 임의 판단하지 말고 ANU 에 보고하라.**

## 완료 조건
E2E 파싱 실행(경로 명시) · **담보명 '실손' 보존 여부 원문 대조표** · `silson_relevance` basis 제시 ·
회귀 픽스처 추가 + 변이로 봉인 실증 · 2세대 판정 확인 · PII 유출 0 · PDF 미커밋 · 회귀 유지

## 보고
**★★★ PR 생성까지가 범위다. 머지는 ANU 가 한다. 절대 직접 머지하지 마라.**
`memory/reports/task-3005.md` 작성 후 표준 완료 콜백 등록. 콜백 프롬프트 **UTF-8 3900 bytes 이하**.
★ **담보명 '실손' 보존 여부를 봉투 첫 줄에 담아라.** 이것이 이 태스크의 결론이다.