Files
llm-wiki/docs/superpowers/specs/2026-07-28-ca-skeleton-frontend-runtime-adapter-features-design.md
T
DongHyeonka d19670975b docs(spec): 실행 결과 반영 — 정정 3건과 검증 기록
- §12.1 #42: §21 표와 frontmatter imports 에 FE-OC-027~032 포함.
  둘 다 branch-owned 계약을 hub 가 pin 하는 자리다
- §12.3: registry 개수 서술이 Summary 밖에도 14곳 있었음
- §13: contract_packet_sha256 생성기 부재 — 신규 노트는 필드 미포함,
  기존 7개는 해시가 낡음
- §15 실행 기록 신설
2026-07-28 14:43:00 +09:00

81 KiB
Raw Blame History

CA Skeleton Frontend — 런타임 adapter feature 확장 설계

일자 / Date: 2026-07-28 대상 문서 / Target: raw/project-notes/ca-skeleton-frontend-operational-contract.md 범위 / Scope: 신규 능력 6개 도메인을 port·adapter·registry·gate 계층까지 계약화. use case·domain model·business rule 은 명시적 제외. 요청 언어 / User language: ko 상태 / Status: 설계 승인 완료 (2026-07-28), 구현 계획 미작성


0. 이 문서의 지위

이 문서는 raw/project-notes/ca-skeleton-frontend-operational-contract.md(이하 hub)에 무엇을 어떻게 추가할지 고정한 설계 스펙이다. hub 본문의 대체물이 아니며, 여기서 확정한 ID·문자열·수치를 hub 와 신규 branch-note 가 그대로 옮겨 담는다.

이 문서 자체는 구현 증거가 아니다. hub §0.2 의 증거 등급 경계가 그대로 적용되어, 여기 적힌 모든 계약·기본값·경로는 planned 또는 documented-only 다.


1. 배경과 문제

1.1 요청

사용자 요청은 hub 에 다음 능력을 "구현할 수 있게" 추가하되 런타임(adapter)까지이고 use case·domain 이 필요한 부분까지는 아니라는 것이다.

  1. File, Blob, 파일 선택기, 다운로드, IndexedDB, OPFS, Cache Storage
  2. TanStack Query 메모리 캐시, Local/Session Storage, IndexedDB, 탭 간 무효화
  3. Presigned URL, Multipart/Resumable Upload, Streaming Download, Image CDN
  4. REST·GraphQL·gRPC-Web API, Schema, Mapper, Server State Cache
  5. SSE, WebSocket, WebPush, 제한된 Polling
  6. gRPC-Web·Connect-Web·Protobuf 또는 REST Gateway
  7. Fetch HTTP Client, Runtime Config, Router, Query/Mutation
  8. Connection, Reconnect, Resume, Event Validation, Subscription Cleanup
  9. Web Worker, Service Worker, Background Sync

1.2 기존 계약과의 대조

요청 9묶음을 hub 의 26개 FE-OC-* 와 8개 registry 에 대조하면 상당 부분이 이미 계약되어 있다.

요청 묶음 기존 계약
7 (Fetch HTTP Client · Runtime Config · Router · Query/Mutation) FE-OC-004·FE-OC-005·FE-OC-006·FE-OC-012전부 존재
4 중 REST API · Schema · Mapper · Server State Cache FE-OC-006·FE-OC-007·FE-OC-012 + feature-boundary-mapper-viewmodel-contract존재
2 중 Local/Session Storage · IndexedDB FE-REG-STORAGE.backend enum 에 세 값 존재. OPFS·Cache Storage 는 부재
9 중 Service Worker FE-D019 / DEC-…-OFFLINE-CACHE-001default off 로 고정

따라서 순수 델타는 9개가 아니라 6개 능력 도메인이다. 나머지는 기존 계약의 additive 확장으로 처리한다.

1.3 델타가 만드는 구체적 실패

이 확장이 없으면 발생하는 실패를 명시한다. 계약은 이 실패를 막기 위해 존재한다(hub §2.2 질문 1).

실패 설명
Blob URL 누수 URL.createObjectURL 을 컴포넌트가 직접 부르고 revokeObjectURL 을 빠뜨려 탭 수명 동안 메모리가 증가한다.
조용한 quota fallback IndexedDB quota 초과 시 correctness 에 영향을 주는 값(업로드 part 상태)이 memory 로 fallback 되어 새로고침에 사라진다.
탭 간 stale 탭 A 의 mutation 이 탭 B 의 캐시를 무효화하지 않아 두 탭이 서로 다른 사실을 보여준다.
credential 유출 presigned URL 로 보내는 byte 전송에 session 헤더가 그대로 붙어, 제3자 스토리지 도메인에 인증 정보가 전달된다.
GraphQL 부분 실패 오판 200 OK + errors[] 응답을 success 로 반환해 빈 화면이 정상처럼 보인다.
gRPC status 오판 HTTP 200 + grpc-status: 13 을 성공으로 처리한다.
재연결 폭주 SSE/WebSocket 끊김에 상한 없는 즉시 재연결을 걸어 backend 를 증폭 공격한다.
구독 누수 라우트 이탈 후에도 WebSocket 이 열린 채 남아 연결 수가 단조 증가한다.
미검증 이벤트 인바운드 프레임을 스키마 검증 없이 상태에 병합해 TypeError 가 렌더 트리 깊은 곳에서 늦게 터진다.
중복 write Background Sync 가 idempotency key 없는 mutation 을 재생해 중복 생성한다.
release 훼손 Service Worker precache 가 이전 release 자산을 붙들어 FE-OC-016/FE-OC-017 의 release coherence 를 깬다.

2. 확정된 설계 선택 (사용자 승인)

선택 결정 근거
분해 단위 6개 능력 도메인 = FE-OC-027~FE-OC-032 + branch 6개 + WI 6개 요청 9묶음을 그대로 쓰면 FE-OC-004/005/006/007/012 와 소유권이 겹쳐 DUPLICATE_CONTRACT_OWNER 가 된다
활성화 자세 port + adapter 구현, capability flag default OFF FE-D019(SW off)·FE-D025(제거 가능 sample fixture) 자세와 일관. 안 쓰는 프로젝트가 번들·보안 표면을 떠안지 않는다
FE-D019 충돌 SW 역할 분리 후 supersede — precaching 은 OFF 유지, push·background sync·Cache Storage 호스트는 capability opt-in WebPush·Background Sync·Cache Storage 가 SW 없이는 동작하지 않는다
registry FE-REG-CAPABILITY 하나만 신설 → 9개. 실시간 구독은 FE-REG-API 의 protocol 행 구독을 별도 장부로 두면 같은 backend 를 REST/SSE 로 부를 때 operation 정의가 이원화된다
근거 자료 project-local default 로 명시 + §19.2 open question 으로 후속 조사 예약 FE-D001·FE-D010·FE-D011 선례. 없는 출처를 지어내지 않는다
산출물 hub 갱신 + branch-note 6개 스캐폴딩 각 branch 의 깊은 명세는 다음 단계

3. 범위

3.1 In scope

  • 6개 도메인의 port 정의(application 소유), adapter 구현 계약, registry 행, 정규화 실패 어휘, acceptance gate, NFR, runbook
  • 기존 8개 registry 의 additive 확장
  • FE-D019 supersede 를 포함한 결정 레지스트리 갱신
  • 신규 branch-note 6개 스캐폴딩과 Cluster 연결
  • 기존 branch-note 7개의 pin·문자열·위임 접수 정합 수정 (§12.3)

3.2 Out of scope

사용자 제약을 문서에 못박는 항목이다. hub §0.5 Out of scope 에 그대로 추가한다.

  • 6개 도메인의 use case, domain model, business rule — port 와 adapter 계약까지만 정의하고, 그 port 를 호출하는 use case 는 적용 프로젝트가 작성한다
  • 구체 backend API 설계(presigned URL 발급 endpoint 스펙, GraphQL 스키마, protobuf 서비스 정의, push 발송 서버)
  • 특정 vendor 선택(Image CDN 제공자, object storage 제공자, push 서비스)
  • 파일 형식별 처리(이미지 리사이즈 알고리즘, 비디오 트랜스코딩, 문서 파서)
  • 오프라인 우선(offline-first) 데이터 동기화 정책과 충돌 해결(CRDT, last-write-wins 등)
  • SSR·RSC·edge rendering (hub §0.5 유지)

3.3 Non-goal

  • 6개 도메인을 기본 활성화하는 것. 기본값은 전부 OFF 이며 FE-GATE-033 이 이를 증명한다.
  • 기존 26개 FE-OC-* 의 의미 변경. FE-OC-006·FE-OC-012·FE-OC-013 은 확장되지만 normative summary 는 유지된다.

4. 도메인 분해

4.1 도메인 → 계약 · branch · Work Item

계약 도메인 branch slug Work Item
FE-OC-027 바이너리/파일 I-O + 로컬 대용량 저장 feature-frontend-binary-file-io-store-contract WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-028
FE-OC-028 캐시 계층 + 탭 간 무효화 feature-frontend-cache-tier-cross-tab-invalidation-contract WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-029
FE-OC-029 대용량 객체 전송 feature-frontend-large-object-transfer-contract WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-030
FE-OC-030 멀티프로토콜 API transport feature-frontend-multi-protocol-api-transport-contract WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-031
FE-OC-031 실시간 구독 수명주기 feature-frontend-realtime-subscription-lifecycle-contract WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-032
FE-OC-032 백그라운드 실행 feature-frontend-background-execution-worker-contract WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-033

요청 묶음과의 대응:

요청 묶음 흡수한 계약
1 (File·Blob·picker·download·IndexedDB·OPFS·Cache Storage) FE-OC-027
2 (TanStack 메모리·Local/Session·IndexedDB·탭 간 무효화) FE-OC-028 (+ 기존 FE-OC-012·FE-OC-013 확장)
3 (presigned·multipart/resumable·streaming download·Image CDN) FE-OC-029
4 (REST·GraphQL·gRPC-Web·Schema·Mapper·Server State Cache) FE-OC-030 (+ 기존 FE-OC-006·FE-OC-007·FE-OC-012)
5 (SSE·WebSocket·WebPush·제한된 Polling) FE-OC-031 (+ WebPush 의 SW 호스트는 FE-OC-032)
6 (gRPC-Web·Connect-Web·Protobuf·REST Gateway) FE-OC-030
7 (Fetch·Runtime Config·Router·Query/Mutation) 기존 FE-OC-004·005·006·012 — 신규 계약 없음
8 (Connection·Reconnect·Resume·Event Validation·Subscription Cleanup) FE-OC-031
9 (Web Worker·Service Worker·Background Sync) FE-OC-032

4.2 §2.1 Stable Contract Index 신규 행

hub §2.1 표에 그대로 추가한다.

