# task-2958-merge · InsuRo 실손계산기 기능① PR #219 병합

- **작업일**: 2026-08-15
- **담당**: 헤르메스 (개발1팀장)
- **유형**: 병합(merge only) — 코드 수정 0
- **타이머 ID**: `task-2958.1` (본 task-2958 은 구현 시점에 이미 종결)
- **결과**: ✅ success (merged=true)

## 1. 목표
ANU 독립검증 PASS · 회장 승인 완료된 PR #219 (Jeon-Jonghyuk/InsuRo) 를
squash 병합하고 origin/main 반영을 확인.

## 2. 병합 전 게이트 (지시 시점 상태 재확인)
| 항목 | 값 |
|---|---|
| PR | #219 `task-2958: InsuRo 실손계산기 기능① MVP (세대별 계산 정규화 테이블 + 결정적 엔진 + 화면)` |
| head ref | `task/task-2958-dev1` |
| head sha | `1e388edcc40f0f85992ac246dc58c8b98b735e0a` (**핀과 일치**) |
| head tree | `1c096aea269e1023d4a2783a7dbf79be375098d7` (ANU 검증 기록과 일치) |
| state | open / merged=false / draft=false |
| CI check-runs (1e388ed) | **11/11 success** |

## 3. 1차 병합 시도 — 405 차단
```
PUT repos/Jeon-Jonghyuk/InsuRo/pulls/219/merge
  merge_method=squash, sha=1e388edcc40f0f85992ac246dc58c8b98b735e0a
→ http 405
  "Repository rule violations found / 8 of 8 required status checks are expected."
```

**원인 확정** — `GET /repos/.../rules/branches/main` 조회:

- ruleset `required_status_checks` 의 **`strict_required_status_checks_policy = true`**
  (= 브랜치가 base 와 최신 동기화 상태여야 병합 가능)
- 필수 8종: `cancel-kill-switch` `qc-check` `hidden-path-audit` `lock-in-check`
  `merge-safety-check` `gemini-review-gate` `ci/guard` `guard`
- PR #219 base 는 `6eeb5b68` 인데, 그 사이 **PR #218(task-2957)** 이 main 에 병합되어
  main head 가 `1d424a9d` 로 1커밋 전진 → `mergeable_state = behind`
- 이 경우 GitHub 은 통과한 검사들을 "expected" 로 재설정하므로 CI 11/11 이어도 차단됨
  (검사 실패가 아니라 **최신화 미충족**)

> 참고: `GET /branches/main/protection` 은 App 권한으로 403 — ruleset 엔드포인트로 우회 확인.
> 규칙 무력화·우회는 하지 않음.

## 4. 인가경로 — update-branch (force 아님)
```
PUT repos/Jeon-Jonghyuk/InsuRo/pulls/219/update-branch
  expected_head_sha=1e388edcc40f0f85992ac246dc58c8b98b735e0a   # 검증된 상태에서만 갱신되도록 핀
→ http 202  "Updating pull request branch."
```
main 을 PR 브랜치로 **merge**(rebase/force-push 아님) → 새 head `34811536078f2d990796869006a1b0533e447118`.

### 4-1. 갱신 델타 교차대조 (밀수 변경 차단)
**A) `1e388ed` → 새 head** = 정확히 PR #218 변경분 + 병합커밋 1개, **그 외 0**

| 파일 | 증감 |
|---|---|
| `docs/analysis-table-contract.md` | +209/-0 |
| `server/main.py` | +24/-0 |
| `server/policy_analysis_table.py` | +96/-0 |
| `server/tests/test_policy_analysis_table.py` | +446/-0 |
| `src/components/policy/CoverageAnalysisTable.tsx` | +195/-0 |
| `src/pages/PolicyAnalysis.tsx` | +54/-93 |
| `src/pages/__tests__/fixtures/analysis-table-e2e.json` | +201/-0 |

커밋 2개: `1d424a9d [task-2957] … (#218)` · `34811536 Merge branch 'main' into task/task-2958-dev1`

