WI-...-028~033 에 대응하는 FE-OC-027~032 owner 노트.
- 각 노트의 제외 범위에 'use case·domain model·business rule' 을 명시해
이 skeleton 이 port 와 adapter 계약까지임을 못박았다
- 근거 절에 '근거 등급 경계' 문단을 넣어 project-local default 와
외부 근거를 구분했다 (수집은 FE-Q-011~014 가 소유)
- 구현 가이드 절은 비워 두고 사유를 남겼다 — 근거 raw 없이 채우면
모든 cell 이 UNSUPPORTED_IMPL_DECISION 이 된다
- multi-protocol 노트는 '신규 port 0개' 를 제외 범위에 명시했다.
port 가 늘어나면 그 자체가 회귀 신호다
FE-D019("service worker와 offline asset cache는 default off") 는 FE-D034 로 superseded 되었다. 이 branch 는 그 후속 결정의 owner 이며, 아래는 예외 선언이 아니라 대체 사실의 기록이다.
Override ID
Overrides
Reason
Approval
Status
—
—
예외 없음. DEC-...-OFFLINE-CACHE-001@2 를 그대로 소비한다
—
—
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-OFFLINE-CACHE-001@2 의 소비자는 raw/branch-notes/feature-frontend-release-cache-rollback-contract 이며, 이 branch 는 그 결정을 SERVICE-WORKER-ROLE-001@1 로 상속받아 SW 쪽 절반을 구현한다. precaching 절반은 여전히 release branch 소유이자 default off 다.
WorkerTaskPort·ServiceWorkerHostPort·BackgroundSyncPort 를 정의하고, FE-D034 의 SW 역할 분리를 구현 계약으로 내린다. 이 계약이 없으면 Background Sync 가 idempotency key 없는 mutation 을 재생해 중복 생성하고, SW precache 가 이전 release 자산을 붙들어 FE-OC-016·FE-OC-017 의 release coherence 를 깬다.
근거 등급 경계: FE-D034(SW 역할 분리)의 rationale 은 precaching은 release coherence 훼손 원인이나 push·sync는 SW 없이는 불가; project decision 이고, FE-D035·FE-D036 은 각각 FE-D016 상속과 project decision 이다. Service Worker·Background Sync·Web Push 명세를 다룬 raw 자료는 이 repo 에 없다(FE-Q-011). skipWaiting 금지는 명세가 아니라 FE-OC-016 coherence 에서 도출한 project 판단이다.
TODO
WorkerTaskPort 인터페이스와 timeout·terminate 계약 확정 — 등급: planned
ServiceWorkerHostPort 인터페이스와 등록 scope 확정 — 등급: planned
BackgroundSyncPort 의 keyed-only 등록 조건 — 등급: planned
§9.7 update surface state 와 사용자 주도 적용 action — 등급: planned
serviceWorkerVersion 토큰 산출과 release manifest 연결 — 등급: planned
worker/SW 엔트리 import 경계 lint fixture — 등급: planned
FE-D019 를 되살리려는 압력이 나중에 생길 수 있다 — "이왕 SW 있으니 자산도 캐시하자". 그 순간 FE-OC-016·FE-OC-017 이 다시 위태로워진다. precaching 을 켜려면 FE-D034 를 다시 supersede 하는 절차(§3.3)를 밟아야 하며, 그때 update UX 와 rollback drill 이 함께 설계되어야 한다는 조건이 FE-D034 의 revisit trigger 에 이미 적혀 있다.
결정 사항
2026-07-28: 자동 skipWaiting 금지 / 이유: 열린 탭이 release 를 갈아타면 HTML·asset·config 가 섞임 / 검토한 대안: 유휴 시 자동 적용 / 근거: FE-OC-016 coherence 에서 도출, 근거 raw 미수집
2026-07-28: background sync 는 keyed only / 이유: 지연 재생은 중복 write 위험이 온라인 재시도보다 큼 / 검토한 대안: 모든 mutation 재생 + 서버 dedup 신뢰 / 근거: FE-D035 (FE-D016 상속)
결정-근거 매핑
Decision ID
Decision
선택 조건 (언제 이 결정 / 언제 대안)
Supporting Claims
Evidence Strength
Open Risk
D1
자동 skipWaiting 금지
항상. 모든 탭이 단명하는 제품이면 재검토
FE-OC-016 coherence 도출
project decision
사용자가 적용 action 을 누르지 않으면 구버전이 오래 남음
D2
serviceWorkerVersion release token
SW 를 쓸 때. 안 쓰면 토큰은 비어 있음
없음 — FE-Q-011
project-local default
release manifest 스키마가 커짐
D3
worker/SW 엔트리의 import 경계
항상
없음 — FE-Q-011
project-local default
공유 로직을 복제하게 될 수 있음 — domain 순수 모듈 참조로 완화
구현 가이드
근거 raw 자료(FE-Q-011) 수집 전까지 비워 둔다. SW 수명주기(installing→waiting→active)와 Background Sync 의 재시도 정책은 명세를 읽지 않고 쓸 수 없다.
엣지·실패·의존
실패·엣지 경로
SW 등록·갱신 실패 → SW_REGISTRATION_FAILED, SW 없이 계속. 제품 흐름을 차단하지 않음
새 SW 설치 완료 → sw-update-pending. 실패가 아니라 상태이며 error kind 가 아님
Background Sync API 미지원 → BACKGROUND_SYNC_UNSUPPORTED, 온라인 복귀 시 전면 재시도로 대체
keyed 아닌 mutation 의 재생 시도 → BACKGROUND_SYNC_REPLAY_REJECTED, 큐에서 제거하고 재생하지 않음
Worker 생성 불가 → WORKER_UNAVAILABLE, 메인 스레드 대체 경로 또는 기능 저하
worker task timeout → WORKER_TASK_TIMEOUT, terminate 후 결과를 기다리지 않음
rollback 후 SW 버전 불일치 → FE-RB-007 절차. serviceWorkerVersion 을 함께 되돌림