# task-2973 · [T2 하드닝 후속] 게이트 봉인 하드닝 3파일 신규 PR (a9b1e9c 이관)

## 배경 (회장 승인)
- PR #226(게이트 봉인 본체)은 머지됐으나(origin/main `dce9c987`), **마아트·Codex가 찾은 구멍 3건을 막는 하드닝(로컬 `a9b1e9c`, 3파일 +480/−25)이 main에 미반영**(ANCESTOR_NO). PR #226 이미 종료라 신규 PR 필요.
- 사후검증: `memory/reports/report_task2970_merged_without_hardening_260818.md`.
- 담당 dev2(하드닝 원작자, 맥락 보유). repo `/home/jay/projects/InsuRo`, origin/main `dce9c987`.

## 미반영 3구멍 (main 실측 재현됨)
| 공격 | 현 main (라이브) | 하드닝 적용 시 |
|---|---|---|
| A 위조 axes (6축 결손 + `axes_verified=True`) | 공식비교 채택(`ok_confirmed`) | 제외(`excluded_axes_malformed`) |
| B `single_modality` **소문자** ↔ 비세분형 group | 채택(표기변형만으로 봉인 무력화) | 제외(`excluded_modality_axes_group_mismatch`) |
| C `map_state` 키 부재 entry | **`KeyError` 예외 누출** | 제외(`excluded_malformed_entry`) |
- ★ 위험: T6(axes 배선) 올라가는 순간 A/B 라이브화. B는 지금도 내부경로 도달 가능. **회귀 테스트도 main 부재**.

## 작업 (범위 3파일 한정, 코드 신규작성 없음)
- 로컬 하드닝 커밋 `a9b1e9c`의 내용을 **그대로 이관**한 신규 브랜치 → PR → main:
  1. `server/policy_grouping/comparison_gate.py` — 3구멍 차단(`axes_schema_valid`/`REASON_EXCLUDED_AXES_MALFORMED`/`REASON_EXCLUDED_MALFORMED_ENTRY`, 소문자 modality 정규화·차단, map_state 부재 방어)
  2. `server/tests/test_grouping_gate_seal_task2970.py` — 회귀 테스트(+273줄) 신규
  3. `server/tests/test_policy_grouping_comparison_gate.py` — 계약 갱신(diff ~23줄)
- **신규 코드 작성 금지** — `a9b1e9c` 내용 이관만. 이관 후 A/B/C 3공격이 전부 `excluded_*`로 차단되는지 재실행 실증.

## 완료 조건
- **PR**(3파일) + 회귀(A/B/C 차단 실증 + 대조군 B2 대문자 정상) + CI PASS. `git push` harness 차단 시 인가경로(봇 토큰 API).
- `memory/reports/task-2973.md`(3구멍 차단 실증표) + `.done` + ANU 콜백. **머지 HOLD**(ANU 검증 후).
- ⚠️ 이번엔 **머지 전 하드닝이 origin/main 조상인지 확인**(ANCESTOR 검증) — PR #226 사고 재발 방지.