docs(hub): 범위·runbook 2개·evidence·risk·open question·답변경계

- §0.5 out of scope 에 '6개 도메인의 use case/domain model/business rule'
  을 명시. 이 skeleton 은 port 와 adapter 계약까지다.
- FE-RB-006 실시간 연결 장애 — 상한 소진 후 terminal 전이가 유지되는지
  먼저 확인하고 backend 에 무제한 재시도를 보내지 않는다
- FE-RB-007 백그라운드 실행 장애 — skipWaiting 임의 강제 금지,
  중복 write 방지가 지연 전송보다 우선
- FE-Q-009(service worker 필요한가)는 FE-D034 로 해소
This commit is contained in:
DongHyeonka
2026-07-28 14:23:45 +09:00
parent 1f5a5ced3a
commit 074931bea4
@@ -116,9 +116,17 @@ In scope:
- backend API 및 auth provider와 연결되는 얇은 integration port
- static hosting과 browser runtime의 failure mode
- sample feature slice를 통한 contract enforcement
- 파일·바이너리 I-O와 로컬 대용량 저장(IndexedDB·OPFS·Cache Storage)의 port·adapter 계약
- 캐시 계층(memory↔session↔local↔IndexedDB)과 탭 간 무효화 계약
- 대용량 객체 전송(presigned URL·재개 가능 업로드·스트리밍 다운로드)과 미디어 URL 정책
- REST 이외 protocol adapter(GraphQL·gRPC-Web·Connect-Web·REST gateway)의 정규화 계약
- 실시간 구독(SSE·WebSocket·WebPush·bounded polling)의 수명주기 계약
- 백그라운드 실행(Web Worker·Service Worker·Background Sync) 계약
Out of scope:
- **위 6개 도메인의 use case, domain model, business rule** — 이 skeleton은 port와 adapter 계약까지만 제공한다
- 구체 backend API 설계(presigned URL 발급 endpoint 스펙, GraphQL 스키마, protobuf 서비스 정의, push 발송 서버), vendor 선택(Image CDN·object storage·push 서비스), 파일 형식별 처리(이미지 리사이즈·트랜스코딩·문서 파싱), offline-first 동기화 충돌 해결(CRDT·last-write-wins 등)
- domain-specific page, business rule, copy, branding, product analytics taxonomy
- token 발급, token 저장, refresh token rotation, logout propagation의 lifecycle 소유
- backend authorization 판정 대체
@@ -2216,6 +2224,111 @@ Runbook은 provider-specific console command를 현재 발명하지 않는다.
`artifacts/runbooks/FE-RB-005/<release-id>/` planned.
### 16.6 `FE-RB-006` — 실시간 연결 장애
| Field | Planned contract |
| --- | --- |
| Primary owner | `feature-frontend-operational-runbook-contract` |
| Technical escalation | `feature-frontend-realtime-subscription-lifecycle-contract` → backend API owner |
| Activation condition | `realtime.connection.state_changed``reconnecting` 비율 급증, 또는 `REALTIME_RESUME_GAP` 발생 |
| Conditional window | detection 즉시 containment; owner triage 시작 목표 5분 |
| Evidence path | `artifacts/runbooks/FE-RB-006/<release-id>/` |
**Trigger**
- `REALTIME_CONNECT_FAILED`가 다수 세션에서 반복
- `REALTIME_DISCONNECTED` terminal 전이 급증
- `REALTIME_RESUME_GAP` 감지
**Immediate containment**
1. 재연결 상한과 cap을 현재 값 이하로 낮춘다.
2. 필요하면 `CAP_FE_REALTIME`을 OFF로 내려 bounded polling으로 강등한다.
3. backend에 무제한 재시도를 보내지 않는다 — 상한 소진 후 terminal 전이가 유지되는지 먼저 확인한다.
**Diagnosis evidence**
- transport 종류(SSE/WebSocket/poll)와 `attempt_count_bucket` 분포
- terminal 전이까지 걸린 시간과 `from_state`/`to_state` 흐름
- `realtime.event.rejected` 비율 — 스키마 drift와 연결 장애를 구분한다
- 동시 열린 구독 수 추이
**Mitigation options**
- backend 측 연결 한도/유휴 종료가 원인 → 서버 정책 확인 후 cap 조정.
- resume cursor 불일치가 원인 → 해당 구독을 full refetch로 강등.
- transport 자체가 불가 → capability OFF + bounded polling fallback.
**Escalation**
- transport 종류를 바꿔도 재현되면 backend API owner에게 확대한다.
- 스키마 거부가 주원인이면 `feature-runtime-schema-validation-contract` owner에게 넘긴다.
**Recovery assertions**
- 재연결 간격이 cap(`REALTIME_RECONNECT_CAP_MS`) 이하
- 상한 소진 시 terminal 전이가 관측됨
- 동시 열린 구독 수가 단조 증가하지 않음
- `EVENT_SCHEMA_MISMATCH`로 드롭된 프레임이 application에 도달하지 않음
**Evidence**
`artifacts/runbooks/FE-RB-006/<release-id>/` planned.
### 16.7 `FE-RB-007` — 백그라운드 실행 장애
| Field | Planned contract |
| --- | --- |
| Primary owner | `feature-frontend-operational-runbook-contract` |
| Technical escalation | `feature-frontend-background-execution-worker-contract``feature-frontend-release-cache-rollback-contract` |
| Activation condition | `sw.update.applied` 부재로 `sw-update-pending`이 정체, 또는 `background.sync.replayed`에 중복 outcome |
| Conditional window | detection 즉시 containment; owner triage 시작 목표 5분 |
| Evidence path | `artifacts/runbooks/FE-RB-007/<release-id>/` |
**Trigger**
- `SW_REGISTRATION_FAILED` 반복
- `sw-update-pending` 상태가 다수 세션에서 해소되지 않음
- `BACKGROUND_SYNC_REPLAY_REJECTED` 또는 중복 write 정황
- rollback 후 `serviceWorkerVersion`이 target release와 불일치
**Immediate containment**
1. background sync 큐 등록을 중단한다 — 중복 write 방지가 지연 전송보다 우선이다.
2. `skipWaiting`을 임의로 강제하지 않는다. 열린 탭이 release를 갈아타면 `FE-OC-016` coherence가 깨진다.
3. 필요하면 `CAP_FE_BACKGROUND_EXEC`를 OFF로 내리고 SW 등록을 해제한다.
**Diagnosis evidence**
- `serviceWorkerVersion` vs `releaseId`·`buildId`
- `sw.update.applied``previous_build_id` 흐름
- `background.sync.replayed``outcome` 분포와 대상 `operation_id``idempotency`
- `WORKER_TASK_TIMEOUT` 비율
**Mitigation options**
- SW 스크립트만 stale → 해당 scope 등록 해제 후 재등록.
- rollback과 SW 버전 불일치 → `DELEG-FE-011`에 따라 release owner가 SW 버전을 함께 되돌린다.
- keyed 아닌 mutation이 큐에 들어감 → 큐를 비우고 `FE-D035` 위반 지점을 코드에서 제거한다.
**Escalation**
- release·rollback 판정이 필요하면 `feature-frontend-release-cache-rollback-contract` owner에게 넘긴다.
- 중복 write가 실제 발생했으면 backend owner에게 즉시 확대한다.
**Recovery assertions**
- rollback 후 `serviceWorkerVersion`이 대상 release와 일치
- 중복 write 0건
- `sw-update-pending`이 사용자 주도 action으로 해소됨
- worker task가 timeout 후 terminate되고 결과를 기다리지 않음
**Evidence**
`artifacts/runbooks/FE-RB-007/<release-id>/` planned.
두 runbook의 drill assertion은 새 gate를 만들지 않고 `FE-GATE-031`·`FE-GATE-032`의 required fixture에 포함한다.
---
## 17. Evidence Ledger
@@ -2237,6 +2350,8 @@ Runbook은 provider-specific console command를 현재 발명하지 않는다.
| `FE-EV-011` | deployment draw.io + `docs/superpowers/specs/2026-07-18-ca-skeleton-frontend-operational-contract-review/diagram-review.md` | `documented-only`, reviewer PASS 100/100 scoped | static asset와 `/config.json` delivery slice가 declared boundary와 정합 | §12 전체 release/rollback topology, 실제 hosting·deploy |
| `FE-EV-012` | test/CI evidence | `UNVERIFIED` | dedicated search/command가 기록되지 않았다는 경계 | artifact 부재 또는 gate pass/fail |
| `FE-EV-013` | release/deploy evidence | `UNVERIFIED` | dedicated search/command가 기록되지 않았다는 경계 | artifact 부재, rollback 또는 runtime behavior |
| `FE-EV-014` | `docs/superpowers/specs/2026-07-28-ca-skeleton-frontend-runtime-adapter-features-design.md` | `documented-only` | 6개 능력 도메인의 계약 범위·ID·기본값·gate 구조 | 코드 존재, adapter 동작, gate 실행 |
| `FE-EV-015` | `FE-OC-027`~`FE-OC-032`의 신규 branch-note 6개 | `documented-only` | branch 소유권과 완료 조건의 선언 | 구현 또는 테스트 |
### 17.2 Evidence promotion protocol
@@ -2333,6 +2448,12 @@ Repository identity와 implementation/test/CI/deploy evidence 또는 blocking ga
| `FE-RISK-010` | bundle threshold가 실제 device UX와 무관 | performance owner | first measurement | context/field data로 threshold revisit | decision update with evidence | `open` |
| `FE-RISK-011` | supply-chain scanner policy가 미정이라 gate가 형식적 | security owner | repo bootstrap | scanner/severity/suppression decision | SARIF gate pass | `open` |
| `FE-RISK-012` | draw.io와 text contract의 component/edge drift | architecture owner | diagram 또는 FE-D 변경 | reviewer + contract ID annotation in caption | review report resolves all edges | `open` |
| `FE-RISK-013` | capability flag가 늘어나 조합 폭발로 테스트 매트릭스가 비현실적이 됨 | capability owner | 3개 이상 동시 활성 | 조합 대신 개별 ON + 전부 OFF 두 축만 gate로 검증 | `FE-GATE-033`이 두 축을 모두 산출 | `open` |
| `FE-RISK-014` | OPFS·Cache Storage 브라우저 지원 편차로 동일 코드가 환경별로 다르게 동작 | binary I-O owner | 지원 매트릭스 확정 | feature detection + `disabledFallback` 강제 | `FE-NFR-C02` 브라우저 매트릭스에서 fallback 동작 확인 | `open` |
| `FE-RISK-015` | presigned URL이 로그·telemetry·referrer로 유출 | transfer owner | 전송 구현 | `forbiddenAttributes` + `Referrer-Policy` + gate negative fixture | `FE-GATE-029` credential/URL 누출 fixture pass | `open` |
| `FE-RISK-016` | 재연결 backoff가 여러 구독에서 동시 만료해 thundering herd 발생 | realtime owner | 다중 구독 사용 | 구독별 독립 full jitter + 전역 동시 재연결 상한 | 다중 구독 fixture에서 재연결 분산 확인 | `open` |
| `FE-RISK-017` | Service Worker가 rollback 후에도 이전 스크립트를 유지해 release 판정이 어긋남 | background exec owner | rollback drill | `serviceWorkerVersion` 토큰 + `FE-RB-007` | `FE-GATE-032` rollback fixture pass | `open` |
| `FE-RISK-018` | protobuf·GraphQL 스키마 파이프라인이 없어 codec과 runtime schema가 갈라짐 | protocol owner | 첫 비-REST 통합 | 단일 생성 소스 결정 전까지 REST 유지 | `FE-Q-013` 해소 + `FE-GATE-030` pass | `open` |
### 19.2 Open questions
@@ -2346,8 +2467,12 @@ Repository identity와 implementation/test/CI/deploy evidence 또는 blocking ga
| `FE-Q-006` | auth integration adapter는 어떤 owner가 제공하는가? | auth owner | guarded route | session interface + lifecycle doc | port contract test |
| `FE-Q-007` | browser support matrix는? | product owner | first release | product analytics/requirement | CI browser matrix fixed |
| `FE-Q-008` | telemetry sink와 consent policy는? | telemetry/privacy owners | production telemetry | data inventory + endpoint | redaction and delivery tests |
| `FE-Q-009` | service worker/offline이 필요한가? | product/release owners | offline requirement | UX/update design | `FE-D019` retained or superseded |
| `FE-Q-009` | service worker/offline이 필요한가? | product/release owners | offline requirement | UX/update design | **해소(2026-07-28)**`FE-D034``FE-D019`를 superseded. precaching은 off 유지, push/sync/Cache Storage 호스트만 opt-in |
| `FE-Q-010` | vulnerability/license blocking threshold는? | security owner | CI setup | organization policy | security gate configured |
| `FE-Q-011` | 6개 능력 도메인의 근거 raw 문서(MDN·WHATWG·gRPC-Web·Connect·Web Push 등)를 언제 수집할 것인가? | project owner | 첫 capability 활성화 | raw source 문서 + verbatim quote | `FE-D026`~`FE-D036`의 rationale이 project-local default에서 외부 근거로 승격 |
| `FE-Q-012` | object storage 제공자와 presigned/multipart 제약(part 최소 크기·만료)은 무엇인가? | transfer owner | 첫 업로드 구현 | provider 문서 + 실측 | `FE-D030`의 part size·병렬도 default 확정 |
| `FE-Q-013` | protobuf/GraphQL 스키마 생성 파이프라인의 SSOT는 어디인가? | protocol owner | 첫 비-REST 통합 | 생성 도구 + 버전 관리 방식 | codec과 runtime schema가 한 소스에서 생성됨 |
| `FE-Q-014` | Web Push 발송 서버와 VAPID 키 소유자는 누구인가? | background exec owner | push 활성화 | 발송 서버 소유자 + 키 관리 절차 | `PUSH_PUBLIC_KEY` 값의 출처와 회전 절차 확정 |
---
@@ -2585,6 +2710,7 @@ Canonical 또는 derived 문서는 implementation evidence와 promotion gate를
- 왜 build/runtime/secret config를 분리했는지
- 왜 retry에 cap, jitter, idempotency 조건을 둔 설계인지
- 두 architecture diagram의 scoped reviewer PASS와 그 범위; implementation·§12 전체 deploy/rollback evidence와는 분리한 설명
- 6개 opt-in capability의 port 이름·기본값·gate 구조와, 왜 멀티프로토콜에 신규 port를 두지 않았는지
### 22.2 설계라고 명시해야 답할 수 있는 것
@@ -2611,6 +2737,9 @@ repository 생성 후 <gate/artifact>로 검증할 예정이다.
- retry/rollback이 운영 장애에서 효과가 있었다는 주장
- auth token refresh를 구현했다는 주장
- diagram review가 실제 implementation·hosting·§12 전체 release/rollback을 증명한다는 주장
- 6개 capability의 adapter가 동작한다는 주장
- 실시간·전송·worker의 성능이나 안정성 수치를 측정했다는 주장
- 특정 storage·CDN·push vendor와의 통합을 검증했다는 주장
### 22.4 Derived output gate