Files
llm-wiki/raw/branch-notes/feature-frontend-realtime-subscription-lifecycle-contract.md
DongHyeonka 7bcb54c464 docs(branch-spec): feature-frontend-binary-file-io-store-contract 채움
MDN 근거 3건 수집 후 결정 7개를 근거 기반으로 확정하고 §구현 가이드
4개 sub-section 을 채웠다. 조사에서 기존 계약 2건의 사실 오류가 나왔다.

- EVICTION_SCOPE_DRIFT: 브라우저 eviction 은 origin 전량 삭제이므로
  FE-REG-STORAGE.evictionOrder 는 애플리케이션 주도 정리에만 유효
- CACHE_STORAGE_CONSTRAINT_DRIFT: Cache Storage 는 SW 전용이 아니다
  (Window.caches 접근 가능). FE-D027 의 제한은 정책이지 플랫폼 제약이 아님
- NO_GROUND_TRUTH: ca-tmpl 은 backend 전용이라 이 branch 에 미적용
- CAPABILITY_NAME_COLLISION: ca-tmpl capabilities.yaml 과 다른 개념

신규 raw: mdn-storage-quotas-eviction-persistence,
mdn-file-system-access-opfs, mdn-object-url-cache-storage
6개 신규 branch-note 전부에 governing_docs 추가.
2026-07-28 15:24:19 +09:00

17 KiB

title, source_type, status, id, kind, project, work_item, inherits, refines, overrides, depends_on, imports, delegates, accepts_delegations, contract_packet, branch, parent_branch, related_projects, governing_docs, tags, created, target_merge, status_label
title source_type status id kind project work_item inherits refines overrides depends_on imports delegates accepts_delegations contract_packet branch parent_branch related_projects governing_docs tags created target_merge status_label
branch / feature-frontend-realtime-subscription-lifecycle-contract branch-note raw BR-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-032 project-work-item ca-skeleton-frontend-operational-contract WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-032
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-CAPABILITY-001@1
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-REALTIME-TRANSPORT-001@1
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-REALTIME-LIFECYCLE-001@1
WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-006
WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-007
WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-013
FE-GATE-031@1
FE-OC-007@1
FE-OC-008@1
FE-OC-011@1
FE-OC-025@1
FLOW-FE-EVENT-003@1
FLOW-FE-EVENT-004@1
FLOW-FE-EVENT-005@1
DELEG-FE-007@1
1 feature-frontend-realtime-subscription-lifecycle-contract
ca-skeleton-frontend
ca-skeleton
raw/project-notes/ca-skeleton-frontend-operational-contract.md
branch
ca-skeleton-frontend
realtime
sse
websocket
push
2026-07-28 in-progress

branch: feature-frontend-realtime-subscription-lifecycle-contract

부모 (필수)

형제 branch (같은 부모, 이번 확장에서 함께 생성):

브랜치 계약 패킷

  • 생성 시 프로젝트 개정: 2
  • 패킷 스키마: contract_packet: 1
  • 완료 조건: backoff·resume·구독 해제·이벤트 검증 fixture와 FE-RB-006 drill이 통과한다

상속한 프로젝트 결정

Decision Ref Project Summary Branch Application Source
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-CAPABILITY-001@1 신규 runtime capability 6종은 FE-REG-CAPABILITY flag로 default OFF이며 활성화는 owner·gate·runbook을 동반한다 CAP_FE_REALTIME 을 이 branch 가 소유하고 default OFF 로 유지한다 raw/project-notes/ca-skeleton-frontend-operational-contract
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-REALTIME-TRANSPORT-001@1 실시간 transport는 SSE를 우선하고 양방향이 필요하면 WebSocket, 둘 다 불가할 때만 최소 간격·backoff·visibility gating을 갖춘 bounded polling을 쓴다 RealtimeSubscriptionPort adapter 선택 순서에 적용한다 raw/project-notes/ca-skeleton-frontend-operational-contract
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-REALTIME-LIFECYCLE-001@1 실시간 연결은 full jitter backoff와 30초 cap을 쓰고 재시도 상한 후 terminal 상태로 전이하며 resume은 Last-Event-ID 또는 cursor로 수행하고 unmount 시 구독을 해제한다 연결 수명주기 상태 기계와 해제 계약에 적용한다 raw/project-notes/ca-skeleton-frontend-operational-contract