Contract ID Single owner Normative summary Minimum evidence Status
FE-OC-027 feature-frontend-binary-file-io-store-contract 파일 선택·다운로드·로컬 바이너리 저장은 등록된 port 를 MUST 경유하고, 원시 File/Blob handle 과 object URL 수명은 adapter 경계를 MUST NOT 벗어남 binary I-O fixtures planned
FE-OC-028 feature-frontend-cache-tier-cross-tab-invalidation-contract 캐시 계층과 탭 간 무효화는 QueryCachePort 정책과 registry 를 MUST 경유하고, release·config·API version 이 불일치하는 영속 캐시를 MUST NOT 재사용 cache tier + cross-tab tests planned
FE-OC-029 feature-frontend-large-object-transfer-contract 대용량 전송은 presigned 획득과 byte 전송의 credential 경계를 MUST 분리하고, 재개 가능 전송의 part 상태·무결성·취소를 MUST 소유 transfer fixtures planned
FE-OC-030 feature-frontend-multi-protocol-api-transport-contract 모든 protocol adapter 는 동일한 application output port 를 구현하고 protocol 별 성공/실패를 정규화된 failure 로 MUST 매핑하며, transport status 만으로 성공을 판정하면 안 됨 protocol mapping tests planned
FE-OC-031 feature-frontend-realtime-subscription-lifecycle-contract 실시간 구독은 연결·재연결·재개·이벤트 검증·해제를 MUST 계약하고, 스키마 미검증 이벤트를 application 으로 MUST NOT 전달하며 unmount 후 열린 구독을 MUST NOT 남김 realtime lifecycle tests planned
FE-OC-032 feature-frontend-background-execution-worker-contract 백그라운드 실행은 명시 owner·update UX·idempotency 조건을 MUST 갖추고, precaching 으로 release coherence 를 MUST NOT 훼손 background execution tests planned

4.3 §2.1.1 Contract Registry (typed) 신규 행

Contract ID Concern Key Revision Type Owner Trigger Required Effect Enforcement Status
FE-OC-027 fe.binary-file-io-store 1 operational-contract feature-frontend-binary-file-io-store-contract 파일을 고르거나 내려받거나 바이너리를 로컬에 쓸 때 파일 선택·다운로드·로컬 바이너리 저장은 등록된 port 를 MUST 경유하고, 원시 File/Blob handle 과 object URL 수명은 adapter 경계를 MUST NOT 벗어남 binary I-O fixtures active
FE-OC-028 fe.cache-tier-cross-tab 1 operational-contract feature-frontend-cache-tier-cross-tab-invalidation-contract 캐시를 영속화하거나 다른 탭에 무효화를 전파할 때 캐시 계층과 탭 간 무효화는 QueryCachePort 정책과 registry 를 MUST 경유하고, release·config·API version 이 불일치하는 영속 캐시를 MUST NOT 재사용 cache tier + cross-tab tests active
FE-OC-029 fe.large-object-transfer 1 operational-contract feature-frontend-large-object-transfer-contract 대용량 객체를 올리거나 스트리밍으로 내려받을 때 대용량 전송은 presigned 획득과 byte 전송의 credential 경계를 MUST 분리하고, 재개 가능 전송의 part 상태·무결성·취소를 MUST 소유 transfer fixtures active
FE-OC-030 fe.multi-protocol-transport 1 operational-contract feature-frontend-multi-protocol-api-transport-contract REST 이외 protocol 로 operation 을 호출할 때 모든 protocol adapter 는 동일한 application output port 를 구현하고 protocol 별 성공/실패를 정규화된 failure 로 MUST 매핑하며, transport status 만으로 성공을 판정하면 안 됨 protocol mapping tests active
FE-OC-031 fe.realtime-subscription-lifecycle 1 operational-contract feature-frontend-realtime-subscription-lifecycle-contract 스트림을 구독하거나 해제할 때 실시간 구독은 연결·재연결·재개·이벤트 검증·해제를 MUST 계약하고, 스키마 미검증 이벤트를 application 으로 MUST NOT 전달하며 unmount 후 열린 구독을 MUST NOT 남김 realtime lifecycle tests active
FE-OC-032 fe.background-execution 1 operational-contract feature-frontend-background-execution-worker-contract worker·service worker·background sync 를 등록하거나 갱신할 때 백그라운드 실행은 명시 owner·update UX·idempotency 조건을 MUST 갖추고, precaching 으로 release coherence 를 MUST NOT 훼손 background execution tests active

gate 행 7개는 §7.1 에 있다.


5. Port 설계

5.1 신규 port 12개

FE-D010(port 는 application 소유, adapter 가 구현)과 FE-D011(bootstrap 단일 composition root)을 그대로 따른다. hub §4.4 Port ownership matrix 에 추가한다.

Port Definition owner Planned implementation Consumer Input / output Failure vocabulary
CapabilityPort application adapters/capability bootstrap + 모든 capability 소비 use case capability ID → 활성 여부 + 사유 CAPABILITY_DISABLED, CAPABILITY_UNSUPPORTED
FileDialogPort application adapters/file 파일 입출력 use case 선택 제약(accept·multiple·max) → 파일 descriptor 목록 / 저장 요청 → 저장 결과 FILE_PICKER_DISMISSED, FILE_REJECTED
BlobStorePort application adapters/blob-store 로컬 바이너리 보관 use case 등록 key + 바이너리 descriptor → 저장/조회/삭제 결과 BLOB_STORE_UNAVAILABLE, BLOB_STORE_QUOTA_EXCEEDED
CachePersistencePort application adapters/cache-persistence QueryCachePort 구현 보조 캐시 스냅샷 + version tuple → 영속/복원 결과 CACHE_PERSISTENCE_FAILURE
CrossTabSyncPort application adapters/cross-tab 캐시 무효화 orchestration 무효화 key 메시지 → 발행/수신 구독 CROSS_TAB_CHANNEL_UNAVAILABLE
UploadTransferPort application adapters/transfer/upload 업로드 use case 전송 계획(source descriptor + presign 결과) → 진행 스트림 + 완료 결과 PRESIGN_EXPIRED, UPLOAD_PART_FAILED, TRANSFER_INTEGRITY_MISMATCH
StreamingDownloadPort application adapters/transfer/download 다운로드 use case operation + range/resume 위치 → 진행 스트림 + 완료 결과 STREAM_INTERRUPTED
RealtimeSubscriptionPort application adapters/realtime/{sse,websocket,polling} 스트림 소비 use case 구독 descriptor + resume cursor → 검증된 이벤트 스트림 + 해제 handle REALTIME_CONNECT_FAILED, REALTIME_DISCONNECTED, REALTIME_RESUME_GAP, EVENT_SCHEMA_MISMATCH
PushSubscriptionPort application adapters/realtime/push 알림 등록 use case 권한 요청 + 공개키 → 구독 descriptor PUSH_PERMISSION_DENIED, PUSH_SUBSCRIPTION_EXPIRED
WorkerTaskPort application adapters/worker CPU 오프로드 use case task 이름 + 직렬화 가능 입력 + timeout → 결과 또는 종료 WORKER_UNAVAILABLE, WORKER_TASK_TIMEOUT
ServiceWorkerHostPort application adapters/service-worker bootstrap + release 감시 등록 요청 → 등록/갱신 상태 스트림 SW_REGISTRATION_FAILED
BackgroundSyncPort application adapters/service-worker/sync 지연 mutation use case keyed mutation descriptor → 큐 등록 결과 BACKGROUND_SYNC_UNSUPPORTED, BACKGROUND_SYNC_REPLAY_REJECTED

5.2 의도적으로 port 를 만들지 않는 두 가지

이 두 결정은 설계의 핵심이며 hub §4.4 하단에 설명 문단으로 넣는다.

멀티프로토콜(FE-OC-030)은 신규 port 가 0개다. GraphQL·gRPC-Web·Connect-Web 은 기존 ResourceQueryPort/ResourceCommandPort 의 다른 구현체다. 프로토콜이 application 에 새 인터페이스로 새면 FE-D010(dependency inversion)이 무너지고, backend 가 REST 에서 gRPC 로 옮겨갈 때 use case 를 다시 써야 한다. 프로토콜 선택은 FE-REG-API.protocol 필드 = 데이터이지 타입이 아니다.

Image CDN 은 adapter 가 아니라 application 의 순수 정책이다. URL 파생에는 I-O 가 없다. MediaUrlPolicyapplication/policies/ 에 두고 CDN base·허용 transform 은 FE-REG-ENV 행에서 읽는다. port 로 만들면 테스트에 불필요한 test double 만 늘어난다.

5.3 §4.2 Component responsibility 신규 행

Component Owns Consumes MUST NOT own Evidence status
adapters/capability capability flag 해석, 브라우저 feature detection, 비활성 사유 application port, runtime config, browser globals 활성화 여부의 제품 판단 planned
adapters/file 파일 선택·저장 dialog, object URL 생성/해제 application port, File System Access / input element 파일 내용 해석, 도메인 검증 planned
adapters/blob-store IndexedDB·OPFS·Cache Storage 백엔드, quota 매핑, eviction application port, browser storage API 저장 대상의 의미, 도메인 정책 planned
adapters/cache-persistence 캐시 직렬화, version partition, 복원 거부 application port, adapters/blob-store 계약이 아닌 자체 백엔드 캐시 정책 결정(= QueryCachePort 소유) planned
adapters/cross-tab BroadcastChannel·storage event 전송, 메시지 봉투 application port, browser globals 무효화 대상 결정 planned
adapters/transfer part 분할·병렬·재시도·무결성·진행 보고, credential-less 전송 application port, fetch, Streams presign 발급, 업로드 대상 도메인 규칙 planned
adapters/protocol GraphQL·gRPC-Web·Connect-Web codec 과 status 정규화 application output port, fetch operation 정의, use-case policy planned
adapters/realtime 연결 수명주기, 재연결 backoff, resume cursor, 프레임 디코드, 구독 해제 application port, EventSource·WebSocket·fetch 이벤트의 도메인 의미, 상태 병합 정책 planned
adapters/worker worker 생성·통신·timeout·terminate application port, Worker API 도메인 계산 규칙 planned
adapters/service-worker SW 등록·갱신 상태, background sync 큐 등록 application port, ServiceWorker API precache 정책 결정(FE-D034 소유), mutation 의미 planned

5.4 §4.3 Dependency matrix 보강

