# task-2966-merge — InsuRo 증권분석 결함A PR #220 squash 병합

- 팀: dev1 (헤르메스)
- 종류: merge_only (코드 수정 0건)
- 결과: **성공 (merged=true)**
- 실행 시각: 2026-08-16T15:03:34Z

## S (상황)
PR #220 (Jeon-Jonghyuk/InsuRo) 은 task-2966 결함A 수정 — `None` 누수 TypeError 차단 및
분석 실패 증권의 합산 제외 — 을 담고 ANU + codex 검증 PASS, 회장 승인까지 완료된 상태로
`MERGEABLE`/`CLEAN` 대기 중이었다. 남은 일은 병합 실행 하나였다.

## C (문제)
merge/push CLI 문자열은 harness 가 차단하므로 일반 `gh pr merge` 경로를 쓸 수 없다.
또한 병합 대상 sha 가 대기 중 이동하면 승인받지 않은 코드가 들어갈 수 있다.

## Q (질문)
harness 를 무력화하지 않으면서, 승인된 정확히 그 sha 만 병합하려면?

## A (해결)
봇 `BOT_GITHUB_TOKEN` 으로 인가된 API 경로를 사용하고 sha 를 핀했다.

```
gh api -X PUT repos/Jeon-Jonghyuk/InsuRo/pulls/220/merge \
  -f merge_method=squash \
  -f sha=047a1ab66b09eaaf992dabf9fc4b1e4dc758f3df
```

## 병합 전 확인 (실측)
- `mergeable=true`, `mergeable_state=clean`
- head sha = `047a1ab66b09eaaf992dabf9fc4b1e4dc758f3df` (지시서 핀 값과 일치)
- check-runs **11/11 전부 success**: ci, diagnostic, guard, e2e-test, ci/guard,
  cancel-kill-switch, hidden-path-audit, gemini-review-gate, merge-safety-check,
  qc-check, lock-in-check
  (legacy status 가 아니라 check-runs 로 판정)

## 병합 결과 (실측)
| 항목 | 값 | 검증 상태 |
|---|---|---|
| merged | true | gh api pulls/220 로 확인 |
| merge_commit | `40f886b3ddd7b02e74555134bcdc9afeb1cb4c00` | 확인 |
| origin main head | `40f886b3ddd7b02e74555134bcdc9afeb1cb4c00` | commits/main 으로 대조 일치 |
| parent | `d381e570765f8a63a68db588f61ff4137f906855` | 병합 전 main head 와 일치 = 선형 squash |
| tree | `40ee90b51f5d5bb9430782764788e5e6ffda77fd` | 확인 |
| merged_by | jeon-jonghyuk-taskctl-bot[bot] | 봇 토큰 경로 확증 |
| PR state | closed / merged | 확인 |

### 수정 파일별 검증 상태
| 파일 | 검증 상태 |
|---|---|
| server/policy_analyzer.py | 병합 커밋 files 목록에 존재 OK |
| server/main.py | 병합 커밋 files 목록에 존재 OK |
| server/tests/test_policy_analyzer.py | 병합 커밋 files 목록에 존재 OK |
| server/tests/test_policy_analysis_failure_isolation.py | 병합 커밋 files 목록에 존재 OK |
| server/tests/test_policy_analysis_table.py | 병합 커밋 files 목록에 존재 OK |
| src/pages/PolicyAnalysis.tsx | 병합 커밋 files 목록에 존재 OK |

6파일 / +687 −12 — PR 범위와 동일, 범위 이탈 없음.

## 준수 사항
- 코드 수정 0건 · force push 0건 · 배포 0건 · harness 무력화 0건
- 인가 경로만 사용 (봇 토큰 + sha 핀)

## 잔여 / 회장 판단 대기
1. **머지 ≠ 프로덕션 반영.** 서버는 `/home/jay/projects/InsuRo/server` 포트 8001 별도
   프로세스이며 **재기동 전까지 라이브 미반영**. 배포는 본 작업 범위 밖.
2. 미해결 결함 3건 (이번 PR 의도적 미수정, "모르는 값을 0 으로" 패턴):
   - `total_payment_years` 키 부재 → 0 → "납입완료" 오표기 [HIGH]
   - `enrollment_date` 파싱 불가 → "0년 0개월" [MEDIUM]
   - `coverages[].amount` None → 0 → "가입금액 0만원" 오표기 [HIGH, 영향 최대]
   보류 사유: 기존 통과 테스트가 해당 동작을 고정 중 → 핫픽스에서 건드리면 회귀 위험.
   한 곳만 고치면 같은 함수 안에서 UNKNOWN 과 0 이 섞이는 더 나쁜 계약. **단일 후속 task 제안.**
3. 후속: PR #221(Phase 2) 머지 승인 → Phase 2 배포 시 **RLS SERVICE_ROLE 강제 확인**
   (anon 폴백이면 운영 write 전면 실패) → Phase 3(신규설계 비교) 착수.

## 산출물
- 이벤트: `/home/jay/workspace/memory/events/task-2966-merge.done`
- ANU 콜백: schedule_id `39DF7E1E`, ANU 독립 키 발사, 2,908 byte (< 3,900), 잘림 없음