브랜치 지역 결정

Decision ID Decision Relation Supporting Claims Status
D1 구독 해제는 RealtimeSubscriptionPort 가 반환하는 handle 로만 수행하고, adapter 내부에 열린 연결 목록을 유지해 파괴 시 전부 닫는다 refines DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-REALTIME-LIFECYCLE-001@1 근거 raw 미수집 (FE-Q-011) proposed
D2 backoff jitter 의 random source 는 주입 가능해야 한다 (결정론 테스트 요건) local DELEG-FE-005 선례 — feature-api-client-response-envelope-contract 가 같은 문제를 이미 위임함 proposed
D3 구독별로 독립적인 full jitter 를 쓰고, 추가로 전역 동시 재연결 상한을 둔다 local 근거 raw 미수집 (FE-Q-011) proposed

선언한 예외

해당 없음.

가져온 artifact 계약

Artifact Ref Owner Producer Schema Ref

가져온 프로젝트 계약

Ref Owner 요약 Branch 적용
FE-GATE-031@1 raw/project-notes/ca-skeleton-frontend-operational-contract backoff·resume·구독 해제·이벤트 검증 fixture 가 실패하면 merge·release 를 MUST 차단 이 branch 가 owner 로서 fixture 와 report 를 산출
FE-OC-007@1 raw/branch-notes/feature-runtime-schema-validation-contract JSON envelope와 payload는 boundary에서 runtime schema를 MUST 통과 인바운드 프레임도 같은 규칙 적용
FE-OC-008@1 raw/branch-notes/feature-frontend-error-classification-boundary-contract 모든 failure는 stable frontend error kind로 MUST 정규화하고 raw body·stack을 UI에 노출하면 안 됨 실시간 실패 4종의 정규화 대상
FE-OC-011@1 raw/branch-notes/feature-async-ui-state-contract async surface는 initial-loading, success, empty, terminal-error를 MUST 표현 §9.5 실시간 state 를 이 4-state 에 매핑
FE-OC-025@1 raw/branch-notes/feature-frontend-operational-runbook-contract boot, chunk mismatch, API degradation, telemetry failure, rollback, realtime 연결, background 실행 runbook을 MUST 유지 FE-RB-006 의 기술 escalation 대상

수신한 위임

없음. 이 branch 는 DELEG-FE-007 의 delegator 다.

가져온 흐름 단계

FLOW-FE-EVENT-001·002 는 이 branch 가 소유하므로 import 하지 않는다.

Stage Ref Order Owner Input Action Output
FLOW-FE-EVENT-003@1 3 feature-runtime-schema-validation-contract unvalidated event JSON event envelope 공유 스키마 검증 discriminated event envelope
FLOW-FE-EVENT-004@1 4 feature-runtime-schema-validation-contract discriminated event envelope eventSchema per-event 검증 검증된 event payload
FLOW-FE-EVENT-005@1 5 feature-frontend-error-classification-boundary-contract 검증된 event payload 또는 실패 신호 정규화된 이벤트 또는 failure 반환 application event 또는 normalized failure

목표

RealtimeSubscriptionPortPushSubscriptionPort 를 정의하고, 연결·재연결·재개·이벤트 검증·해제를 계약한다. 이 계약이 없으면 끊김에 상한 없는 즉시 재연결을 걸어 backend 를 증폭 공격하고, 라우트 이탈 후에도 WebSocket 이 열린 채 남아 연결 수가 단조 증가하며, 미검증 프레임이 상태에 병합되어 TypeError 가 렌더 트리 깊은 곳에서 늦게 터진다.

  • 이슈:
  • PR:

