# task-3007 — 증권분석 타임아웃 현실화 (스캔 PDF 실호출 3/3 실패)

**레벨**: Lv.2 · **팀**: dev3-team (다그다) · **회장 승인 완료** (2026-08-25)

## 배경 — 지금 실사용이 실패한다

**ANU/dev7 실측 (task-3005)**
```
server/policy_analyzer.py:227-229
    stdout, stderr = await asyncio.wait_for(
        ...,
        timeout=120,          ← 현재값
    )

스캔이미지 PDF 5페이지 실소요 : 85 ~ 139초
실호출 결과                   : 3/3 전건 타임아웃 실패
```
회장이 스캔본 증권(텍스트 레이어 0인 이미지 PDF)을 업로드하면 **분석이 완주하지 못한다.**
139초짜리가 120초에서 잘린다.

검증용 샘플: `/home/jay/workspace/memory/fixtures/silson/jonghap-sample-260824.pdf`
(회장 제공 KB손해보험 증권 · 5페이지 · 전 페이지 스캔 이미지 · 텍스트 0자)
★ **실명·주민번호 앞자리·주소 포함. git 커밋 금지. 보고서·로그에 PII 기록 금지.**

---

## 고칠 것

### ① 타임아웃 값 현실화
- 실측 상한 **139초**에 여유를 둔 값으로 올린다. **근거를 수치로 제시**하라
- ★ 무한정 늘리지 마라. 값을 정한 근거(실측 분포 + 여유율)를 보고서에 적어라
- 같은 파일에 다른 타임아웃이 있으면 함께 검토하되, **이 경로와 무관한 것은 건드리지 마라**

### ② 실패했을 때 사유가 드러나게
현재 타임아웃 시 사용자가 원인을 알 수 있는지 확인하고, 불명확하면 개선하라.
- ★ **"조용한 실패"를 만들지 마라.** 실패인데 성공처럼 보이는 응답·문구를 새로 만들지 말 것
  (2026-08-25 복합설계 사고가 정확히 그 유형이었다)
- 기술 스택트레이스·내부 경로를 사용자에게 노출하지는 마라

### ③ 회귀 봉인
- 타임아웃 값이 실측 하한 아래로 되돌아가면 FAIL 하는 테스트를 넣어라
- ★ **변이로 실증하라**: 값을 120으로 되돌렸을 때 그 테스트가 **실제로 FAIL** 하는지 확인하고 복원

---

## 검증 (실측 강제)
1. **수정 전 재현** — 위 샘플로 실호출해 **타임아웃 실패**를 재현하고 소요 시간을 기록하라
2. **수정 후** — 같은 샘플로 **3회 이상** 실호출해 전건 완주 확인. 소요 시간 분포(평균·최대) 제시
3. **텍스트레이어 경로 무회귀** — 기존 텍스트 PDF 증권 분석이 그대로 동작하는지 확인
4. **변이로 봉인 실증** (③)
5. `pytest` 회귀 유지 (**base 재측정 기준선**. 명세 수치 아님)

## 범위 · 금지
**수정 허용**: `server/policy_analyzer.py` · `server/tests/**`

**금지**:
- **LLM 프롬프트 변경** (`build_policy_prompt` · `DEFAULT_COVERAGES`) — 파급이 크다. 필요하면 **보고만** 하라
  ★ 담보명 리네임(`종합입원형(질병)실손의료비` → `질병입원의료비`) 문제는 **이 태스크 범위가 아니다.**
    고치려 들지 마라. 실손 판정은 현재 `category='실손'` 경로로 정상 작동한다
- `server/silson/**` (task-3004/3005 영역)
- `server/scripts/**` · systemd 유닛 (task-3008 동시 진행 영역)
- `src/**` · `supabase/**` · `extension/**`
- 샘플 PDF 를 git 에 추가하거나 PII 를 기록

## allowed_resources

```yaml
allowed_resources:
  paths:
    - "server/policy_analyzer.py"
    - "server/tests/**"
    - "memory/reports/task-3007.md"
  forbidden_paths:
    - "server/silson/**"
    - "server/scripts/**"
    - "server/main.py"
    - "src/**"
    - "supabase/**"
    - "extension/**"
    - ".github/**"
  commands:
    - "pytest"
    - "python3"
  merge_policy: "tiered"
  ttl_hours: 48
```

## 운영 계약
- `origin/main` 기준 `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 에 보고하라.**

★ **배포 주의**: 백엔드 서빙 sha 는 `eadd0c9` 로 main 보다 뒤처져 있다(미배포).
머지해도 자동 반영되지 않는다. 배포는 ANU 가 task-3008 검증 후 한 번에 한다.

## 완료 조건
수정 전 실패 재현 · 수정 후 3회 이상 완주 + 소요 분포 제시 · 값 근거 수치 제시 ·
텍스트레이어 경로 무회귀 · 변이로 봉인 실증 · PII 유출 0 · 회귀 유지

## 보고
**★★★ PR 생성까지가 범위다. 머지는 ANU 가 한다. 절대 직접 머지하지 마라.**
`memory/reports/task-3007.md` 작성 후 표준 완료 콜백 등록. 콜백 프롬프트 **UTF-8 3900 bytes 이하**.