# [Lv.4] Integration Phase2 PR-D1 — 확장 model A bytes 인프라 + source-based taint-guard

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "extension/**"
  forbidden_paths:
    - "src/**"
    - "server/**"
    - ".github/**"
    - "docs/**"
  commands:
    - "npx vitest"
    - "git"
  merge_policy: "none"
  ttl_hours: 24
```
> ★ merge_policy=none — PR OPEN 유지(자동머지 금지). 머지 판정은 아누 Codex+독립검증.

## 배경·단일소스
- 설계: `/home/jay/workspace/memory/plans/insuro-composite-design/integration-design-260721.md` (X 아키텍처=확장 중심, 결정9 model A + source-based taint-guard).
- 리포 `/home/jay/projects/InsuRo`, base=현 origin/main(bf44379, Phase2 서버 PR-D0 반영됨).
- **Integration Phase2 PR-D1**. PR-D2(플로우: 매칭UI·assembly·ingest)는 별도. 이 task 는 **bytes 인프라 + taint-guard만**(서버 호출·UI 없음, 서버 없이 단위검증 가능).

## 왜 (Codex 실측 갭)
현재 확장(Track A)은 로컬 미리보기만: JWT 가 `chrome.storage.local`(session 아님), byte-보존 재시도 경로 없음, request_body_bytes 조립부 없음. model A 인프라를 먼저 깐다.

## 작업 (결정9 model A)
1. **저장소 = `chrome.storage.session`**: SW 사망에도 생존·브라우저 재시작 자동소멸. **JWT 도 storage.local → storage.session 이동**(Codex 지적). SW 전역변수/content main-world/popup 상태/localStorage/IndexedDB 금지.
2. **★ source-based taint-guard (유일 load-bearing 불변식)**: PII(고객 reference·설계결과·동의)를 **직렬화 불가능한 opaque 래퍼**(예: 값은 WeakMap/closure 에, toJSON→throw, enumerable 필드 0)에 담아, **어떤 sink(log/console/telemetry/storage/URL)로 가도 안전**. sink 열거 방식 아님. **sink-spy 유닛테스트**로 강제(console/JSON.stringify/스토리지 저장 시 PII 문자열 0).
3. **byte-보존 조립·재시도 프리미티브**: `request_body_bytes` 를 **1회 조립 → base64 + sha256 hex 로 굳혀** storage.session 저장. 재시도 = base64 디코드 후 **그대로 재전송**(재직렬화 0). 조립 API 는 이 task 에서 **인프라만**(실제 payload 필드 채움은 PR-D2). idempotency_key 도 조립 시 1회 생성·bytes 와 함께 보존.
4. **수명 = save-operation scope**: `chrome.alarms`(setTimeout 금지) + **read-time lazy expiry**(now-createdAt 초과 시 즉시 폐기·미전송). 폐기 트리거 훅: 성공·취소·계정전환·만료·재시작 자동소멸. (실제 UI 이벤트 연결은 PR-D2, 여기선 폐기 함수·alarm 인프라만.)
5. **Track A 로컬 미리보기 유지**(회귀 0).

## 제약
- **서버 호출·UI 신설 0**(PR-D2). 이 task 는 순수 클라이언트 인프라·유닛테스트.
- request_body_bytes 에 실제 reference/consent/matrix 채우는 로직은 PR-D2 — 여기선 **조립·보존·재전송 프리미티브 + taint-guard**만.
- extension/ 밖 변경 0. Track A 기존 테스트 회귀 0.

## 검증 (전부 통과)
- **taint-guard**: PII 래퍼를 `console.log`/`JSON.stringify`/storage 저장/URL 조립에 넣어도 **PII 문자열 유출 0**(sink-spy). 래퍼 toJSON/enumerable 우회 시도 → 안전값.
- **byte 보존**: 조립한 bytes → base64 저장 → 디코드 → **원본과 바이트 동일**(sha256 일치). 재직렬화 경로 0.
- **storage.session**: 값이 storage.session 에만, local/IndexedDB 0. 재시작 시뮬레이션 → 소멸.
- **수명**: lazy expiry(만료 초과 read → null), alarm 폐기, 계정전환/성공/취소 폐기 함수 동작.
- 기존 확장 테스트(track-a-*) 회귀 0.

## 완료
- extension/ 외 변경 0 (`git diff --stat`)
- **dev6 금지** — dev1. worktree finish(STRICT+정확base+worktree cwd) → PR(OPEN 유지) → ANU 독립검증. **머지 금지**(merge_policy none).
- **ANU callback**(UTF-8 ≤3900 bytes, envelope). scope-guard 막힘 시 result.json+ANU callback.
