# task-2883 보고서 — 생보 캡처 실패 수정 (content script의 chrome.storage.session 접근 허용)

- 작업 ID: task-2883
- 팀: dev2-team (오딘)
- 레벨: Lv.2 / merge_policy: none (base=origin/main)
- 담당: 토르(백엔드, sonnet)
- 브랜치: `task/task-2883-dev2`
- worktree: `/home/jay/workspace/projects/insuro/.worktrees/task-2883-dev2`
- 프로젝트: InsuRo (`/home/jay/projects/InsuRo`, `workspace/projects/insuro` 심링크)

## Situation
InsuRo 확장에서 "생보 이어서 캡처" 클릭 시 화면 감지/스크랩은 정상인데도 항상 default 에러 문구("지금은 캡처할 수 없어요. 잠시 후 다시 시도해주세요.")가 표시됨.

## Complication
근본원인(회장 실사용 진단 확정): `content.js`의 `saveLifeMatrixToSession`/`loadLifeMatrixFromSession`이 **content script에서 `chrome.storage.session`을 직접 호출**하는데, `chrome.storage.session`의 기본 access level이 `TRUSTED_CONTEXTS`(백그라운드 전용)라 content script 접근 시 예외 발생 → `captureLifeMatrixToSession` 예외 → `.catch` → default 메시지. 확장 어디에도 `setAccessLevel` 호출이 없었음.

## Question
어떻게 content script의 session storage 접근을 안전하게 허용하고, 기존 동작 회귀 0을 보장하는가?

## Answer — 세션 스토리지 접근권한 승격 (범위 최소)

### 수정 파일 (전부 allowed_resources 범위 내)
1. **extension/background.js** (+41행)
   - `enableSessionStorageForContentScripts()` 헬퍼 추가(46행). `chrome.storage.session.setAccessLevel({ accessLevel: "TRUSTED_AND_UNTRUSTED_CONTEXTS" })` 호출을 `typeof`/존재 가드 + try/catch + Promise rejection 흡수로 감쌈 → 미지원 브라우저/테스트 mock에서 무해(no-op).
   - **세 지점**에서 호출: top-level(SW 로드 시, 445행) + `chrome.runtime.onInstalled`(449행) + `chrome.runtime.onStartup`(455행). SW 재기동·설치·브라우저 시작 모두 커버. 각 리스너 등록에 `chrome.runtime` 존재 가드 포함.
   - 맨 끝 `module.exports`에 `enableSessionStorageForContentScripts` 추가(483행, 테스트 노출).
2. **extension/content.js** (+5/-1행, 선택적 진단성 개선)
   - `handleCaptureLifeMatrixClick`의 `.catch(() => {...})` → `.catch((err) => {...})`, `console.error("[InsuRo] life matrix capture failed:", err)` 로깅 추가(535행). 사용자 문구/흐름 불변.
3. **extension/__tests__/task-2883-session-access-level.test.ts** (신규, +191행)
   - a7-write-path-blocked.test.ts의 vm/캐시버스팅 로딩 관례 준수. 4 테스트: ①top-level setAccessLevel(TRUSTED_AND_UNTRUSTED_CONTEXTS) 호출 ②onInstalled 콜백 재호출 ③onStartup 콜백 재호출 ④setAccessLevel 미정의 mock에서 예외 없이 graceful degrade.

### 불변 확인
- manifest.json 불변("storage" 권한 이미 존재). src/·server/·.github/ 불변. 손보 캡처·저장·consent·egress·taint-guard·life_matrix 라우팅 로직 불변.
- diff: 3 files, +236/-1. 전부 extension/ 범위 내(background.js, content.js, __tests__/).

## 테스트 결과 (팀장 독립 재실행)
- `npx vitest run extension/__tests__/` → **24 files / 505 tests 전부 PASS, 실패 0** (신규 4 포함).
- baseline(수정 전) 501 passed / 0 failed → 수정 후 505 passed(501+4) / 0 failed → **회귀 0**.

## L1 스모크테스트 결과
- **서버 재시작: 해당없음** — 대상은 Chrome 확장 service worker(`background.js`)의 `chrome.storage.session` access level 승격. 로컬 서버/API 없음.
- **API 응답 확인: 해당없음** — 네트워크 API 미관여(session storage 접근권한 코드 경로).
- **스크린샷: 해당없음** — 실 확장 런타임 수동 실증은 회장/ANU가 새 확장 빌드 재설치 후 "생보 이어서 캡처 → '생보 담보를 이어서 담았어요' 성공 메시지"로 확인(task 지시 44행). 봇 환경엔 확장 로드된 Chrome 없음.
- **실행한 관찰 가능 검증**: goal_assertion `npx vitest run extension/__tests__/`를 팀장이 직접 재실행(505 passed) + 신규 테스트가 setAccessLevel 3지점 호출 + graceful degrade를 단위 수준에서 계약 검증. diff scope grep 재확인.

## 발견 이슈 및 해결
- tsc 진단 경고 2건(content.js 191행 `_lastMmlfcpTrace`, 2888행 `snapshot` 미사용) 감지 — **본 변경(530~535행)과 무관한 pre-existing 미사용 변수**(diff 확인). 범위 외이므로 미수정.

## 머지 판단 (순서 B — merge_policy=none)
- **머지 필요: Yes (단, ANU 소유)** — task 지시상 봇은 push+.done까지. ANU 검증·머지·새 확장 빌드 전송 담당.
- 브랜치: `task/task-2883-dev2`
- 머지 의견: 변경 additive·extension-only·회귀 0·범위 내. 실 확장 수동 실증(생보 이어서 캡처 성공 메시지)은 ANU가 새 빌드로 확인 필요.

## 커밋
- `764633e` [task-2883] 토르: background.js session storage access level 승격 + content.js 캡처실패 로깅
- `bf21e01` [task-2883] 토르: session storage access level 승격 단위 테스트 추가

## 모델 사용 기록
- 토르(백엔드): sonnet. (전략/기획/크리에이티브 아님, haiku 미사용.)

## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회


## 세션 통계
- 총 도구 호출: 0회