기존 adapters/* 행의 "다른 adapter 의 concrete implementation import 금지"를 유지하되 두 예외를 명시한다.

  • adapters/transferUploadTransferPort 입력으로 바이너리 descriptor 를 받는다. adapters/file·adapters/blob-store 의 concrete 모듈을 import 하지 않는다. descriptor 조립은 bootstrap 또는 application orchestration 이 한다.
  • adapters/realtime/pushServiceWorkerHostPort 인터페이스를 통해 SW 등록 상태를 읽는다. adapters/service-worker 의 concrete 모듈을 import 하지 않는다. 이 관계는 DELEG-FE-007 로 등록한다.

worker/SW 엔트리 파일 규칙을 추가한다.

  • src/workers/*.worker.jspublic/sw.js별도 실행 컨텍스트이므로 presentation·application·domain 을 import 하지 않는다. 공유가 필요하면 domain 의 순수 모듈만 복제 없이 참조하고, 그 사실을 FE-REG-CAPABILITY 행에 기록한다.
  • worker 엔트리는 adapters/worker 가 소유한다. bootstrap 이 직접 new Worker() 를 부르지 않는다.

5.5 §4.5 Boot order 변경

기존 10단계 사이에 capability 해석을 넣는다. 삽입 위치는 registry snapshot load 직후, adapter 생성 직전이다.

1. build identity 읽기
2. runtime config fetch
3. config envelope·schema·compatibility 검증
4. release manifest 정합성 확인
5. registry snapshot load
6. capability 해석 — flag × 브라우저 feature detection → 활성 capability 집합 확정   ← 신규
7. auth integration adapter 주입
8. HTTP/storage/telemetry/query-cache adapter 생성
9. 활성 capability 의 adapter 생성 (비활성 capability 의 adapter 는 생성하지 않음)   ← 신규
10. application facade 생성
11. router 생성
12. React root mount

규범:

  • 6단계는 MUST 실패하지 않는다. flag ON + 브라우저 미지원이면 해당 capability 를 비활성으로 확정하고 capability.activation.rejected telemetry 를 남긴 뒤 boot 를 계속한다. capability 부재가 boot 를 막으면 skeleton 이 특정 브라우저에 묶인다.
  • 9단계는 비활성 capability 의 adapter 모듈을 동적 import 하지 않는다. 정적 import 하면 FE-NFR-020(비활성 시 initial JS 증가 0)이 깨진다.

5.6 §4.6 Directory blueprint 확장

src/
  adapters/
    capability/
    file/
    blob-store/
    cache-persistence/
    cross-tab/
    transfer/
      upload/
      download/
    protocol/
      graphql/
      grpc-web/
      connect-web/
    realtime/
      sse/
      websocket/
      polling/
      push/
    worker/
    service-worker/
      sync/
  application/
    policies/            # MediaUrlPolicy 등 순수 정책
  contracts/
    capabilities.js      # FE-REG-CAPABILITY
  workers/               # *.worker.js 엔트리
public/
  sw.js                  # capability 활성 시에만 배포 artifact 에 포함

6. Registry 설계

6.1 FE-REG-CAPABILITY — 9번째 registry (신설)

FE-REG-CAPABILITY 의 owner 는 feature-frontend-env-runtime-config-contract 다. capability flag 는 runtime config 키이므로 env registry owner 가 자연 owner 이고, 새 branch 를 추가로 만들지 않는다.

Planned path: src/contracts/capabilities.js Ad hoc use failure: registry 없이 import.meta.env 나 config 객체를 직접 읽어 기능을 분기

hub 에서의 위치는 §5.11 로 뒤에 붙인다. §5.5 뒤에 끼워 넣으면 §5.6~§5.10 이 밀려 문서 전체와 branch-note 의 절 참조가 어긋난다. 절 번호 순서보다 기존 참조 안정성이 우선이다.

Field Required Rule
capabilityId yes stable UPPER_SNAKE_CASE; rename 은 breaking
envFlagKey yes FE-REG-ENV포인터. 키의 타입·기본값·검증은 env registry 가 계속 소유하고 여기 재진술하지 않음
owner yes 소유 branch slug
requiredGate yes 활성화 시 반드시 PASS 해야 하는 FE-GATE-*
browserRequirement yes feature detection 식별자. 미지원 시 활성화되지 않음
disabledFallback yes 비활성 시 동작 — feature-hidden, degraded-alternative, error-surface 중 하나
runbookRef conditional 운영 실패 절차가 있는 capability 는 FE-RB-* 참조 필수

Initial planned rows:

capabilityId envFlagKey owner requiredGate browserRequirement disabledFallback runbookRef
CAP_FE_BINARY_IO CAPABILITY_BINARY_IO_ENABLED feature-frontend-binary-file-io-store-contract FE-GATE-027 indexedDB (OPFS·Cache Storage 는 하위 detection) feature-hidden
CAP_FE_CACHE_PERSISTENCE CAPABILITY_CACHE_PERSISTENCE_ENABLED feature-frontend-cache-tier-cross-tab-invalidation-contract FE-GATE-028 indexedDB degraded-alternative (메모리 캐시만)
CAP_FE_LARGE_TRANSFER CAPABILITY_LARGE_TRANSFER_ENABLED feature-frontend-large-object-transfer-contract FE-GATE-029 ReadableStream, AbortController feature-hidden
CAP_FE_ALT_PROTOCOL CAPABILITY_ALT_PROTOCOL_ENABLED feature-frontend-multi-protocol-api-transport-contract FE-GATE-030 fetch streaming (gRPC-Web 시) degraded-alternative (REST gateway)
CAP_FE_REALTIME CAPABILITY_REALTIME_ENABLED feature-frontend-realtime-subscription-lifecycle-contract FE-GATE-031 EventSource 또는 WebSocket degraded-alternative (bounded polling) FE-RB-006
CAP_FE_BACKGROUND_EXEC CAPABILITY_BACKGROUND_EXEC_ENABLED feature-frontend-background-execution-worker-contract FE-GATE-032 Worker; SW 하위 기능은 serviceWorker feature-hidden FE-RB-007

6.2 기존 8개 registry 확장 (전부 additive)

FE-REG-API — §5.3 schema 확장

Field Required Rule
protocol yes rest(기본) | graphql | grpc-web | connect-web | sse | websocket | poll. rest 외 값은 대응 capability 활성 필요
transferMode yes unary(기본) | stream | upload | download
operationRef conditional graphql 은 persisted-document ID, grpc-web/connect-webpackage.Service/Method. restnone
eventSchema conditional transferMode: stream 이면 이벤트 union schema reference 필수
resumeStrategy conditional stream/downloadnone | last-event-id | cursor | range 중 하나

기존 필드는 그대로 유지된다. timeoutMstransferMode: stream 행에서 연결 수립 timeout 을 뜻하고 스트림 총 수명에는 적용하지 않는다 — 이 해석 차이를 §5.3 본문에 명시한다.

Initial planned rows(sample fixture 용, feature-sample-feature-slice-contract-fixture owner):

operationId method path protocol transferMode idempotency 비고
STREAM_SAMPLE_EVENTS GET /api/sample/events sse stream safe resumeStrategy: last-event-id
PRESIGN_SAMPLE_UPLOAD POST /api/sample/uploads/presign rest unary keyed presign 획득만; byte 전송 아님
DOWNLOAD_SAMPLE_OBJECT GET /api/sample/objects/:id/content rest download safe resumeStrategy: range

FE-REG-STORAGE — §5.5 schema 확장

  • backend enum 에 opfs, cacheStorage 추가
  • +payloadClassstructured(기본) | binary. binarysensitive-forbidden classification 과 조합할 수 없다
  • +evictionOrder — quota 압박 시 제거 순서(정수). 낮을수록 먼저 제거. FE-D027 의 "correctness 값은 임의 fallback 금지"와 연동해 correctness 값은 null(제거 불가)로 표기

Initial planned rows 추가:

logicalName backend classification payloadClass TTL / fallback evictionOrder
UPLOAD_PART_STATE indexedDB opaque-cache structured 전송 완료 또는 24h / fallback 없음 null
TRANSFER_OBJECT_BUFFER opfs opaque-cache binary 전송 완료 시 삭제 / no-persist 1
QUERY_CACHE_SNAPSHOT indexedDB opaque-cache structured release·config·API version 파티션 / memory-only 2
SW_RESPONSE_CACHE cacheStorage opaque-cache binary release 단위 파티션 / feature-disable 3

FE-REG-ERROR — §5.6 kind enum 26종 추가

CAPABILITY_DISABLED
CAPABILITY_UNSUPPORTED
FILE_PICKER_DISMISSED
FILE_REJECTED
BLOB_STORE_UNAVAILABLE
BLOB_STORE_QUOTA_EXCEEDED
CACHE_PERSISTENCE_FAILURE
CROSS_TAB_CHANNEL_UNAVAILABLE
PRESIGN_EXPIRED
UPLOAD_PART_FAILED
TRANSFER_INTEGRITY_MISMATCH
STREAM_INTERRUPTED
PROTOCOL_STATUS_MISMATCH
CODEC_DECODE_FAILURE
PARTIAL_RESULT_FAILURE
REALTIME_CONNECT_FAILED
REALTIME_DISCONNECTED
REALTIME_RESUME_GAP
EVENT_SCHEMA_MISMATCH
PUSH_PERMISSION_DENIED
PUSH_SUBSCRIPTION_EXPIRED
WORKER_UNAVAILABLE
WORKER_TASK_TIMEOUT
SW_REGISTRATION_FAILED
BACKGROUND_SYNC_UNSUPPORTED
BACKGROUND_SYNC_REPLAY_REJECTED

의도적으로 제외한 것:

  • TRANSFER_ABORTED — 기존 REQUEST_ABORTED 를 재사용한다.
  • SUBSCRIPTION_LEAKED — 사용자에게 보이는 실패가 아니라 gate 가 잡는 결함이다. FE-GATE-031 fixture 이름으로만 쓴다.
  • SW_UPDATE_PENDING — 실패가 아니라 §9.7 SW 갱신 surface state 다.

FILE_PICKER_DISMISSED 는 사용자 취소이므로 severity: info, action: none 이고 error surface 를 띄우지 않는다. 이를 §8.2 failure matrix 행에 명시한다.

FE-REG-QUERY — §5.7 규칙 확장

Rule Normative behavior
persistenceTier memory(기본) | session | local | indexedDB. memory 외 값은 CAP_FE_CACHE_PERSISTENCE 활성 필요
crossTabScope none(기본) | same-origin. same-origin 은 무효화 key 만 전파하고 값은 전파하지 않음(FE-D028)
version partition 영속 tier 는 releaseId·configSchemaVersion·apiContractVersion 을 파티션 키에 포함. 불일치 시 복원하지 않고 폐기

FE-REG-ENV — §5.4 신규 키

Key Phase Classification Required Default Failure
CAPABILITY_BINARY_IO_ENABLED runtime public no false invalid value boot fail
CAPABILITY_CACHE_PERSISTENCE_ENABLED runtime public no false invalid value boot fail
CAPABILITY_LARGE_TRANSFER_ENABLED runtime public no false invalid value boot fail
CAPABILITY_ALT_PROTOCOL_ENABLED runtime public no false invalid value boot fail
CAPABILITY_REALTIME_ENABLED runtime public no false invalid value boot fail
CAPABILITY_BACKGROUND_EXEC_ENABLED runtime public no false invalid value boot fail
ALT_PROTOCOL_BASE_URL runtime public-sensitive conditional none capability 활성 시 boot fail
REALTIME_ENDPOINT_URL runtime public-sensitive conditional none capability 활성 시 boot fail
MEDIA_CDN_BASE_URL runtime public-sensitive conditional none 미설정 시 원본 URL 사용
MEDIA_CDN_ALLOWED_TRANSFORMS runtime public conditional [] 허용 외 transform 요청은 무시
PUSH_PUBLIC_KEY runtime public conditional none push 활성 시 boot fail
TRANSFER_PART_SIZE_BYTES runtime public no 8388608 (8 MiB) invalid value boot fail
TRANSFER_MAX_PARALLEL_PARTS runtime public no 3 invalid value boot fail
REALTIME_RECONNECT_CAP_MS runtime public no 30000 invalid value boot fail
WORKER_TASK_TIMEOUT_MS runtime public no 30000 invalid value boot fail

PUSH_PUBLIC_KEY 는 VAPID 공개키이므로 public 이다. 대응 개인키는 backend 소유이며 frontend registry 에 등록할 수 없다.

FE-REG-TELEMETRY — §5.8 신규 이벤트

Event Trigger Required attributes
capability.activation.rejected flag ON 인데 브라우저 미지원으로 비활성 확정 capability_id, reason, build_id
transfer.part.failed upload part 재시도 소진 operation_id, part_index_bucket, error_kind
transfer.completed 전송 종료(성공/실패 공통) operation_id, outcome, size_bucket, duration_bucket
realtime.connection.state_changed 연결 상태 전이 operation_id, from_state, to_state, attempt_count_bucket
realtime.event.rejected 인바운드 프레임 스키마 거부 operation_id, error_kind
sw.update.applied SW 신 버전 활성화 build_id, previous_build_id
background.sync.replayed background sync 재생 결과 operation_id, outcome

forbiddenAttributes 는 기존 규칙 그대로다. 특히 파일명·object key·presigned URL·구독 endpoint 는 전송 금지이며 이를 §5.8 본문에 추가 명시한다.

FE-REG-RELEASE — §5.9 신규 토큰

Token Source Compatibility role
serviceWorkerVersion build output SW 스크립트와 release 의 coherence. rollback 시 SW 도 되돌아갔는지 판정

6.3 registry 개수 변경 파급

FE-D018DEC-…-REGISTRY-001 의 Summary 가 "8개 registry" 를 열거하므로 다음을 함께 고친다.

  • §5.1 Registry owner map 에 FE-REG-CAPABILITY 행 추가 (8행 → 9행)
  • FE-OC-022 의 normative summary "8개 registry" → "9개 registry" (§2.1 과 §2.1.1 양쪽)
  • §18.2 FE-RDY-009 blocking question "8 registry" → "9 registry"
  • DEC-…-REGISTRY-001 Summary 갱신 — 상세는 §7.2 참조

7. 결정 레지스트리

7.1 신규 결정 11건

hub 는 §3.2(FE-D*, legacy)와 §6.1(DEC-…, 현행 SSOT)을 쌍으로 유지한다. 신규 결정도 같은 패턴으로 양쪽에 넣는다.

§3.2 신규 행:

Decision ID Decision Status Owner Affected FE-OC Evidence / rationale Revisit trigger Supersedes
FE-D026 신규 runtime capability 6종은 FE-REG-CAPABILITY flag 로 default OFF이며 활성화는 owner·gate·runbook 을 동반한다 conditional-default feature-frontend-env-runtime-config-contract FE-OC-004, FE-OC-022, FE-OC-027~FE-OC-032 project-local default, 외부 source claim 아님 특정 capability 가 제품 필수가 되어 상시 활성이 요구됨
FE-D027 로컬 바이너리 backend 는 IndexedDB 를 default 로 하고 OPFS 는 대용량 순차 write 에 opt-in, Cache Storage 는 service worker 호스팅 response cache 전용이다 conditional-default feature-frontend-binary-file-io-store-contract FE-OC-013, FE-OC-027 project-local default, 외부 source claim 아님 OPFS 브라우저 지원 또는 quota 정책이 바뀜
FE-D028 탭 간 무효화는 BroadcastChannel 우선에 storage event fallback 을 쓰고 leader election 없이 무효화 key 만 전파한다 conditional-default feature-frontend-cache-tier-cross-tab-invalidation-contract FE-OC-012, FE-OC-028 project-local default, 값 전파 시 PII·stale 표면 확대 다중 탭 실시간 협업이 제품 요구가 됨
FE-D029 presigned URL 획득은 shared client 를 경유하고 실제 byte 전송은 session credential 을 첨부하지 않는 transfer adapter 가 수행한다 accepted-documented-only feature-frontend-large-object-transfer-contract FE-OC-006, FE-OC-019, FE-OC-029 credential 유출 방지 invariant, project decision 스토리지가 same-origin proxy 만 제공
FE-D030 재개 가능 전송은 part size·병렬도·part 재시도 상한을 registry 로 고정하고 part 상태를 BlobStorePort 에 보존한다 conditional-default feature-frontend-large-object-transfer-contract FE-OC-029 project-local default, 외부 source claim 아님 스토리지 제공자가 다른 multipart 제약을 요구
FE-D031 transport default 는 REST 이고 GraphQL·gRPC-Web·Connect-Web 은 FE-REG-API 의 protocol 필드로 opt-in 하며 미지원 환경은 REST gateway 로 fallback 한다 conditional-default feature-frontend-multi-protocol-api-transport-contract FE-OC-006, FE-OC-007, FE-OC-030 project-local default, 외부 source claim 아님 backend 가 단일 비-REST protocol 만 제공
FE-D032 실시간 transport 는 SSE 를 우선하고 양방향이 필요하면 WebSocket, 둘 다 불가할 때만 최소 간격·backoff·visibility gating 을 갖춘 bounded polling 을 쓴다 conditional-default feature-frontend-realtime-subscription-lifecycle-contract FE-OC-031 project-local default, polling 은 마지막 수단 backend 가 SSE 를 제공하지 않거나 양방향이 기본 요구가 됨
FE-D033 실시간 연결은 full jitter backoff 와 30초 cap 을 쓰고 재시도 상한 후 terminal 상태로 전이하며 resume 은 Last-Event-ID 또는 cursor 로 수행하고 unmount 시 구독을 해제한다 conditional-default feature-frontend-realtime-subscription-lifecycle-contract FE-OC-031, FE-OC-011 재연결 폭주·구독 누수 억제, project decision backend 가 서버 주도 재연결 정책을 계약으로 제공
FE-D034 service worker 는 역할을 분리해 release asset precaching 은 default off 로 유지하고 push·background sync·Cache Storage 호스트 역할만 capability opt-in 으로 허용하며 update UX 계약을 요구한다 conditional-default feature-frontend-background-execution-worker-contract FE-OC-016, FE-OC-017, FE-OC-023, FE-OC-032 precaching 은 release coherence 훼손 원인이나 push·sync 는 SW 없이는 불가 offline-first 가 제품 요구가 되고 update UX 가 설계됨 FE-D019
FE-D035 background sync 재생은 idempotency: keyed operation 만 허용한다 accepted-documented-only feature-frontend-background-execution-worker-contract FE-OC-009, FE-OC-032 FE-D016 의 중복 write 방지 invariant 를 지연 재생에 확장 mutation 이 naturally idempotent 임이 schema 로 증명됨
FE-D036 Web Worker 작업은 structured-clone 또는 Transferable 로만 통신하고 timeout 과 terminate 를 계약하며 worker 안에서 application port 를 재구현하지 않는다 accepted-documented-only feature-frontend-background-execution-worker-contract FE-OC-002, FE-OC-032 worker 안 로직 중복이 layer 경계를 우회하는 것을 차단, project decision SharedArrayBuffer 기반 병렬 처리가 요구됨

Evidence / rationale 열의 "project-local default, 외부 source claim 아님" 표기는 FE-D001 이 쓰는 문구와 같다. 근거 raw 문서 부재를 감추지 않고 명시하는 장치다.

7.2 §6.1 Project Decision Registry 신규 행

Summary 셀은 소비 branch 의 상속 표와 문자열이 정확히 일치해야 한다(hub §6.1 하단 규칙). 아래 문자열이 SSOT 다.

조사(particle) 앞 공백 없음. 기존 §6.1 행이 …release token을 8개 registry로 관리한다 형태이므로 신규 행도 같은 표기를 쓴다. 이 표를 branch-note 상속 표에 옮길 때 공백을 하나라도 넣으면 문자열 불일치가 된다.

Decision ID Revision Domain Decision Summary Status Evidence
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-CAPABILITY-001 1 capability 신규 runtime capability 6종은 FE-REG-CAPABILITY flag로 default OFF이며 활성화는 owner·gate·runbook을 동반한다 conditional-default §3.2 FE-D026
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-BINARY-STORE-001 1 binary-store 로컬 바이너리 backend는 IndexedDB를 default로 하고 OPFS는 대용량 순차 write에 opt-in, Cache Storage는 service worker 호스팅 response cache 전용이다 conditional-default §3.2 FE-D027
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-CROSS-TAB-001 1 cross-tab 탭 간 무효화는 BroadcastChannel 우선에 storage event fallback을 쓰고 leader election 없이 무효화 key만 전파한다 conditional-default §3.2 FE-D028
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-TRANSFER-CREDENTIAL-001 1 transfer-credential presigned URL 획득은 shared client를 경유하고 실제 byte 전송은 session credential을 첨부하지 않는 transfer adapter가 수행한다 accepted-documented-only §3.2 FE-D029
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-RESUMABLE-TRANSFER-001 1 resumable-transfer 재개 가능 전송은 part size·병렬도·part 재시도 상한을 registry로 고정하고 part 상태를 BlobStorePort에 보존한다 conditional-default §3.2 FE-D030
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-PROTOCOL-001 1 protocol transport default는 REST이고 GraphQL·gRPC-Web·Connect-Web은 FE-REG-API의 protocol 필드로 opt-in하며 미지원 환경은 REST gateway로 fallback한다 conditional-default §3.2 FE-D031
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-REALTIME-TRANSPORT-001 1 realtime-transport 실시간 transport는 SSE를 우선하고 양방향이 필요하면 WebSocket, 둘 다 불가할 때만 최소 간격·backoff·visibility gating을 갖춘 bounded polling을 쓴다 conditional-default §3.2 FE-D032
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-REALTIME-LIFECYCLE-001 1 realtime-lifecycle 실시간 연결은 full jitter backoff와 30초 cap을 쓰고 재시도 상한 후 terminal 상태로 전이하며 resume은 Last-Event-ID 또는 cursor로 수행하고 unmount 시 구독을 해제한다 conditional-default §3.2 FE-D033
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-SERVICE-WORKER-ROLE-001 1 service-worker-role service worker는 역할을 분리해 release asset precaching은 default off로 유지하고 push·background sync·Cache Storage 호스트 역할만 capability opt-in으로 허용하며 update UX 계약을 요구한다 conditional-default §3.2 FE-D034
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-BACKGROUND-SYNC-001 1 background-sync background sync 재생은 idempotency keyed operation만 허용한다 accepted-documented-only §3.2 FE-D035
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-WORKER-TASK-001 1 worker-task Web Worker 작업은 structured-clone 또는 Transferable로만 통신하고 timeout과 terminate를 계약하며 worker 안에서 application port를 재구현하지 않는다 accepted-documented-only §3.2 FE-D036

Owner 열은 모두 [[raw/project-notes/ca-skeleton-frontend-operational-contract]] 다(§6.1 의 기존 모든 행과 동일).

§3.2 의 Decision 셀은 문자열 일치 제약을 받지 않으므로 §7.1 의 서술형 문장을 그대로 써도 된다. 제약을 받는 것은 §6.1 Summary 셀과 branch-note 상속 표 두 곳뿐이다.

7.3 기존 결정 개정 2건

§3.3 변경 프로토콜을 따르고 §6.1 하단 개정 기록에 남긴다.

(a) FE-D019 → superseded, DEC-…-OFFLINE-CACHE-001 → revision 2

  • 분류: 새 결정(FE-D034)이 기존 의미를 대체 → §3.3 5단계 supersede chain

  • compatibility_impact: behavior-change — "SW 전면 off" 가 "precaching off + 역할별 opt-in" 으로 바뀐다

  • §3.2 FE-D019Statussuperseded 로 바꾸고 행은 삭제하지 않는다

  • DEC-…-OFFLINE-CACHE-001 을 revision 2 로 올리고 Summary 를 다음으로 교체 (교체 전 문자열은 service worker와 offline asset cache는 default off다):

    service worker의 release asset precaching은 default off이고 push·background sync·Cache Storage 호스트 역할만 capability opt-in으로 허용한다

  • 파급 pin: feature-frontend-release-cache-rollback-contract 의 frontmatter inherits: 에서 DEC-…-OFFLINE-CACHE-001@1@2, 그리고 그 branch 의 상속 표 Summary 문자열도 위 문자열로 교체

  • §8.0 WI-…-024Applies Decisions 에서도 @1@2

  • behavior-change 이므로 §3.3 4단계: migration·rollback·test evidence 없이 merge 금지. 여기서는 FE-GATE-032(SW update UX + rollback 시 SW 되돌림)와 FE-RB-007 이 그 evidence 요구를 담당한다

(b) DEC-…-REGISTRY-001 — revision 1 유지, Summary 갱신

  • 분류: 9번째 registry 추가 → 기존 8개의 동작은 바뀌지 않음

  • compatibility_impact: additive. §6.1 의 DEC-…-SUPPLY-CHAIN-001 선례대로 revision 을 유지(1) 한다

  • Summary 를 다음으로 교체 (교체 전 문자열은 route, API operation, env, storage, error, query, telemetry, release token을 8개 registry로 관리한다):

    route, API operation, env, storage, error, query, telemetry, release token, capability를 9개 registry로 관리한다

  • FE-D018 의 Decision 셀도 같은 취지로 갱신

  • 파급 문자열: 이 결정을 상속 표에 복사해 둔 4개 branch — feature-frontend-storage-registry-contract, feature-frontend-observability-logging-trace-contract, feature-frontend-contract-registry-governance, feature-frontend-contract-compatibility-governance — 의 Summary 문자열을 함께 교체해야 CONFLICTS_WITH_PROJECT_DECISION 이 발생하지 않는다. inherits:@1 pin 은 revision 이 그대로이므로 수정 불필요

7.4 §2.1.2 Delegation Registry 신규 행

Delegation ID Concern Key Revision Delegator Delegate Scope Status
DELEG-FE-007 fe.deleg.sw-host-for-push 1 feature-frontend-realtime-subscription-lifecycle-contract feature-frontend-background-execution-worker-contract WebPush 가 요구하는 service worker 등록·수명주기 호스팅 proposed
DELEG-FE-008 fe.deleg.binary-handle-ownership 1 feature-frontend-large-object-transfer-contract feature-frontend-binary-file-io-store-contract 전송 대상 File/Blob handle 과 object URL 수명 소유 proposed
DELEG-FE-009 fe.deleg.persistent-cache-key 1 feature-frontend-cache-tier-cross-tab-invalidation-contract feature-frontend-storage-registry-contract 영속 캐시의 physical key·namespace·classification·quota fallback 소유 proposed
DELEG-FE-010 fe.deleg.decoded-payload-validation 1 feature-frontend-multi-protocol-api-transport-contract feature-runtime-schema-validation-contract codec 디코드 이후 payload 의 runtime schema 검증 proposed
DELEG-FE-011 fe.deleg.sw-release-coherence 1 feature-frontend-background-execution-worker-contract feature-frontend-release-cache-rollback-contract service worker 버전과 release·rollback coherence 판정 proposed

Statusproposed 로 시작하고 delegate branch 가 frontmatter accepts_delegations 로 접수하면 accepted 가 된다. 이번 스캐폴딩에서 5건 모두 accepted 까지 완료한다.

  • DELEG-FE-007(delegate = background-execution)·DELEG-FE-008(delegate = binary-file-io) — delegate 가 이번에 새로 만드는 branch 이므로 생성 시점에 accepts_delegations 를 채워 바로 접수한다.
  • DELEG-FE-009(storage-registry)·DELEG-FE-010(runtime-schema-validation)·DELEG-FE-011(release-cache-rollback) — delegate 가 기존 branch 이므로 해당 파일의 accepts_delegations 를 §12.3 에서 함께 수정한다.

접수하지 않고 proposed 로 남기면 "A 가 넘겼는데 B 는 받은 적 없는" 공백이 되고, 검사기가 없는 현재 환경에서는 그 공백이 자동으로 드러나지 않는다.

7.5 §2.1.4 Flow Stage Registry — inbound event 흐름 신설

기존 FLOW-FE-RESP-001~008 은 요청/응답 전용이라 스트림 프레임이 들어갈 자리가 없다. 같은 형식으로 인바운드 이벤트 흐름을 추가한다.

Stage ID Order Owner Input Action Output Invariants Revision
FLOW-FE-EVENT-001 1 feature-frontend-realtime-subscription-lifecycle-contract 열린 연결 프레임 수신 대기 raw frame 연결 오류는 이 단계가 소유하고 이후 단계로 예외를 넘기지 않는다 1
FLOW-FE-EVENT-002 2 feature-frontend-realtime-subscription-lifecycle-contract raw frame transport decode (SSE 필드 / WebSocket frame / poll 응답 본문) unvalidated event JSON decode 실패는 프레임을 버리고 실패로 전환하며 연결을 즉시 끊지 않는다 1
FLOW-FE-EVENT-003 3 feature-runtime-schema-validation-contract unvalidated event JSON event envelope 공유 스키마 검증 discriminated event envelope 경계 검증은 non-throwing 이며 throw 를 상위로 누출하지 않는다 1
FLOW-FE-EVENT-004 4 feature-runtime-schema-validation-contract discriminated event envelope eventSchema per-event 검증 검증된 event payload 미검증 프레임은 EVENT_SCHEMA_MISMATCH 로 드롭하고 application 에 도달시키지 않는다 1
FLOW-FE-EVENT-005 5 feature-frontend-error-classification-boundary-contract 검증된 event payload 또는 실패 신호 정규화된 이벤트 또는 failure 반환 application event 또는 normalized failure 총함수 — 미매핑 예외는 UNKNOWN_FAILURE 로 귀결한다 1

구독 해제(cleanup)는 이 흐름이 아니라 RealtimeSubscriptionPort 계약이 소유한다. 흐름은 프레임 하나의 여정만 기술한다.


8. Acceptance Gate

8.1 조건부 차단 개념 — NOT_APPLICABLE

capability 가 OFF 인 프로젝트에서 해당 gate 를 PASS 라고 하면 거짓말이고, FAIL 이라고 하면 영원히 배포할 수 없다. NOT_APPLICABLE 상태를 도입하되 남용을 막는 불변식을 건다.

hub §18.1 Formula 를 다음으로 교체한다.

PASS_STATES = {PASS, PASS_SCOPED}
NOT_APPLICABLE = capability-scoped gate 가, 대응 capability flag 가 OFF 이고
                 FE-GATE-033 이 그 adapter 의 번들 부재를 증명했을 때만 취할 수 있는 상태
READY iff every blocking row Current is in PASS_STATES or is a valid NOT_APPLICABLE
otherwise NOT_READY

규범:

  • NOT_APPLICABLEFE-GATE-027~FE-GATE-032 취할 수 있다. FE-GATE-033 자신은 취할 수 없다.
  • FE-GATE-033 이 PASS 가 아니면 모든 NOT_APPLICABLE 은 무효이며 FAIL_UNVERIFIED 로 강등된다.
  • "안 쓴다"는 주장은 선언이 아니라 번들에 그 adapter 가 없다는 증거로만 성립한다.

8.2 §2.1.1 gate 행 (typed)

Contract ID Concern Key Revision Type Owner Trigger Required Effect Enforcement Status
FE-GATE-027 fe.gate.binary-file-io 1 gate feature-frontend-binary-file-io-store-contract 파일 I-O 또는 로컬 바이너리 저장 코드를 변경할 때 picker·다운로드·quota·object URL 해제 fixture 가 실패하면 merge 를 MUST 차단 binary I-O report active
FE-GATE-028 fe.gate.cache-tier-cross-tab 1 gate feature-frontend-cache-tier-cross-tab-invalidation-contract 캐시 영속화나 탭 간 전파를 변경할 때 version 파티션·탭 간 무효화 fixture 가 실패하면 merge 를 MUST 차단 cache tier report active
FE-GATE-029 fe.gate.large-object-transfer 1 gate feature-frontend-large-object-transfer-contract 대용량 전송 경로를 변경할 때 presign 만료·part 재시도·무결성·credential 경계 fixture 가 실패하면 merge·release 를 MUST 차단 transfer report active
FE-GATE-030 fe.gate.multi-protocol-transport 1 gate feature-frontend-multi-protocol-api-transport-contract protocol adapter 나 codec 을 변경할 때 protocol 별 성공/실패 정규화 fixture 가 실패하면 merge 를 MUST 차단 protocol mapping report active
FE-GATE-031 fe.gate.realtime-lifecycle 1 gate feature-frontend-realtime-subscription-lifecycle-contract 실시간 연결·구독 코드를 변경할 때 backoff·resume·구독 해제·이벤트 검증 fixture 가 실패하면 merge·release 를 MUST 차단 realtime lifecycle report active
FE-GATE-032 fe.gate.background-execution 1 gate feature-frontend-background-execution-worker-contract worker·service worker·background sync 를 변경할 때 SW update UX·sync idempotency·worker timeout fixture 가 실패하면 merge·release 를 MUST 차단 background execution report active
FE-GATE-033 fe.gate.capability-default-off 1 gate feature-frontend-env-runtime-config-contract capability flag 나 adapter 등록을 변경할 때 기본 config build 에 비활성 capability 의 adapter 가 포함되면 merge·release 를 MUST 차단 capability bundle report active

8.3 §15.1 Gate ownership 행

Gate ID Gate Blocking scope Covered FE-OC Covered FE-NFR Required fixtures Pass condition Evidence artifact Current
FE-GATE-027 binary I-O & local store merge FE-OC-013, FE-OC-027 picker 취소·거부, quota 초과 fallback, OPFS 순차 write, Cache Storage 버전 파티션, object URL 해제 모든 fixture 가 기대 kind 로 처리되고 object URL 누수 0 binary I-O report FAIL_UNVERIFIED
FE-GATE-028 cache tier & cross-tab merge FE-OC-012, FE-OC-028 영속 캐시 version 파티션, 탭 A mutation → 탭 B 무효화, BroadcastChannel 부재 fallback 불일치 version 캐시는 복원되지 않고 탭 간 무효화가 도달 cache tier report FAIL_UNVERIFIED
FE-GATE-029 large object transfer merge + release FE-OC-019, FE-OC-029 FE-NFR-018 presign 만료, part 재시도 상한, stream 중단 후 재개, 무결성 불일치, credential 첨부 negative 모든 fixture 통과 + 전송 요청에 session credential 0건 transfer report FAIL_UNVERIFIED
FE-GATE-030 multi-protocol transport merge FE-OC-006, FE-OC-007, FE-OC-030 GraphQL 200 + errors[], gRPC status ↔ HTTP status, codec decode 실패, gateway fallback 모든 protocol 실패가 기대 kind 로 정규화 protocol mapping report FAIL_UNVERIFIED
FE-GATE-031 realtime lifecycle merge + release FE-OC-011, FE-OC-031 FE-NFR-016, FE-NFR-017 결정론 fake clock backoff, resume gap 감지, unmount 후 열린 연결, 이벤트 스키마 거부, FE-RB-006 drill backoff 가 cap 을 넘지 않고 unmount 후 열린 연결 0, 미검증 이벤트 0건 도달 realtime lifecycle report FAIL_UNVERIFIED
FE-GATE-032 background execution merge + release FE-OC-016, FE-OC-017, FE-OC-032 FE-NFR-019 SW 등록·갱신 UX, rollback 시 SW 되돌림, background sync keyed-only, worker timeout·terminate, FE-RB-007 drill 모든 fixture 통과 + keyed 아닌 mutation replay 0건 background execution report FAIL_UNVERIFIED
FE-GATE-033 capability default-off merge + release FE-OC-004, FE-OC-022, FE-OC-027~FE-OC-032 FE-NFR-020 기본 config 로 production build, 각 capability ON 조합 build 비활성 capability 의 adapter 모듈이 어떤 chunk 에도 없고 initial JS 증가 0 capability bundle report FAIL_UNVERIFIED

§15.1 서두의 "현재 stable gate registry는 26개 row" 를 33개 row 로 고친다.

8.4 §15.2 Negative fixture 신규 행

Gate Negative fixture example
binary I-O quota 초과인데 UPLOAD_PART_STATE 가 memory 로 fallback
cache tier release/config version 불일치 캐시를 복원해 사용
large object transfer transfer 요청에 session credential 헤더가 첨부
multi-protocol 200 OK + errors[] 를 success 로 반환
realtime lifecycle unmount 후에도 구독이 살아 있음 / 미검증 프레임이 application 도달
background execution idempotency: none mutation 이 background sync 로 replay
capability default-off flag OFF 인데 adapter 가 initial chunk 에 포함

8.5 §15.3 Promotion rule 갱신

MERGE_READY = FE-GATE-001, FE-GATE-002, FE-GATE-003, FE-GATE-004, FE-GATE-005, FE-GATE-006,
              FE-GATE-007, FE-GATE-008, FE-GATE-009, FE-GATE-010, FE-GATE-011, FE-GATE-013,
              FE-GATE-020, FE-GATE-033 PASS
              AND FE-GATE-027, FE-GATE-028, FE-GATE-030 각각 PASS 또는 유효한 NOT_APPLICABLE
RELEASE_READY = MERGE_READY AND FE-GATE-012, FE-GATE-014, FE-GATE-015, FE-GATE-019, FE-GATE-026 PASS
              AND FE-GATE-029, FE-GATE-031, FE-GATE-032 각각 PASS 또는 유효한 NOT_APPLICABLE
PROD_PROMOTION_READY = RELEASE_READY AND FE-GATE-016, FE-GATE-021, FE-GATE-022, FE-GATE-023,
              FE-GATE-024, FE-GATE-025 PASS
FIELD_SLO_READY = PROD_PROMOTION_READY AND FE-GATE-018 PASS
DOCUMENTATION_READY = FE-GATE-017 PASS_SCOPED AND evidence ledger updated
PROJECT_READY = all applicable blocking gates PASS

FE-GATE-033NOT_APPLICABLE 을 취할 수 없으므로 항상 MERGE_READY 에 무조건 포함된다.


9. NFR · Async surface · Runbook

9.1 §14.2 신규 NFR 5개

NFR ID Metric Context Initial target Current evidence
FE-NFR-016 realtime reconnect backoff cap 결정론 fake clock 재연결 간격 ≤ 30s, 재시도 상한 후 terminal 전이 none
FE-NFR-017 subscription leak unmount fixture unmount 후 열린 구독/연결 0 none
FE-NFR-018 upload part 재시도 결정론 fake clock part 당 재시도 ≤ 2 (FE-D015 상속), 전체 전송은 취소 가능 none
FE-NFR-019 worker task timeout worker fixture 기본 30s 초과 시 terminate 되고 결과를 기다리지 않음 none
FE-NFR-020 capability OFF 시 번들 증가 FE-NFR-C04 6개 capability 전부 OFF 일 때 initial JS gzip 증가 0 KiB none

FE-NFR-020FE-NFR-001(initial JS ≤ 200 KiB) 예산을 신규 기능이 잠식하지 않음을 수치로 방어하는 항목이다.

9.2 §9.5 실시간 surface state (신설)

hub §9.1 의 4-state 모델은 요청/응답 전용이라 스트림에 그대로 맞지 않는다. 별도 표로 추가하되 §9.1 과 충돌하지 않게 매핑을 명시한다.

State 의미 §9.1 대응 UI requirement
connecting 최초 연결 시도 중, 수신 이벤트 0 initial-loading 안정 skeleton, focus 탈취 금지
live 연결 유지, 이벤트 수신 중 success 최신 상태 표시
reconnecting 끊김 후 backoff 재시도 중, 마지막 데이터 유지 refreshing 기존 내용 유지 + 은은한 표시
resumed-with-gap 재연결했으나 resume cursor 로 메운 구간에 공백 존재 stale-degraded 공백 사실 표시 + 수동 새로고침
disconnected 재시도 상한 소진, terminal terminal-error 안전한 메시지 + registry action

reconnectingterminal-error 로 표시하면 사용자가 불필요하게 새로고침하고, disconnectedrefreshing 으로 표시하면 영원히 오지 않는 데이터를 기다린다. 이 구분이 이 표의 존재 이유다.

9.3 §9.6 전송 진행 surface state (신설)

State 의미 §9.1 대응 UI requirement
transfer-preparing presign 획득·part 분할 중 initial-loading 취소 가능 표시
transfer-active byte 전송 중 mutation-pending 진행률 + 취소, 중복 시작 차단
transfer-paused 사용자 중단 또는 네트워크 중단, 재개 가능 stale-degraded 재개 action
transfer-failed 재시도 소진 또는 무결성 불일치 terminal-error registry action, part 상태 폐기 여부 명시
transfer-completed 완료 및 검증됨 success 결과 표시

진행률은 telemetry 에 원본 크기·파일명을 남기지 않고 size_bucket·duration_bucket 만 남긴다(§6.2 telemetry 확장과 일치).

9.4 §9.7 Service Worker 갱신 surface state (신설)

State 의미 UI requirement
sw-none 등록 없음(기본) 표시 없음
sw-active 현재 release 의 SW 활성 표시 없음
sw-update-pending 새 SW 가 설치됐고 활성화 대기 사용자 주도 적용 action. 자동 skipWaiting 금지 — 열린 탭이 release 를 갈아타면 FE-OC-016 coherence 가 깨진다
sw-update-failed 등록·갱신 실패 SW_REGISTRATION_FAILED, 기능 저하만, 제품 흐름 차단 금지

9.5 §16 신규 runbook 2개

기존 5개 runbook 형식(trigger / diagnosis evidence / mitigation invariant / recovery assertion / escalation)을 그대로 따른다.

  • FE-RB-006 실시간 연결 장애 — trigger: realtime.connection.state_changedreconnecting 비율 급증 또는 REALTIME_RESUME_GAP 발생. mitigation invariant: 재연결 상한을 낮추거나 capability 를 OFF 로 내려 bounded polling 으로 강등하되 backend 에 무제한 재시도를 보내지 않는다. recovery assertion: 재연결 간격이 cap 이하이고 terminal 전이가 관측되며 구독 수가 안정된다.
  • FE-RB-007 백그라운드 실행 장애 — trigger: sw.update.applied 부재로 sw-update-pending 이 정체되거나 background.sync.replayed 에 중복 outcome. mitigation invariant: SW 등록을 해제해 이전 release 로 되돌릴 때 serviceWorkerVersion 을 함께 되돌리고, keyed 아닌 mutation 은 재생하지 않는다. recovery assertion: rollback 후 SW 버전이 대상 release 와 일치하고 중복 write 가 0 이다.

두 runbook 의 drill assertion 은 새 gate 를 만들지 않고 FE-GATE-031·FE-GATE-032 안에 포함한다. FE-OC-025 의 normative summary 를 "boot, chunk mismatch, API degradation, telemetry failure, rollback, realtime 연결, background 실행 runbook 을 MUST 유지" 로 갱신한다.


10. 그 밖의 hub 파급

10.1 §0.5 범위

In scope 에 추가:

  • 파일·바이너리 I-O 와 로컬 대용량 저장의 port·adapter 계약
  • 캐시 계층과 탭 간 무효화 계약
  • 대용량 객체 전송(presigned·재개 가능 업로드·스트리밍 다운로드)과 미디어 URL 정책
  • REST 이외 protocol adapter 의 정규화 계약
  • 실시간 구독 수명주기 계약
  • 백그라운드 실행(Worker·Service Worker·Background Sync) 계약

Out of scope 에 추가:

  • 위 6개 도메인의 use case, domain model, business rule — 이 skeleton 은 port 와 adapter 계약까지만 제공한다
  • 구체 backend API 설계, vendor 선택, 파일 형식별 처리, offline-first 동기화 충돌 해결

10.2 §8.2 Failure matrix

신규 26개 kind 에 대해 retryable 여부·기본 action·telemetry event·redaction 을 기존 표 형식으로 채운다. 특기 사항:

  • FILE_PICKER_DISMISSED — retryable 아님, action: none, error surface 없음, telemetry 없음(사용자 취소는 실패가 아니다)
  • CAPABILITY_DISABLED / CAPABILITY_UNSUPPORTED — retryable 아님, action 은 registry 의 disabledFallback 에 따름
  • PRESIGN_EXPIRED — retryable(presign 재획득 후 재개), action: retry
  • REALTIME_DISCONNECTED — 재시도 상한 소진 후 도달하는 terminal 이므로 자동 retry 금지, action: retry(사용자 주도)
  • BACKGROUND_SYNC_REPLAY_REJECTED — retryable 아님, action: contact-support, 중복 write 방지가 우선

10.3 §17.1 Evidence ledger

Evidence ID Artifact / observation Grade Supports Does not prove
FE-EV-014 본 설계 문서 documented-only 6개 도메인의 계약 범위·ID·기본값·게이트 구조 코드 존재, adapter 동작, 게이트 실행
FE-EV-015 신규 branch-note 6개 documented-only branch 소유권과 완료 조건의 선언 구현 또는 테스트

10.4 §18.2 Readiness scorecard

  • FE-RDY-009 blocking question "8 registry" → "9 registry"
  • 신규 행 FE-RDY-017 — blocking question "비활성 capability 가 번들에서 실제로 부재한가", required evidence "capability bundle report", Current FAIL, reason "build evidence UNVERIFIED"

10.5 §19 Risk / Open question

신규 risk:

Risk ID Risk Owner Trigger Mitigation
FE-RISK-013 capability flag 가 늘어나 조합 폭발로 테스트 매트릭스가 비현실적이 됨 capability owner 3개 이상 동시 활성 조합 대신 개별 ON + 전부 OFF 두 축만 gate 로 검증
FE-RISK-014 OPFS·Cache Storage 브라우저 지원 편차로 동일 코드가 환경별로 다르게 동작 binary I-O owner 지원 매트릭스 확정 feature detection + disabledFallback 강제
FE-RISK-015 presigned URL 이 로그·telemetry·referrer 로 유출 transfer owner 전송 구현 forbiddenAttributes + Referrer-Policy + gate negative fixture
FE-RISK-016 재연결 backoff 가 여러 구독에서 동시 만료해 thundering herd 발생 realtime owner 다중 구독 사용 구독별 독립 full jitter, 전역 동시 재연결 상한
FE-RISK-017 Service Worker 가 rollback 후에도 이전 스크립트를 유지해 release 판정이 어긋남 background exec owner rollback drill serviceWorkerVersion 토큰 + FE-RB-007
FE-RISK-018 protobuf·GraphQL 스키마 파이프라인이 없어 codec 과 runtime schema 가 갈라짐 protocol owner 첫 비-REST 통합 단일 생성 소스 결정 전까지 REST 유지

신규 open question:

Question ID Question Owner Decision trigger
FE-Q-011 6개 도메인의 근거 raw 문서(MDN·WHATWG·gRPC-Web·Connect·Web Push 등)를 언제 수집할 것인가 project owner 첫 capability 활성화
FE-Q-012 object storage 제공자와 presigned/multipart 제약(part 최소 크기·만료)은 무엇인가 transfer owner 첫 업로드 구현
FE-Q-013 protobuf/GraphQL 스키마 생성 파이프라인의 SSOT 는 어디인가 protocol owner 첫 비-REST 통합
FE-Q-014 Web Push 발송 서버와 VAPID 키 소유자는 누구인가 background exec owner push 활성화

FE-Q-009("service worker/offline이 필요한가")는 FE-D034 로 해소되므로 Resolution condition 열에 "FE-D034 로 해소(2026-07-28)" 를 기록하고 상태를 닫는다.

10.6 §22 External Answer Boundary

§22.2("설계라고 명시해야 답할 수 있는 것")에 추가: 6개 capability 의 port 이름·기본값·게이트 구조. §22.3("현재 답하면 안 되는 것")에 추가: 이 adapter 들이 동작한다는 진술, 성능·안정성 수치, 특정 vendor 와의 통합 검증.


11. Branch 스캐폴딩

11.1 §8.0 Work Item Registry 신규 행

이 절과 §11.2 에서 WI-…-0NNWI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-0NN 의, DEC-…-DOMAIN-001DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-DOMAIN-001 의 축약이다. hub 에 옮겨 적을 때는 전체 ID 를 그대로 쓴다. 전체 문자열 SSOT 는 §7.2 다.

Work Item ID branch slug 완료 조건 (측정가능) Applies Decisions Dependencies
WI-…-028 feature-frontend-binary-file-io-store-contract picker·다운로드·object URL 해제·quota·OPFS·Cache Storage fixture 가 통과하고 binary I-O report 가 생성된다 DEC-…-CAPABILITY-001@1, DEC-…-BINARY-STORE-001@1, DEC-…-REGISTRY-001@1 WI-…-011(storage registry), WI-…-002(layering)
WI-…-029 feature-frontend-cache-tier-cross-tab-invalidation-contract version 파티션·탭 간 무효화·채널 부재 fallback fixture 가 통과한다 DEC-…-CAPABILITY-001@1, DEC-…-CROSS-TAB-001@1, DEC-…-SERVER-STATE-001@1 WI-…-010(server state), WI-…-011
WI-…-030 feature-frontend-large-object-transfer-contract presign 만료·part 재시도·무결성·credential 경계 fixture 가 통과한다 DEC-…-CAPABILITY-001@1, DEC-…-TRANSFER-CREDENTIAL-001@1, DEC-…-RESUMABLE-TRANSFER-001@1 WI-…-005(API client), WI-…-028
WI-…-031 feature-frontend-multi-protocol-api-transport-contract protocol 별 성공/실패 정규화와 gateway fallback fixture 가 통과한다 DEC-…-CAPABILITY-001@1, DEC-…-PROTOCOL-001@1, DEC-…-VALIDATION-001@1 WI-…-005, WI-…-006(runtime schema), WI-…-007(error classification)
WI-…-032 feature-frontend-realtime-subscription-lifecycle-contract backoff·resume·구독 해제·이벤트 검증 fixture 와 FE-RB-006 drill 이 통과한다 DEC-…-CAPABILITY-001@1, DEC-…-REALTIME-TRANSPORT-001@1, DEC-…-REALTIME-LIFECYCLE-001@1 WI-…-006, WI-…-007, WI-…-013(async UI)
WI-…-033 feature-frontend-background-execution-worker-contract SW update UX·rollback SW 되돌림·sync idempotency·worker timeout fixture 와 FE-RB-007 drill 이 통과한다 DEC-…-CAPABILITY-001@1, DEC-…-SERVICE-WORKER-ROLE-001@1, DEC-…-BACKGROUND-SYNC-001@1, DEC-…-WORKER-TASK-001@1 WI-…-024(release/cache/rollback), WI-…-005

FE-GATE-033 의 owner 는 feature-frontend-env-runtime-config-contract 이므로 기존 WI-…-004 의 완료 조건에 "capability registry 와 default-off 번들 검증" 을 추가한다. 새 WI 를 만들지 않는다.

11.2 §20 Branch Decomposition 신규 행

Branch slug Primary contract IDs Contributes to Priority Dependency
feature-frontend-binary-file-io-store-contract FE-OC-027 FE-OC-013, FE-OC-022, FE-OC-029 P4 storage registry, layering
feature-frontend-cache-tier-cross-tab-invalidation-contract FE-OC-028 FE-OC-012, FE-OC-013, FE-OC-023 P4 server state, storage registry
feature-frontend-large-object-transfer-contract FE-OC-029 FE-OC-006, FE-OC-019, FE-OC-027 P4 API client, binary I-O
feature-frontend-multi-protocol-api-transport-contract FE-OC-030 FE-OC-006, FE-OC-007, FE-OC-008 P4 API client, runtime schema, error classification
feature-frontend-realtime-subscription-lifecycle-contract FE-OC-031 FE-OC-007, FE-OC-008, FE-OC-011, FE-OC-025 P4 runtime schema, error classification, async UI
feature-frontend-background-execution-worker-contract FE-OC-032 FE-OC-009, FE-OC-016, FE-OC-017, FE-OC-025 P4 release/cache/rollback, API client

P4 는 신규 우선순위 계층이다. 기존 P1~P3(핵심 skeleton)이 완료된 뒤 착수하는 opt-in capability 임을 뜻하며, §20 서두에 이 의미를 정의한다. §20 서두의 "27개 branch-note" 를 33개 로 고친다.

11.3 branch-note 파일 생성

templates/branch-note-template.md 로 6개 파일을 raw/branch-notes/ 에 생성한다. /branch 슬래시 명령은 이 repo 에 더 이상 존재하지 않으므로(§13 참조) 템플릿에서 직접 만든다.

각 파일에서 채우는 것:

  • frontmatter — title, source_type: branch-note, status: raw, id: BR-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-0NN, kind: project-work-item, project, work_item, inherits(§11.1 의 pin), imports(관련 FE-OC-*@1), delegates/accepts_delegations(§7.4), contract_packet: 1, related_projects, tags, created: 2026-07-28, status_label: in-progress
  • ## 부모[[raw/project-notes/ca-skeleton-frontend-operational-contract]] (project 직접 자식이므로 parent_branch: 는 비움)
  • ## 브랜치 계약 패킷 — 생성 시 project revision, 완료 조건(§11.1 문자열 그대로)
  • ### 상속한 프로젝트 결정 — pinned pointer + Summary 문자열(§7.2 SSOT 와 정확히 일치) + branch 적용점 1줄
  • ## 목표 / ## 범위 — 포함 범위는 port·adapter·registry·gate, 제외 범위에 "use case·domain model·business rule" 명시
  • ## 근거 — 이 설계 문서 링크 + "project-local default, 외부 source claim 아님" 명시
  • ## 검증해야 할 주장 — 대응 gate 의 fixture 를 claim 으로 전개

채우지 않는 것: ## 구현 가이드 는 헤딩과 R1/R2/R3 규칙 안내만 남기고 비워 둔다. 이 섹션은 근거 있는 결정에서 도출돼야 하며(CLAUDE.md §15.5), 근거 raw 수집 전에 채우면 전부 UNSUPPORTED_IMPL_DECISION 이 된다. 다음 단계에서 채운다.

11.4 §21.2 Cluster

<!-- GENERATED: branches:start --> 블록과 하단 수기 목록 양쪽에 6개 항목을 알파벳 순서로 삽입한다. 생성기가 없으므로 수기로 정렬을 맞춘다.


12. 편집 체크리스트

12.1 hub — raw/project-notes/ca-skeleton-frontend-operational-contract.md

# 섹션 변경
1 frontmatter imports 에 신규 FE-OC-027@1FE-OC-032@1, FE-GATE-027@1FE-GATE-033@1 중 hub 가 소비하는 것 추가; last_reviewed: 2026-07-28
2 §0.5 In scope 6항 + Out of scope 2항 (§10.1)
3 §2.1 FE-OC-027~032 행 6개 (§4.2); FE-OC-022·FE-OC-025 summary 갱신
4 §2.1.1 계약 행 6개 (§4.3) + gate 행 7개 (§8.2)
5 §2.1.2 DELEG-FE-007~011 (§7.4)
6 §2.1.4 FLOW-FE-EVENT-001~005 (§7.5)
7 §3.2 FE-D026~036 신규 11행 (§7.1); FE-D019superseded; FE-D018 Decision 셀 갱신
8 §6.1 DEC-… 신규 11행 (§7.2); OFFLINE-CACHE-001 revision 2; REGISTRY-001 Summary 갱신; 개정 기록 2건 추가 (§7.3)
9 §4.2 adapter 신규 10행 (§5.3)
10 §4.3 adapters/* 예외 2건 + worker/SW 엔트리 규칙 (§5.4)
11 §4.4 port 신규 12행 (§5.1) + "port 를 만들지 않는 두 가지" 문단 (§5.2)
12 §4.5 boot order 12단계로 교체 (§5.5)
13 §4.6 directory blueprint 확장 (§5.6)
14 §5.1 FE-REG-CAPABILITY 행 추가 (8→9)
15 §5.3 FE-REG-API 필드 5개 + sample 행 3개 + stream timeout 해석 문단
16 §5.4 FE-REG-ENV 신규 키 15개
17 §5.5 FE-REG-STORAGE 필드 2개 + backend enum 2값 + 행 4개
18 §5.6 kind enum 26종 추가
19 §5.7 FE-REG-QUERY 규칙 3행
20 §5.8 telemetry 이벤트 7개 + forbiddenAttributes 명시
21 §5.9 serviceWorkerVersion 토큰
22 §5.11 (신설) FE-REG-CAPABILITY minimum schema (§6.1)
23 §8.2 failure matrix 신규 kind 행 (§10.2)
24 §9.5~§9.7 realtime / transfer / SW surface state (§9.2~§9.4)
25 §14.2 FE-NFR-016~020 (§9.1)
26 §15.1 gate 7행 + 서두 "26개"→"33개" (§8.3)
27 §15.2 negative fixture 7행 (§8.4)
28 §15.3 promotion rule 교체 (§8.5)
29 §16 FE-RB-006·FE-RB-007 (§9.5)
30 §17.1 FE-EV-014·FE-EV-015
31 §18.1 NOT_APPLICABLE 불변식 (§8.1)
32 §18.2 FE-RDY-009 문구 + FE-RDY-017
33 §19.1 FE-RISK-013~018
34 §19.2 FE-Q-011~014 + FE-Q-009 해소 기록
35 §8.0 WI 6행 + WI-…-004 완료 조건 보강 (§11.1)
36 §20 branch 6행 + 서두 "27개"→"33개" + P4 정의 (§11.2)
37 §21.2 Cluster 6항 (§11.4)
38 §22.2·§22.3 answer boundary (§10.6)
39 §23.1 체크리스트 "8개 registry owner" → "9개", "runbook 5종" → "runbook 7종"
40 §25 Next Steps 에 P4 — Opt-in runtime capability 절 신설, 6개 branch 항목
41 §26 Verification Status Summary 에 opt-in runtime capability 행 추가 (planned, "설계만 존재; adapter·gate evidence UNVERIFIED")
42 §21 가져온 프로젝트 계약 + frontmatter imports FE-OC-027@1FE-OC-032@1 6행/6항 추가 — 2026-07-28 실행 중 정정. 초판은 "hub 가 정의하는 계약이므로 제외" 라 적었으나, 이 표와 배열은 FE-OC-002025 처럼 branch 가 owner 인 계약을 hub 가 pin 하는 곳이고 신규 6개도 같은 관계다. 제외하면 FE-OC-026(hub owner)과 구분이 사라진다. gate 는 기존에도 FE-GATE-018·026 2개만 pin 되어 있어 그 성긴 패턴을 유지한다

§24.2 drift check 는 손대지 않는다. 정규식 FE-D[0-9]{3}FE-REG-[A-Z]+(-[A-Z]+)*FE-D026~FE-D036FE-REG-CAPABILITY 를 이미 포괄하고, definition set 추출 패턴 ^\| \FE-` 도 신규 표 행 형식과 일치한다.

12.2 신규 파일 6개

raw/branch-notes/ 에 §11.3 대로 생성.

12.3 기존 branch-note 7개 수정

파일 변경 사유 변경
feature-frontend-release-cache-rollback-contract 결정 revision + 위임 접수 inherits: OFFLINE-CACHE-001@1@2; 상속 표 Summary 교체; accepts_delegationsDELEG-FE-011
feature-frontend-storage-registry-contract 문자열 파급 + 위임 접수 REGISTRY-001 Summary 문자열 교체; 본문의 "8개 registry 중 하나" 1곳; accepts_delegationsDELEG-FE-009@1 + 수신 위임 표
feature-frontend-observability-logging-trace-contract 문자열 파급 REGISTRY-001 Summary 문자열 교체
feature-frontend-contract-registry-governance 문자열 파급 (본문 다수) REGISTRY-001 Summary 문자열 교체 + 본문 서술 11곳의 "8개/8 registry" → 9 (완료 조건·D1·목표·구현가이드·TODO·검증표). 이 branch 는 registry governance owner 라 개수를 여러 절에서 서술한다 — Summary 만 고치면 문서가 자기모순이 된다
feature-frontend-contract-compatibility-governance 문자열 파급 REGISTRY-001 Summary 문자열 교체 + 본문 서술 2곳
feature-runtime-schema-validation-contract 위임 접수 accepts_delegationsDELEG-FE-010
feature-frontend-env-runtime-config-contract 신규 owner 취득 FE-REG-CAPABILITY registry owner 와 FE-GATE-033 gate owner 로서 소유 표 갱신; WI-…-004 완료 조건 보강 반영

13. 알려진 drift (이번 범위 밖)

직전 커밋 d71669e("하네스 제거")가 harness/.claude/{commands,agents,hooks} 를 삭제했다. 결과:

  • /branch·/branch-spec·/depth·/coverage·/lint·/sync 슬래시 명령이 존재하지 않는다. 이 설계의 branch 스캐폴딩은 템플릿에서 직접 수행한다.

  • hub §2.1.1 의 harness/source/typed-contracts.json 과 §2.1.3 의 harness/source/artifact-schemas/ca-skeleton-frontend/*.schema.json끊긴 경로다.

  • 결정론 검사기(wiki_consistency_check.py, wiki_structure_lint.py)가 없으므로 CONFLICTS_WITH_PROJECT_DECISION·STALE_IMPORTED_CONTRACT·UNACCEPTED_DELEGATION 은 자동 검출되지 않는다. §12 체크리스트의 문자열 정합은 수기로 확인해야 한다.

  • 기존 branch-note 129개 전부가 frontmatter 에 contract_packet_sha256 을 갖는다. 이 해시를 계산하던 branch_from_project.py 가 삭제됐으므로 신규 6개 노트에는 이 필드를 넣지 않았다. 값을 지어내면 검증기가 복원됐을 때 조용히 통과하는 거짓 해시가 남는다. 기존 7개 노트를 수정하면서 그쪽 해시도 낡았다 — 생성기가 복원되면 33개 노트를 일괄 재계산해야 한다.

이 drift 는 이번 작업이 만든 것이 아니며 고치지 않는다. 다만 두 가지로 대응한다.

  1. 신규 ART-FE-* 행을 만들지 않는다. §2.1.3 의 등록 기준은 "두 개 이상 branch 가 같은 파일의 필드를 각자 정하는 artifact" 이고, 신규 7개 gate 의 report 는 전부 단일 branch 소유이므로 애초에 등록 대상이 아니다. 끊긴 schema 경로를 늘리지 않는 부수 효과가 있다.
  2. hub §19.2 에 FE-Q-011 과 별개로 harness 복원 여부를 묻는 항목은 추가하지 않는다 — 이는 frontend 계약이 아니라 wiki 저장소 운영 이슈이므로 이 문서의 관심사가 아니다.

14. 승인 이력

일자 항목 결정
2026-07-28 분해 단위 6개 능력 도메인
2026-07-28 활성화 자세 port + adapter 구현, capability flag default OFF
2026-07-28 FE-D019 충돌 SW 역할 분리 후 supersede
2026-07-28 산출물 범위 hub 갱신 + branch-note 6개 스캐폴딩
2026-07-28 registry FE-REG-CAPABILITY 하나만 신설 → 9개
2026-07-28 근거 자료 project-local default 로 명시 + open question 예약
2026-07-28 설계 B 전체 승인

15. 실행 기록

2026-07-28 에 docs/superpowers/plans/2026-07-28-ca-skeleton-frontend-runtime-adapter-features.md 의 12개 Task 로 전부 실행했다. 실행 중 이 문서를 세 곳 정정했다.

항목 초판 정정 사유
§12.1 #42 §21 가져온 프로젝트 계약·frontmatter imports 를 건드리지 않음 FE-OC-027@1~032@1 추가 두 곳 모두 branch-owned 계약을 hub 가 pin 하는 자리다. 제외하면 hub-owned(FE-OC-001·026)와 구분이 사라진다
§12.3 REGISTRY-001 Summary 문자열만 교체 contract-registry-governance 본문 11곳, compatibility-governance 2곳, storage-registry 1곳의 개수 서술도 갱신 Summary 만 고치면 같은 파일 안에서 "9개 registry 로 관리한다"와 "8개 registry 를 single-owner 로 관리한다"가 공존한다
§13 contract_packet_sha256 언급 없음 신규 6개 노트에 필드 미포함 + 기존 7개 해시가 낡았음을 명시 생성기 부재 상태에서 값을 지어내면 거짓 해시가 남는다

검증 결과(계획 §Task 12): 정의 없는 참조 0건, FE-OC·FE-GATE 정의 행 중복 이상 0건, 개수 정합 10항 전부 일치(FE-OC 32 / FE-GATE 33 / FE-D 36 / DEC 36 / FE-REG 9 / FE-NFR 20 / FE-RB 7 / WI 33 / 소속 노트 33 / Cluster 33), 미접수 위임 0건, 낡은 결정 문자열 0건, 깨진 wikilink 0건, 신규 문서의 과장 등급 주장 0건.