# Agent 미팅: InsuRo integration gate 결정 9·10 확정

**날짜**: 2026-07-21
**소집 이유**: A↔B integration gate G-1 의 미결 결정 2건(9 PendingRequestBytesPolicy, 10 테스트계정 allowlist) 확정. 금융/보험 PII·fail-closed.
**참여 페르소나**: 불칸(백엔드), 이리스(프론트), 헤임달(보안QA), 아테나(UX), 로키(레드팀·DA), 오딘(아키텍처·cycle2 DA)
**미팅 모드**: hybrid
**토론 깊이**: thorough (Lv.4)
**총 사이클 수**: 2

---

## Cycle 1 (independent)

### 페르소나 의견 요약
- **불칸(백엔드)**: 결정10 찬성. authz 입력은 세션에서·intent 는 payload 에서. **미들웨어(deserialize 전) 게이트·기본 DISABLED·fail-closed·원격 flag store+짧은 TTL 캐시·정확매치·감사로그**. 하드코딩 금지(kill-switch 상수만 예외). 결정9 서버측: 키재사용+body불일치=409, 완료응답 저장·replay, in-flight 상태전이 원자성, 멱등레코드 TTL, operation_scope 서버검증, **인가→해시 순서 강제**.
- **이리스(프론트)**: 결정9 "메모리 전용"을 **`chrome.storage.session`** 으로 확정(브라우저 프로세스 RAM·SW 사망에도 생존·재시작 자동소멸·TRUSTED_CONTEXTS). base64+sha256 굳혀 저장, 재시도는 디코드 후 그대로 전송(재직렬화 금지). **30분은 setTimeout 금지 → chrome.alarms + read-time lazy expiry**. "unload" 트리거는 MV3 에서 신뢰불가. encrypted storage 불채택(복잡도만↑).
- **헤임달(보안QA)**: 둘 다 찬성(강). "폐기했다"를 **관측된 부재(sink-spy)로 증명**. 결정9 최대 리스크 = **부수경로 누출**(APM/에러트래커/crash dump/console/URL/dataLayer/서버 access log) → **allowlist 직렬화+scrubber**. 결정10 = IDOR 매트릭스 6종·JWT 서명선행·fa_account_id 파생소스 단일성(정적+런타임+뮤테이션 3중). 뮤테이션 killed 필수.
- **아테나(UX)**: 결정9 (c)(d) 지지. **(b) 30분 수정** — idle TTL 과 "저장 의도" 분리. 저장 클릭 순간 idle 무효화. 만료 시 **조용한 실패 금지→투명 재조회**. 재시도=명시 버튼. INVALIDATED 잠금+사유+복구액션. **폼 입력값 보존**(재조회 1클릭화).
- **로키(레드팀·DA)**: memory-only ≠ 안전. 6공격(텔레메트리 유출·BFCache·SW→IndexedDB flush·계정전환 레이스·XSS fetch-hook·heap 미소거). 결정10 = 신원게이트뿐·**데이터 스코핑(IDOR) 없음**·세션탈취·TOCTOU.

### 비관습 대안 (로키)
**"Zero client-residency + capability-scoped single-shot"**: 저장클릭=즉시 1회 POST(로컬 pending=0), opaque result_id 반환, 즉시 폐기. capability token(단수명·단회·fa_account_id+계약id 바인딩)+taint 가드. 평가: 지지=공격표면 제거 / 반론=오프라인 재시도 마찰·전송중 노출·서버인프라 / 노력 중~높음 / 리스크 낮~중.

### 미해결 → cycle 2
로키 zero-residency(B) ↔ 계약 §2-3(로컬 bytes 보관, A) **정면 충돌**. 아키텍처 판정 필요.

---

## Cycle 2 (sequential 심화)

### Devil's Advocate: 오딘 (아키텍처)
**축 재정의**: "보관 vs 폐기"가 아니라 **"누가 재전송 bytes 를 소유하나"** — 3모델: **A**(클라 보관=계약) · **B**(로키 폐기) · **C**(서버 draft custody).

1. **로키 B 공격**: "6벡터 통째소멸"은 과장 = 실측 **2 clean + 2 duration-reduce**. 계정전환 레이스는 서버 `(fa_account_id, operation_scope, idempotency_key)` unique 가 이미 차단. XSS fetch-hook 은 B 도 fetch 하므로 여전. heap 은 기간 단축일 뿐. **결정타: B 는 멱등 설계의 존재이유(응답 유실 불확실성)를 재도입** — 응답 유실 시 클라가 bytes 없음(재시도 불가)+result_id 없음(조회 불가)→재제출→**새 멱등키=중복 write=데이터 무결성 결함**. flaky mobile 필드 FA 에 구조적 최악. capability token = net-new nonce store(인프라 오히려 추가).
2. **A+가드 공격**: 5가드 중 **load-bearing 1개 = taint-guard-to-sink + scrubber**(부수경로 누출이 진짜 breach). 나머지(storage.session·alarms·idle분리)를 병렬 기념비로 쌓으면 tribal-knowledge 부채. → **taint-guard 를 유일 불변식으로, sink-spy 테스트로 강제** = 감사가능. A 진짜 취약점 = flat 30분 idle window(과잉).
3. **DA 3대**: (1)실패=필드 FA=flaky mobile→B 가 응답유실 집중 / A=나중 추가 sink 무가드 누출 (2)후회=B→오프라인 큐 요구 시 재아키텍처+§2-3 2차개정 / A→가드 부족화 silent leak (3)단순대안=**save-operation-scoped 잔존**(초 단위 transient 재시도, 그후 re-fetch).
4. **최종 권고(커밋)**: **모델 A 유지, §2-3 개정 금지 + 3수정**. B 파일럿 outright 기각. 규제가 클라 PII 잔존 hard-line 금지 시에만 **C(서버 draft custody)로 개정, 절대 B 아님**.

