# CI-4 정책 결정 패킷 — `is_blocked` 보험 예외 규칙

**상태**: 회장 결정 대기. **소스·테스트 추가 수정 금지**(회장 지시).
**작성**: 아누 2026-07-19 KST · 근거 = ANU 실측(`/tmp/ci-parent-r2/server/scripts`)
**대상**: `server/scripts/keyword_pool_refresh.py` (동일 규칙이 `server/scripts/news_keyword_extract.py` 에도 존재)

---

## 0. 현행 규칙 (실측 원문)
```python
def is_blocked(kw_normalized: str) -> bool:
    if "보험" in kw_normalized:      # ← 화이트리스트가 **모든 검사보다 앞**
        return False
    for pattern in BLOCKLIST_PATTERNS:
        if re.search(pattern, kw_normalized):
            return True
    if kw_normalized in BRAND_LIST:
        return True
    return False
```
**핵심**: 면제가 **최상단 early-return** 이라 `"보험"` 두 글자만 들어가면 **10개 패턴 전부·브랜드 차단까지 무조건 우회**한다.

---

## 1. BLOCKLIST 10패턴 3분류

| # | 패턴 | 분류 | 근거 |
|---|---|---|---|
| 1 | `채용\|연봉\|시험` | **보험 도메인 예외 허용** | 설계사 채용·자격시험·연봉은 정당한 보험 주제 |
| 2 | `사기\|먹튀\|고소` | **혼합 — 판단 필요** | `보험사기`는 정당 주제 / `먹튀`는 noise |
| 3 | `대출\|카드\|주식` | **보험 도메인 예외 허용** | 약관대출·카드납·변액보험 |
| 4 | `나스닥\|코스피\|…\|etf\|펀드\|배당\|관련주` | **일반 noise 차단** | 증시 일반. 단 `변액보험 펀드`는 정당 |
| 5 | `부동산\|아파트\|전세\|월세\|분양` | **일반 noise 차단** | 단 `화재보험 아파트`는 정당 |
| 6 | `금리\|환율\|달러\|엔화\|비트코인\|코인` | **일반 noise 차단** | 단 `공시이율`류 금리는 정당 |
| 7 | `세금\|세무\|연말정산\|종합소득세\|부가세` | **보험 도메인 예외 허용** | 보험료 세액공제는 핵심 상담 주제 |
| 8 | `은행\|적금\|예금\|통장` | **보험 도메인 예외 허용** | 저축보험·연금보험 비교 |
| 9 | **`살인\|자살\|폭행\|성범죄\|음주운전\|마약`** | **★ 절대 정책 차단 후보** | 아래 §2 |
| 10 | **`파산\|부도\|횡령\|배임`** | **★ 절대 정책 차단 후보** | 아래 §2 |

---

## 2. ★★ 실측 결과 — **양방향 오류**가 둘 다 존재한다

### 2-1. False Negative (통과되면 안 되는데 통과)
| 입력 | `is_blocked` | 문제 |
|---|---|---|
| `보험 마약` | **False** | 절대금지어가 "보험" 한 단어로 우회 |
| `보험 살인` | **False** | 〃 |
| `보험 성범죄` | **False** | 〃 |
| `보험금 횡령` | **False** | 〃 |
| `보험사 파산` | **False** | 〃 |

### 2-2. ★ False Positive (차단되면 안 되는데 차단) — **이번에 새로 발견**
| 입력 | `is_blocked` | 문제 |
|---|---|---|
| **`자살면책`** | **True** | **정당한 보험 약관 용어**인데 "보험" 문자열이 없어 차단 |
| **`음주운전 면책`** | **True** | **자동차보험 핵심 주제**인데 동일 사유로 차단 |
| `마약`·`살인`·`자살` | True | (정상 차단) |

**해석**: 현행 규칙은 **"보험" 문자열의 유무**만 본다. 그래서
- 문자열이 있으면 → **무엇이든 통과**(2-1)
- 문자열이 없으면 → **보험 문맥이어도 차단**(2-2)

→ **문자열 매칭을 문맥 판단의 대용으로 쓴 것**이 근본 원인이다. 절대금지 계층 부재는 그 증상 중 하나일 뿐이다.

---

## 3. 보험 정상 콘텐츠 오차 가능성 (실측 표본)

| 키워드 | 현행 판정 | 기대 | 상태 |
|---|---|---|---|
| `자살보험금` | False(통과) | 통과 | ✅ |
| **`자살면책`** | **True(차단)** | 통과 | ❌ FP |
| **`음주운전 면책`** | **True(차단)** | 통과 | ❌ FP |
| `보험사기 처벌` | False(통과) | 통과 | ✅ |
| `실손보험 청구` | False | 통과 | ✅ |
| `보험설계사 채용` | False | 통과 | ✅ |
| `변액보험 주가` | False | 통과 | ✅ |
| `저축보험 적금` | False | 통과 | ✅ |
| `보험 세액공제` | False | 통과 | ✅ |
| `화재보험 아파트` | False | 통과 | ✅ |
| **`보험 마약`** | **False(통과)** | 차단 | ❌ FN |
| **`보험 살인`** | **False(통과)** | 차단 | ❌ FN |

⚠️ 위는 **표본**이다. 전수 오차율은 실제 키워드 풀 로그로만 산출 가능하며 **현재 데이터 없음(UNKNOWN)**.

---

## 4. 회장 결정 선택지

**A. 현행 유지 (characterization 고정)**
- 변경 0. CI-4 는 현행을 박제만 함
- 리스크: `보험 마약`류가 키워드 풀에 유입 가능. 보험 서비스 브랜드 리스크
- FP(`자살면책`) 도 그대로 방치

**B. 절대 금지 계층만 추가 (최소 수정 · **권고**)**
- 패턴 9·10(`살인|자살|폭행|성범죄|음주운전|마약`, `파산|부도|횡령|배임`)을 **면제보다 앞에서 검사**
- 효과: FN 제거
- ⚠️ 부작용: `자살보험금`·`보험사 파산`·`보험금 횡령` 같은 **정당 주제까지 차단**될 수 있음 → **예외 허용 목록**을 함께 정의해야 함

**C. 문맥 판단으로 전환 (근본 수정)**
- "보험" 문자열 포함 여부 → **보험 도메인 용어 사전** 기반 판정
- FN·FP 둘 다 해소. 비용 최대. 별도 설계 task 필요

## 5. ANU 권고
**B + 예외 목록**을 권합니다. FN(브랜드 리스크)이 FP보다 위험도가 높고, C는 이번 CI-UNBLOCK 범위를 크게 넘습니다.
다만 **B 를 하려면 "무엇을 절대금지로 볼지"를 회장님이 정해주셔야** 합니다 — `자살보험금`은 정당 주제이고 `보험 자살`은 아닌데, 그 경계는 사업 판단입니다.

## 6. 결정 필요 항목
1. A / B / C 중 택1
2. B 선택 시 — 패턴 9·10 중 **절대금지로 승격할 어휘**와 **예외 허용 어휘**(예: `자살보험금`·`보험사 파산`)
3. FP 2건(`자살면책`·`음주운전 면책`) 처리 방향
4. `news_keyword_extract.py` 동일 규칙 동시 적용 여부

**결정 전까지 소스·테스트 추가 수정 0.** CI-4 커밋 `ded17c1` 은 **aggregate PR 에서 제외**되어 있습니다.