범위

포함 범위

  • RealtimeSubscriptionPort — SSE·WebSocket·bounded polling adapter
  • PushSubscriptionPort — 권한 요청, VAPID 공개키 기반 구독 등록
  • 연결 수명주기 상태 기계와 §9.5 surface state
  • full jitter backoff, 30초 cap(REALTIME_RECONNECT_CAP_MS), 재시도 상한 후 terminal 전이
  • resume — Last-Event-ID / cursor, gap 감지
  • FLOW-FE-EVENT-001·002 소유 (프레임 수신, transport decode)
  • 구독 해제 계약과 누수 검출(SUBSCRIPTION_LEAKED fixture)
  • bounded polling 의 최소 간격·backoff·visibility gating
  • FE-RB-006 의 기술 escalation
  • CAP_FE_REALTIME capability 행 소유

제외 범위

근거 (필수, 최소 1개+)

Source 정당화하는 결정
[[docs/superpowers/specs/2026-07-28-ca-skeleton-frontend-runtime-adapter-features-design]] §5.1·§7.5·§9.2 port 분해, 이벤트 흐름 5단계, 실시간 surface state
raw/project-notes/ca-skeleton-frontend-operational-contract §7.5·§9.1 기존 retry backoff·jitter 정책과 async state 모델

근거 등급 경계: FE-D032(transport 선택 순서)와 FE-D033(연결 수명주기)의 rationale 은 각각 project-local default, 외부 source claim 아님재연결 폭주·구독 누수 억제, project decision 이다. SSE(WHATWG HTML EventSource)·WebSocket·Web Push 명세를 다룬 raw 자료는 이 repo 에 없다(FE-Q-011). 30초 cap 은 측정값이 아니라 초기 default 다.

TODO

  • RealtimeSubscriptionPort 인터페이스와 해제 handle 확정 — 등급: planned
  • PushSubscriptionPort 인터페이스 확정 — 등급: planned
  • transport 선택 순서(SSE → WebSocket → polling) 구현 — 등급: planned
  • full jitter backoff + cap + terminal 전이 (주입 가능 random source) — 등급: planned
  • resume cursor 와 gap 감지 — 등급: planned
  • FLOW-FE-EVENT-001·002 프레임 수신·디코드 — 등급: planned
  • 구독 해제 계약과 누수 fixture — 등급: planned
  • bounded polling 의 visibility gating — 등급: planned
  • §9.5 surface state 컴포넌트 매핑 — 등급: planned
  • FE-RB-006 drill assertion — 등급: planned
  • FE-GATE-031 realtime lifecycle report 산출 — 등급: planned

진행 중 메모

reconnectingdisconnected 의 구분이 이 branch 의 핵심 UX 계약이다. 전자를 terminal-error 로 표시하면 사용자가 불필요하게 새로고침하고, 후자를 refreshing 으로 표시하면 영원히 오지 않는 데이터를 기다린다. 구현 시 두 상태가 같은 컴포넌트 분기로 합쳐지지 않는지 리뷰에서 확인한다.

D2(주입 가능 random source)는 DELEG-FE-005 가 이미 같은 문제를 다뤘다 — feature-api-client-response-envelope-contractfeature-frontend-clean-architecture-layering-contract 에 주입 형태를 위임했다. 이 branch 는 그 결과를 재사용하고 새 위임을 만들지 않는다.

결정 사항

  • 2026-07-28: 재시도 상한 후 terminal 전이 / 이유: 무한 재시도는 backend 증폭이고 사용자에게도 상태를 숨김 / 검토한 대안: 무한 재시도 + 긴 cap / 근거: FE-D033
  • 2026-07-28: 구독별 독립 jitter + 전역 동시 재연결 상한 / 이유: 구독이 여럿이면 같은 시점에 만료해 thundering herd 가 됨 / 검토한 대안: 전역 단일 backoff / 근거: FE-RISK-016

