# [test-only] PR-D2 egress-gate — 쿼리/프래그먼트 거부 fetch-spy 통합 패리티

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "extension/__tests__/**"
  forbidden_paths:
    - "extension/background/**"
    - "extension/content.js"
    - "src/**"
    - "server/**"
    - ".github/**"
  commands:
    - "npx vitest"
    - "git"
  merge_policy: "none"
  ttl_hours: 4
```
> ★ **소스 변경 절대 0 — 테스트 파일만.** 브랜치 **`task/task-2836-dev1`**(PR #120)에 이어서 커밋(새 PR 금지).

## 배경 (Codex 3차 잔여 — test parity)
`isAllowedCrmUrl` egress 게이트는 이미 완성(포트 `""`/`443` · userinfo 거부 · pathname exact · 쿼리/프래그먼트 거부). Codex 지적: **`:444` 케이스는 실제 egress/fetch 함수를 관통하며 fetch-spy로 "fetch 미호출"을 증명**하는데, **쿼리스트링/프래그먼트 거부는 boolean helper(`isAllowedCrmUrl()`)로만** 증명되고 실제 전송 경로를 안 탐. → 통합 레벨 패리티 미달(실 리스크 아님, 테스트 완결성).

## 작업 (test-only — 소스 손대지 마라)
`extension/__tests__/prd2-crm-egress-gate.test.ts` 에 **`:444` 테스트와 동일한 하네스/패턴**으로 통합 케이스 2건 추가:
1. **쿼리스트링 통합**: 실제 egress/fetch 함수(crm 검색 또는 생성 전송 경로 — `:444` 테스트가 쓰는 그 함수)를 `https://insuro.biz/<CRM_SEARCH_PATH 또는 CREATE_PATH>?x=1` 로 유도 → **`fetch` mock 미호출**(0회) + 실패/`URL_NOT_ALLOWED`(코드상 실패값) 반환.
2. **프래그먼트 통합**: 동일 함수를 `https://insuro.biz/<path>#frag` 로 유도 → **`fetch` 미호출** + 실패.
- `:444` 테스트가 fetch 를 어떻게 spy 하는지 그대로 재사용(vi.fn / spyOn). 순수 boolean 호출 말고 **전송함수 관통**.

## 검증
- 신규 2건 PASS(fetch spy call count 0 단언 포함). egress-gate 파일 기존 6건 + 신규 2건 = 8건.
- 확장 전체(**378 → 380**) 회귀 0. `npx vitest run extension/__tests__/`.

## 완료
- `extension/__tests__/prd2-crm-egress-gate.test.ts` 외 변경 0 (`git diff --stat` — 소스 파일 등장 시 실패). 
- **dev6 금지** — dev1. worktree finish → push(PR #120 반영·새 PR 금지) → ANU 독립검증. **머지 금지**.
- **ANU callback**(UTF-8 ≤3900 bytes, envelope). ⚠️ 세션 사망 대비: 완료 즉시 finish-task(push) 우선.

## goal_assertions (auto-generated)
- `npx vitest run extension/__tests__/`
