# task-2788+2 — A-0 라이브 실행 직전 최종 micro-fix (3건, Codex AGREE)

## 레벨
Lv.2. **same-branch `task/task-2788-dev5` 계속 커밋. PR·merge·배포 금지.**

## 단일 소스
`memory/specs/ohmy_product_premium_data_contract_v1_260718.md` (**§AMENDMENT-1 다중사용자 제약 필독**) + `memory/tasks/task-2788+1.md`

## 배경 (GPT 지적 + 회장 지시 + Codex AGREE)
+1 보안가드 완료·검증됨(495 PASS, delta 2파일). 라이브 실행 직전 **3건만** 보강한다. 그 외는 전부 production 이식 task 로 미룬다(Codex AGREE).

## ★ 불변식 (유지)
서버 전송 0 · **토큰 저장/캐시/로깅 0** · 클릭 전 무동작 · MAIN world 인터셉터 추가 금지 · inject.js/manifest 미수정 · PR/merge/배포 금지 · **기존 보안가드(S1~S5) 무력화 금지**.

## allowed_resources
```yaml
allowed_resources:
  paths:
    - "extension/content.js"
    - "extension/background.js"
    - "extension/__tests__/direct_fetch_spike.test.ts"
    - "memory/reports/task-2788+2.md"
  forbidden_paths: ["src/**","server/**","supabase/**","**/migrations/**",".github/**",".env*","extension/inject.js","extension/manifest.json"]
  new_file_limit: 0
  commands: ["git","npm","node","npx"]
  merge_policy: "none"
  ttl_hours: 5
```

## 수정 요구 (정확히 3건 — 그 외 추가 금지)

### T1. `token_source` 기록 ★회장 지시
회장 지적: **"사용자마다 ohmymanager 진입 시 토큰이 다를 수 있다"**. 현 설계는 `?token=` 이 URL 에 있다는 **가정**에 의존한다. 사용자마다 진입경로(북마크·SPA 라우팅·SSO·쿠키세션)가 달라 **토큰이 URL 에 아예 없을 수 있다.**
- verdict 에 **`token_source: "URL_QUERY" | "ABSENT"`** 추가.
- `ABSENT` 면 **fail-closed** — 다른 곳에서 토큰을 긁어오는 **우회 조립 절대 금지**, 저장된 과거 토큰 재사용 **절대 금지**. verdict 만 반환하고 중단.
- 토큰 **원문·부분문자열 로깅 금지**(존재여부·길이만).

### T2. URL allowlist 포트 조건 (GPT 지적 — 현재 누락)
`isAllowedSpikeUrl` 이 `protocol/hostname/pathname` 만 검사해 **`https://mmlfcp.ohmymanager.com:8443/api/ProductPremiums` 가 통과**한다.
- **포트 조건 추가**: `u.port === "" || u.port === "443"` 만 허용. 그 외 거부(`URL_NOT_ALLOWED`).

### T3. `url_entry_age_ms` 관찰 기록 (차단 아님)
선택된 resource timing entry 가 **얼마나 오래된 것인지** 기록.
- verdict 에 **`url_entry_age_ms`**(선택 entry 의 `startTime` 기준 경과 ms) 추가.
- **차단하지 않는다**(관찰 전용). 조회 없이 눌렀을 때 오래된 URL 을 썼는지 사후 판별용.
- entry 미발견 시 `null`.

## ★ 이번 범위 아님 (production 이식 task 로 — Codex AGREE)
화면값(age/gender/insurance_type/plan_id) 대조 · session owner 비교 · 불일치 시 fetch 차단 · query key allowlist · DOM 기반 URL 직접 구성 · consultantid 기반 세션전환 상태기계. **여기에 손대지 말 것.**

## 검증
`direct_fetch_spike.test.ts` 에 추가: `token_source` 2분기(URL_QUERY/ABSENT) + ABSENT 시 **fetch 미호출** · 포트 거부(`:8443`, `:80`) 및 허용(`443`·생략) · `url_entry_age_ms` 산출/`null` · **거부·성공 모든 경로에서 토큰 문자열 미포함** assert.
기존 테스트 **전부 유지**(495 기준 감소 금지). **ANU 가 `npx vitest run` 전체 독립 재실행.**

## goal_assertions
- `npx vitest run`

## STOP_REPORT 조건
포트 조건 추가 시 정상 경로가 막힘 · `token_source` 판별이 구조적으로 불가 · resource timing entry 의 startTime 접근 불가 · manifest 수정 필요.

## 금지
서버 전송 · 토큰 저장/캐시/로깅 · 자동 실행 · 인터셉터 추가 · inject.js/manifest 수정 · 기존 보안가드 완화 · PR·merge·배포 · 위 "범위 아님" 항목 착수.

## 산출물 & 보고
1. same-branch 커밋. PR 금지.
2. 보고: diff / T1·T2·T3 근거 / 신규 분기 테스트 결과 / vitest 카운트 / MATCH·GAP.
3. 봇 종료 전 ANU callback(envelope만·UTF-8 ≤3900B, collector=ANU key c119085addb0f8b7).