# [Lv.2] TASK-2851-R1 — ingest egress allowlist 강화(crm 정합): 포트/search/hash 거부

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "extension/background/ingest.js"
    - "extension/__tests__/prd1-ingest-core.test.ts"
    - "extension/__tests__/**"
  forbidden_paths:
    - "src/**"
    - "server/**"
    - ".github/**"
    - "extension/content.js"
    - "extension/background/crm.js"
    - "extension/manifest.json"
  commands: ["npx vitest", "node", "git"]
  merge_policy: "none"
  ttl_hours: 6
  base_branch: "task/task-2851-dev1"
```
> ★ merge_policy=none. **기존 브랜치 `task/task-2851-dev1` 위에 이어서 커밋**(PR #125). 신규 브랜치 만들지 말 것. 머지·검증은 ANU 원격 소유.

## 배경 (Codex 반증리뷰 발견 — 2026-07-24)
task-2851(PR #125) 머지 전 Codex 반증리뷰가 실질 결함 1건 확정. **task-2851이 유발한 회귀 아님 — base(60b645d)부터 존재하던 pre-existing 비대칭.** 그러나 이 ingest 경로가 곧 파일럿에서 실 PII를 `api.insuro.biz`로 전송하므로 flag-on 前 crm 정합 필요.

**결함**: `extension/background/ingest.js`의 `isAllowedIngestUrl`가 prod host에 대해 **비표준 포트를 거부하지 않고**, **url.search / url.hash를 거부하지 않는다**. 반면 `crm.js`의 `isAllowedCrmUrl`는 둘 다 거부(정합 기준). 즉 `https://api.insuro.biz:444/<path>`, `...?q=1`, `...#frag`가 ingest allowlist를 잘못 통과함.

## 작업 (surgical — crm.js와 동일 규율로 정합)
1. `extension/background/ingest.js` `isAllowedIngestUrl`:
   - `isProdHost` 조건에 포트 제약 추가 → `url.protocol === "https:" && url.hostname === "api.insuro.biz" && (url.port === "" || url.port === "443")`
   - 최종 `return true` 직전에 추가: `if (url.search !== "" || url.hash !== "") return false;`
   - **그 외 로직(userinfo/localhost/pathname exact/flag=false) 절대 불변.** flag 상수 건드리지 말 것(false 유지).
2. `extension/__tests__/prd1-ingest-core.test.ts`: 신규 거부 케이스 3건 추가(assertion 삭제/약화 금지, 순수 additive):
   - `https://api.insuro.biz:444/api/insuro/consultation-history/v1` → 거부(false)
   - `https://api.insuro.biz/api/insuro/consultation-history/v1?x=1` → 거부(false)
   - `https://api.insuro.biz/api/insuro/consultation-history/v1#frag` → 거부(false)
   - 기존 허용 케이스(`https://api.insuro.biz/<path>`, `http://localhost:8000/<path>`) 회귀 0 유지.

## 검증
- `npx vitest run extension/__tests__/` 전체 PASS(회귀 0). 신규 3건 포함 카운트 증가.
- ingest allowlist 실동작: api.insuro.biz(표준) 허용 / :444 포트·?query·#hash 거부 / insuro.biz(프론트) 거부 / localhost:8000 허용.
- `git diff` 로 ingest.js 변경이 위 2지점(+ 테스트)뿐임을 증명. crm.js/manifest.json/서버/content.js 미접촉.

## 완료 후
- push + `memory/events/task-2851-r1.done` + ANU callback(독립 ANU key). merge_policy=none이므로 팀장 자체 머지 금지 — ANU가 PR #125 재검증(Codex re-review clean 확인) 후 머지.