결정-근거 매핑

Decision ID Decision 선택 조건 (언제 이 결정 / 언제 대안) Supporting Claims Evidence Strength Open Risk
D1 handle 기반 해제 + adapter 내부 연결 목록 항상 없음 — FE-Q-011 project-local default adapter 파괴 시점이 명확하지 않은 사용 패턴이 있을 수 있음
D2 주입 가능 random source 항상. 결정론 테스트 요건 DELEG-FE-005 선례 project precedent 주입 형태가 layering branch 결정에 종속
D3 구독별 독립 jitter + 전역 상한 구독이 2개 이상일 때. 단일 구독이면 전역 상한은 무의미 없음 — FE-Q-011 project-local default 전역 상한이 정상 재연결을 지연시킬 수 있음

구현 가이드

근거 raw 자료(FE-Q-011) 수집 전까지 비워 둔다. SSE 의 재연결·Last-Event-ID 동작과 WebSocket close code 해석은 명세를 읽지 않고 쓸 수 없다.

엣지·실패·의존

검증해야 할 주장

Claim Why uncertain How to verify Status
unmount 후 열린 구독이 0이다 해제 누락이 조용히 누적됨 fixture — 컴포넌트 mount/unmount 반복 후 adapter 내부 연결 목록 길이 0 (FE-NFR-017) planned
재연결 간격이 30초 cap 을 넘지 않는다 jitter 계산이 cap 을 초과하기 쉬움 결정론 fake clock test — 모든 시도 간격 ≤ cap (FE-NFR-016) planned
상한 소진 후 자동 재시도가 멈춘다 무한 루프가 조용히 남음 fixture — 상한 도달 후 추가 연결 시도 0 planned
미검증 프레임이 application 에 도달하지 않는다 검증을 우회하는 빠른 경로가 생기기 쉬움 negative fixture — 스키마 위반 프레임 주입 후 application 콜백 미호출 planned
스키마 위반 프레임 하나가 연결을 끊지 않는다 방어적으로 끊는 구현이 흔함 fixture — 위반 프레임 후 정상 프레임 수신 확인 planned
resume gap 이 실제로 감지된다 서버가 gap 을 알려주지 않으면 감지 방법이 제한적 integration test — 이벤트 ID 불연속 주입 후 REALTIME_RESUME_GAP needs-confirmation
다중 구독 재연결이 동시에 몰리지 않는다 독립 jitter 만으로 충분한지 불확실 부하 fixture — N개 구독 동시 끊김 후 재연결 시각 분포 (FE-RISK-016) needs-confirmation
bounded polling 이 백그라운드 탭에서 멈춘다 visibility gating 누락이 흔함 fixture — document.hidden 상태에서 요청 0 planned

관심사 커버리지 (coverage-auditor 자동 생성 — 있을 때)

미생성.

마주친 문제

없음.

묶음 (이 branch에서 파생된 자료)

Sub-branches (세부 작업)

아직 없음.

오류 기록 (이 branch 작업 중 발생)

아직 없음.

면접 준비 (이 작업에서 나올 수 있는 면접 질문)

아직 없음.

강의 (이 작업을 위해 학습한 강의)

아직 없음.

job-posting tie-ins (이 작업에서 파생된 글감)

아직 없음.

관련 일일 노트

  • 아직 없음

완료 후 정리

  • PR 링크:
  • 리뷰 메모:
  • 머지 결과 / 배포 환경:
  • wiki 추출 대상 (verified만, wiki/projects/로만 추출):
    • actually-implemented 항목: 없음
    • locally-verified 항목: 없음
    • prod-verified 항목: 없음
  • 추출하지 않을 항목: 현재 전 항목 planned