**반박·판정**: 로키 DA 우려(부수경로 누출)는 **taint-guard 단일 불변식화로 흡수**(설계 강화). zero-residency 는 오딘이 데이터 무결성 근거로 반박 → **채택 불가 판정**. 합의 성립.

---

## 최종 합의 사항

### 결정 9 — PendingRequestBytesPolicy → **모델 A(operation-scoped) 채택**
1. **보관위치**: `chrome.storage.session`(브라우저 프로세스 RAM, SW 사망 생존, 재시작 자동소멸, TRUSTED_CONTEXTS). SW 전역변수/content main-world/popup 상태/localStorage/IndexedDB **금지**. encrypted storage **불채택**.
2. **보관형태**: 저장클릭 시 **1회** 조립 → **base64 + sha256 굳혀** 저장. 재시도 = 디코드 후 SHA 재검증만 하고 **그대로 전송**(재직렬화 절대 없음).
3. **수명**: **save-operation 스코프**(idle 30분 flat 폐기). 저장 클릭 순간 idle 시계 무효화, transient 재시도(초~저분)까지만 생존, **그 이상은 폐기 후 re-fetch**.
4. **★ 유일 load-bearing 불변식**: **taint-guard-to-sink + scrubber** — PII 객체를 telemetry/log/storage/URL sink 로 넘기면 실패. **sink-spy 유닛테스트로 강제**(APM/console/crash dump/dataLayer/access log 전수 스캔=0). allowlist(허용필드 열거) 직렬화, denylist 금지.
5. **폐기 트리거**: 저장성공·취소·계정전환 즉시삭제 + save-operation 만료 + 재시작 자동소멸. `chrome.alarms`(setTimeout 금지) + **read-time lazy expiry** 이중방어.
6. **계정전환**: 전송 **차단 후 삭제** 순서 강제. A4 `INVALIDATED` 노출 → integration 저장버튼 잠금(사유+재조회 액션).
7. **재시도 UX**: **명시 버튼**(조용한 자동 재전송 금지). 만료 시 조용한 실패 금지→**투명 re-fetch**. **폼 입력값 보존**으로 재조회 1클릭화.

### 결정 10 — 테스트계정 allowlist → **fa_account_id 서버 principal 단독 + 데이터 스코핑**
1. **판정 입력**: **서버 인증세션 principal 에서 파생한 fa_account_id 단독**. body/query/비인증 헤더/비세션 쿠키 유래 **0**(정적+런타임 단언). 클라이언트 pilot flag·rollout_stage·account_id 주장 **전면 불신**.
2. **게이트 위치**: **미들웨어(deserialize 전)**, 기본 **DISABLED**, fail-closed(조회 실패=차단). JWT **서명·만료·issuer·aud 검증 선행**. **매 요청 재검사**(TOCTOU·세션ID 회전).
3. **★ 데이터 스코핑(IDOR 차단, 로키 지적)**: allowlist(누가 호출)만으로 부족 → **(reference_type, reference_id) 의 인증 tenant 소속 검증 병행** = 계약 `TENANT_REFERENCE_MISMATCH`(이미 존재)로 충족. 파일럿 계정이 마스터키 되지 않게.
4. **store**: 원격/DB + 짧은 TTL 캐시(파일럿 소수면 프로세스 캐시), **정확매치만**(prefix/regex 금지), 하드코딩 금지(컴파일 kill-switch 상수만 예외), **감사로그**(누가·언제·판정).
5. **뮤테이션**: fa_account_id 소스를 `req.body.account_id` 로 변조→IDOR 테스트 killed. JWT 서명검증 제거→killed. pilot flag 반영 주입→killed.

---

## 미해결 항목
- **[OPEN·회장/법무 결정]** 금소법/PII 규제가 **클라이언트 PII 잔존 자체를 hard-line 금지**하는가? YES → **모델 C(서버 draft custody)로 §2-3 개정**(B 아님). 기본값 = 모델 A(operation-scoped).
- **[OPEN·구현]** transient 재시도 정확 timeout(초 단위) 값 → integration 구현 결정.
- **[OPEN·구현]** allowlist store: 파일럿 소수(env) vs DB — 불칸 "소수면 env 허용, DB 권고".

## Temporal Interrogation
- [RESOLVED] bytes 저장소 = chrome.storage.session
- [RESOLVED] bytes 수명 = save-operation scope (not flat 30min)
- [RESOLVED] taint-guard-to-sink + scrubber = 유일 불변식, sink-spy 테스트
- [RESOLVED] 재시도 = 명시 버튼 + 만료 시 투명 re-fetch + 폼 보존
- [RESOLVED] allowlist = fa_account_id 서버 principal, 미들웨어 pre-deserialize, 매요청 재검사
- [RESOLVED] 데이터 스코핑 = TENANT_REFERENCE_MISMATCH(계약 기존)
- [OPEN] 규제 hard-line 여부 → 모델 C 분기 (회장/법무)
- [OPEN] transient timeout 값, allowlist store 매체

## 다음 단계
1. 회장 보고 + **[OPEN] 규제 hard-line 질문** 확정(모델 A vs C 분기).
2. 합의를 integration gate 스펙 G-1-a/G-1-b 에 반영(계약 §2-3 개정 불필요 — 모델 A operation-scoped 는 계약 준수).
3. 나머지 gate G-1 진입조건(3~6 재검증·8 B0확인·11 승인) 처리 후 integration task 발주.