**B) main(`1d424a9`) → 새 head** = **12파일 / +7,913 / −0** — ANU 검증 수치와 **완전 일치**.
`server/main.py` 는 #218 의 +24 와 #219 의 +2 가 **충돌 없이 공존**(자동병합 성공, 수동 해결 0).

### 4-2. 새 head CI 재실행
`34811536` 기준 check-runs **11/11 success** (필수 8종 전부 포함):
`ci` `ci/guard` `guard` `e2e-test` `qc-check` `merge-safety-check`
`hidden-path-audit` `lock-in-check` `diagnostic` `cancel-kill-switch` `gemini-review-gate`

## 5. 2차 병합 — 성공
```
PUT repos/Jeon-Jonghyuk/InsuRo/pulls/219/merge
  merge_method=squash
  sha=34811536078f2d990796869006a1b0533e447118   # 갱신 후 head 핀
→ http 200  {"merged": true, "message": "Pull Request successfully merged"}
```
병합 직전 상태: `mergeable=true` · `mergeable_state=clean`.

## 6. 병합 후 검증
| 항목 | 값 |
|---|---|
| merged | **true** |
| merged_at | 2026-08-15T03:42:20Z (UTC) |
| merged_by | `jeon-jonghyuk-taskctl-bot[bot]` |
| PR state | closed |
| **merge_commit** | **`d381e570765f8a63a68db588f61ff4137f906855`** |
| **origin/main head** | **`d381e570765f8a63a68db588f61ff4137f906855`** (일치) |
| main tree | `1c6894a1aef0dfe56de17197c9822285c3c73cb1` |
| parents | `1d424a9d` **단일** → squash 성립(선형 이력, 병합커밋 오염 없음) |
| 로컬 `/home/jay/projects/InsuRo` main | 추적파일 변경 0 확인 후 `git merge --ff-only origin/main` → `d381e57` (tree 일치) |

### main 반영 diff (`1d424a9` → `d381e57`) = 12파일 / +7,913 / −0
| 파일 | 상태 | 증감 |
|---|---|---|
| `docs/ux/task-2958-silson-calculator-ux.md` | added | +437 |
| `server/main.py` | modified | +2 |
| `server/routes/silson_calculator_v1.py` | added | +154 |
| `server/silson/calc/build_calc_table.py` | added | +967 |
| `server/silson/calc/engine.py` | added | +467 |
| `server/silson/calc/models.py` | added | +169 |
| `server/silson/calc/table.py` | added | +308 |
| `server/silson/data/silson_calc_table.json` | added | +3,255 |
| `server/tests/test_silson_calc_engine.py` | added | +578 |
| `server/tests/test_silson_calc_table.py` | added | +612 |
| `src/config/routes.ts` | modified | +9 |
| `src/pages/SilsonCalculator.tsx` | added | +955 |

**silson 원본 지식파일 diff 0줄** 재확인 — 변경 목록에 기존 silson 원본 없음(전부 신규 `calc/*` 및 신규 데이터).

## 7. 특이사항
- 1차 405 는 **CI 실패가 아니라 strict 최신화 규칙**. 규칙 완화·bypass·admin override 미사용.
  인가경로(update-branch)로만 해소했고, 갱신 델타를 파일 단위로 대조해 무관 변경 유입 0 을 입증.
- sha 핀 지시(`1e388ed`)는 **update-branch 의 `expected_head_sha`** 로 승계하여
  "검증된 상태에서만 갱신" 을 보장했고, 최종 병합은 갱신 후 head 를 다시 핀함.
- **머지 ≠ 배포**. 실배포는 회장 파일럿 후 별도 go 대기. 본 작업에서 배포 미수행.
- 잔여(구현 기록 인계): UNKNOWN 22셀 표준약관 원문 추가 대조 · 영수증 OCR 자동추출 후속 ·
  기능②(변천사·판례 참고탭) 별도 task · 연간 누적 자기부담 한도 단건 추정 미반영(화면 고지 중).

## 8. 제약 준수
- 코드 수정 **0** (병합·브랜치 최신화 외 커밋 없음)
- force push **없음** (update-branch = merge 방식)
- harness 무력화 **없음** — 인가경로(봇 GITHUB_TOKEN GitHub API)만 사용
- 배포 **미수행**
