--- title: branch / feature-frontend-storage-registry-contract source_type: branch-note status: raw id: BR-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-011 kind: project-work-item project: ca-skeleton-frontend-operational-contract work_item: WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-011 inherits: [DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-REGISTRY-001@1] refines: [] overrides: [] depends_on: [WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-002] contract_packet: 1 branch: feature-frontend-storage-registry-contract parent_branch: related_projects: [ca-skeleton-frontend, ca-skeleton] governing_docs: [raw/project-notes/ca-skeleton-frontend-operational-contract.md] tags: [branch, ca-skeleton, frontend, persistence, security, javascript] created: 2026-07-18 target_merge: status_label: in-progress contract_packet_sha256: aa55f276dab66670f66f2424f059e394925f5f1c84ec23381fe506064f4823a1 imports: [FE-GATE-005@1, FE-OC-002@1, FE-OC-010@1, FE-OC-019@1, FE-OC-023@1] --- # branch: feature-frontend-storage-registry-contract > Layer: `raw/branch-notes/` — 단일 브랜치의 TODO·결정·진행 기록. 현재는 `/branch-spec` 로 채운 `planned` 명세 단계다 (frontend repository 미생성). ## 부모 (필수) - [[raw/project-notes/ca-skeleton-frontend-operational-contract]] ## 브랜치 계약 패킷 - **생성 시 프로젝트 개정**: `1` - **패킷 스키마**: `contract_packet: 1` - **완료 조건**: namespace·version·classification·quota fallback test가 통과한다 ### 상속한 프로젝트 결정 | Decision Ref | Project Summary | Branch Application | Source | |---|---|---|---| | `DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-REGISTRY-001@1` | route, API operation, env, storage, error, query, telemetry, release token을 8개 registry로 관리한다 | FE-REG-STORAGE namespace·version·classification schema에 적용한다 | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] | ### 브랜치 지역 결정 | Decision ID | Decision | Relation | Supporting Claims | Status | |---|---|---|---|---| | D1 | storage key를 FE-REG-STORAGE와 versioned namespace로 관리한다 | `local` | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] | `proposed` | | D2 | storage item classification을 필수로 둔다 | `local` | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] | `proposed` | | D3 | schemaVersion mismatch를 migration 또는 discard로 처리한다 | `local` | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] | `proposed` | | D4 | application-owned StoragePort와 storage adapter를 사용한다 | `local` | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] | `proposed` | | D5 | quotaFallback을 registry field로 관리한다 | `local` | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] | `proposed` | | D6 | token·secret·PII·raw payload 저장을 거부한다 | `local` | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] | `proposed` | ### 선언한 예외 | Override ID | Overrides | Reason | Approval | Status | |---|---|---|---|---| 없음. ## 목표 이 브랜치는 project-wide 계약 `FE-OC-013` (browser storage key 는 namespace·version·classification 을 MUST 보유하고 token/secret 저장을 금지) 를, 다음 구현자가 되묻지 않고 `src/contracts/storage-keys.js` 와 `adapters/storage` 를 작성할 수 있는 implementation-ready 명세로 내린다. `FE-REG-STORAGE` 는 [[raw/project-notes/ca-skeleton-frontend-operational-contract]] `FE-D018` 이 규정한 8개 registry 중 하나이며 본 브랜치가 single owner 다. 최소 스키마는 §5.5, 런타임 동작은 §9.4, 브라우저 보안 불변식(번들·storage = 공개물, secret 저장 금지)은 §13.2, quota/unavailable 실패 정규화는 §8.2 에 근거한다. 아직 frontend repository 가 없으므로 본 브랜치의 모든 항목은 `planned` 등급이다. - 이슈: TODO (아직 없음) - PR: TODO (아직 없음) ## 범위 ### 포함 범위 - `FE-REG-STORAGE` registry 스키마 정의 및 single-owner 소유 (§5.5): `logicalName` / `physicalKey` (`::v:`) / `backend` / `classification` / `schemaVersion` / `ttl` / `migration` / `quotaFallback` 필드 계약. - 구조화된 physical key 규약(namespace + schema version 내장) + raw literal key 금지 강제. - classification 3분류(`public-preference` / `opaque-cache` / `sensitive-forbidden`) + sensitive 저장 금지 불변식. - `schemaVersion` + previous-version migration-or-discard 규약. - 단일 application 소유 `StoragePort` + `adapters/storage` 어댑터 boundary, try/catch 로 unavailable / security / quota 구분. - quota fallback 정책(`memory` / `no-persist` / `feature-disable`) + correctness-critical 값의 fallback 금지. - storage 관련 negative fixture: token key 등록 시도 실패(§15.2), quota-exceeded → memory fallback, 미등록 raw key 사용 금지. ### 제외 범위 > 의도적으로 제외 — 다른 owner 브랜치가 소유. CLAUDE.md §15.5 R3(OUT_OF_BRANCH_SCOPE) 준수. - Token / refresh token / auth session material 의 lifecycle·저장 위치 — 외부 auth owner + [[raw/branch-notes/feature-frontend-auth-session-integration-contract]] (`FE-OC-010`) 소유. 본 registry 는 이를 `sensitive-forbidden` 으로 *거부* 만 한다. - CSP / header / secret-scan 등 브라우저 보안 경계 전반 — [[raw/branch-notes/feature-frontend-browser-security-boundary-contract]] (`FE-OC-019`) 소유. 본 브랜치는 storage 관련 fixture 만 기여. - Query cache 의 in-memory 정책·persistence 활성화 — [[raw/branch-notes/feature-server-state-caching-contract]] (`FE-OC-012`) 소유. 본 registry 는 opt-in persistence 가 요구하는 storage key 계약만 제공. - 8-registry governance 전반의 single-owner / compatibility 추적 메커니즘 — [[raw/branch-notes/feature-frontend-contract-registry-governance]] (`FE-OC-022`) 소유. 본 브랜치는 storage registry 스냅샷 1개를 기여. - storage schema 의 breaking-change migration / version-bump 판정 규약 — [[raw/branch-notes/feature-frontend-contract-compatibility-governance]] (`FE-OC-023`) 소유. 본 브랜치는 `schemaVersion` 필드와 discard 기본값만 정의. - `STORAGE_UNAVAILABLE` / `STORAGE_QUOTA_EXCEEDED` error kind enum 정의 — [[raw/branch-notes/feature-frontend-error-classification-boundary-contract]] (`FE-OC-008`) 소유. 본 브랜치는 adapter 실패 → 해당 kind 매핑만. ## 근거 (필수, 최소 1개+) > 본 브랜치는 project-decision-heavy — 외부 storage best-practice 인용 없이 hub 계약(SSOT)에 근거한다. 아카이브된 6개 frontend official-doc(vite/react-ui/tailwind/tanstack-query/zod/react-router) 중 browser storage 를 다루는 것은 없음(확인 완료). | Source | 정당화하는 결정 | |---|---| | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] | 본 브랜치 SSOT. `FE-OC-013` + `FE-D018` + §5.5 / §9.4 / §13.2 / §8.2 / §5.1 이 D1–D6 전부의 근거 (project decision). | | [[raw/official-docs/react-ui-library-official]] | 시드된 일반 frontend UI-composition source (hub §21.3, `FE-D004` React 선택 근거 `REACT-UI-C1`). **storage 전용 결정을 직접 정당화하지 않음** — 본 브랜치 grounding 은 위 hub 계약이다. | ## TODO 각 항목 옆 증거 등급 표기. frontend repository 미생성이므로 전부 `planned` / `needs-confirmation`. - [ ] `src/contracts/storage-keys.js` 에 `FE-REG-STORAGE` 스키마 + 초기 행(COLOR_SCHEME / CHUNK_RELOAD_GUARD / QUERY_PERSISTENCE / AUTH_TOKEN) 정의 — 등급: `planned` - [ ] physical key 빌더 `::v:` + raw literal 금지 lint/test — 등급: `planned` - [ ] classification enforcement + `sensitive-forbidden` 등록 거부 negative fixture(token key 등록 시도) — 등급: `planned` - [ ] `schemaVersion` + migration-or-discard 경로 및 previous-version fixture — 등급: `planned` - [ ] `StoragePort` + `adapters/storage` try/catch 어댑터, unavailable / security / quota 분기 매핑 — 등급: `planned` - [ ] quota fallback 정책 test(`memory` / `no-persist` / `feature-disable`) + correctness-critical no-fallback assertion — 등급: `planned` - [ ] 구현 repository·검증 evidence 식별 — 등급: `needs-confirmation` ## 진행 중 메모 - `/branch-spec` fill 완료 (2026-07-19). 모든 근거는 hub 계약(FE-OC-013 / FE-D018 / §5.5 / §9.4 / §13.2 / §8.2). 외부 storage best-practice 인용 없음 — project-decision 중심 브랜치. ## 결정 사항 > Decision Evidence Map 의 prose mirror. 각 근거는 hub 계약을 가리킨다(외부 source 없음). - **D1**: 모든 storage 항목은 `FE-REG-STORAGE` registry 에만 등록하고 physical key 는 `::v:` 구조를 MUST 가진다(raw `localStorage` literal 금지). 검토한 대안: code-generation SSOT 로 key 생성. 근거: [[raw/project-notes/ca-skeleton-frontend-operational-contract]] `FE-OC-013` · §5.5 · §5.1. - **D2**: 각 항목은 classification(`public-preference` / `opaque-cache` / `sensitive-forbidden`)을 MUST 명시하며 분류 불명 항목은 등록 거부한다. 근거: [[raw/project-notes/ca-skeleton-frontend-operational-contract]] `FE-OC-013` · §5.5. - **D3**: 각 항목은 `schemaVersion` 을 MUST 가지며 incompatible change 시 증가, previous version 을 읽으면 migration 또는 discard(기본 discard). 검토한 대안: 무버전 + 항상 discard. 근거: [[raw/project-notes/ca-skeleton-frontend-operational-contract]] §5.5 · §9.2. - **D4**: 모든 Web Storage 접근은 application 소유 `StoragePort` + `adapters/storage` 어댑터를 통해서만 하고 try/catch 로 unavailable / security / quota 를 구분한다. 검토한 대안: 컴포넌트 직접 `localStorage` 접근. 근거: [[raw/project-notes/ca-skeleton-frontend-operational-contract]] §9.4 · §4.4 · `FE-D010`(port ownership). - **D5**: `quotaFallback` 은 필수 필드(`memory` / `no-persist` / `feature-disable`)이며 quota 초과 시 허용된 cache 를 registry 명시 순서로 evict 후 memory fallback, 단 correctness-critical(mutation / idempotency record) 값은 fallback 금지·terminal 처리한다. 근거: [[raw/project-notes/ca-skeleton-frontend-operational-contract]] §5.5 · §9.4 · §8.2. - **D6**: token / secret / PII / raw API response / error body 는 default registry 에 등록 불가(`sensitive-forbidden`)이며 브라우저 번들·storage 를 공개물로 간주한다. 근거: [[raw/project-notes/ca-skeleton-frontend-operational-contract]] `FE-OC-013` · §9.4 · §13.2. 공동 집행: [[raw/branch-notes/feature-frontend-browser-security-boundary-contract]] (`FE-OC-019`); token lifecycle 은 [[raw/branch-notes/feature-frontend-auth-session-integration-contract]] (`FE-OC-010`) 외부 소유. ## 결정-근거 매핑 > `선택 조건` = hub 결정이 `accepted-documented-only`(`FE-D018`) 이므로 대부분 불변식을 고정. 분기 있는 것만 대안 조건 명시. Supporting Claims 는 hub 계약을 가리킨다(project-decision-heavy 브랜치 — 외부 doc 없음). | Decision ID | Decision | 선택 조건 (언제 이 결정 / 언제 대안) | Supporting Claims | Evidence Strength | Open Risk | |---|---|---|---|---|---| | D1 | storage 항목은 `FE-REG-STORAGE` 에만 등록, physical key `::v:` 구조 필수, raw literal 금지 (`FE-OC-013`) | skeleton storage 는 항상 registry 경유; 대안(code-generation SSOT 로 key 생성)은 `FE-D018` revisit trigger(code generation SSOT 채택) 발생 시에만 | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] `FE-OC-013` · §5.5 · §5.1 | `project-decision` | `` literal 값과 `` 분류 체계(feature별 vs flat) 미확정 — 구현 시 결정 | | D2 | 각 항목 classification 3분류 MUST 명시; 분류 불명 → 등록 거부 | 모든 항목 분류 강제(안전 기본); 분기 없음 | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] `FE-OC-013` · §5.5 | `project-decision` | `opaque-cache` vs `public-preference` 경계 판정 기준 문서화 필요 | | D3 | `schemaVersion` 필수 + incompatible 시 증가, previous version 은 migration 또는 discard | 기본 discard; migration 선택 시 fixture·rollback 은 compatibility-governance(`FE-OC-023`)로 위임 | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] §5.5 · §9.2 | `project-decision` | migration 필요 항목 발생 시 `FE-OC-023` 과 계약 조율 필요 | | D4 | 단일 application 소유 `StoragePort` + `adapters/storage` try/catch, unavailable / security / quota 분기 구분 | Clean Arch layering(`FE-OC-002`) 하에 port-owned 항상; 직접 `localStorage` 접근 금지 | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] §9.4 · §4.4 · `FE-D010` | `project-decision` | private-mode / 정책 차단의 SecurityError 세부 분기 미검증 | | D5 | `quotaFallback` 필수(`memory` / `no-persist` / `feature-disable`); quota 초과 시 evict→memory, correctness-critical 값 fallback 금지 | preference write 실패 → memory fallback 무중단; mutation / idempotency 등 correctness-critical → fallback 없이 terminal | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] §5.5 · §9.4 · §8.2 | `project-decision` | eviction 순서(어떤 cache 먼저)의 registry 표기 형식 미정 | | D6 | token / secret / PII / raw response / error body = `sensitive-forbidden`, default registry 등록 불가, storage = 공개물 | skeleton default 는 항상 금지; auth owner 가 storage 사용 필요 시 별도 threat model + owner evidence(§6.1) — 본 브랜치 범위 밖 | [[raw/project-notes/ca-skeleton-frontend-operational-contract]] `FE-OC-013` · §9.4 · §13.2 · §5.4 | `project-decision` | 공동 집행 경계(browser-security `FE-OC-019` / auth `FE-OC-010`) fixture 중복·누락 조율 | ## 구현 가이드 > `planned` blueprint — frontend repository 미생성. 경로는 hub §4.6 Planned directory blueprint + §5.1 registry owner map 에서 도출(grounded)되나, 코드는 아직 없으므로 전체가 `planned`. CLAUDE.md §15.5 R1(Trace)·R2(UNSUPPORTED_IMPL_DECISION)·R3(OUT_OF_BRANCH_SCOPE) 준수. ### 1. `FE-REG-STORAGE` registry schema (`src/contracts/storage-keys.js`) > **Trace**: D1, D2, D3, D5 → [[raw/project-notes/ca-skeleton-frontend-operational-contract]] `FE-OC-013` · `FE-D018` · §5.5 · §5.1. > > - **UNSUPPORTED_IMPL_DECISION**: > - physical key 의 `` literal 값(예: `ca`)과 `` 분류 체계(feature-prefix vs flat namespace) — §5.5 는 *형식*만 규정하고 구체 값을 권고하지 않음. trade-off: 짧은 prefix = 충돌 위험, 긴 prefix = key 길이 증가. > - registry 를 JS object literal vs factory 함수로 표현 — hub 미권고. trade-off: object = 단순, factory = 등록 시 검증 강제 용이. > - `schemaVersion` 표기(정수 vs semver) — §5.5 는 increment 만 규정. trade-off: 정수 = 단순 비교, semver = additive/breaking 구분. **필드 계약(8-field 스키마)과 초기 4행의 owner 는 [[raw/project-notes/ca-skeleton-frontend-operational-contract]] §5.5 다** — 이전 판은 두 표를 1:1 로 옮겨 적고 있었고("전부 §5.5 grounded" · "§5.5 planned rows 그대로" 라고 스스로 밝힌 그대로), 그러면 §5.5 가 필드를 추가할 때 이 사본이 조용히 낡는다. 요약 한 줄: storage key 는 `logicalName`·`physicalKey`·`backend`·`classification`·`schemaVersion`·`ttl`·`migration`·`quotaFallback` 8필드를 가지고, 초기 행은 색상 테마·chunk reload guard·query persistence(비활성)·auth token(금지) 4개다. 본 브랜치가 소유하는 것은 그 위의 **강제 방법**이다 — 아래 enforcement point, key-name deny 패턴, quota fallback 사다리. ### 2. `StoragePort` boundary + adapter failure mapping (`application/ports` + `adapters/storage`) > **Trace**: D4, D5 → [[raw/project-notes/ca-skeleton-frontend-operational-contract]] §9.4 · §4.4 · §8.2 · `FE-D010`. > > - **UNSUPPORTED_IMPL_DECISION**: > - `StoragePort` method 시그니처(예: `get(logicalName)` / `set(logicalName, value)` / `remove(logicalName)`)의 정확한 이름·인자 — §9.4 는 boundary 원칙만 규정. trade-off: 좁은 API = 안전, 넓은 API = 유연. > - **OUT_OF_BRANCH_SCOPE**: `STORAGE_UNAVAILABLE` / `STORAGE_QUOTA_EXCEEDED` **kind enum 정의**는 [[raw/branch-notes/feature-frontend-error-classification-boundary-contract]] (`FE-OC-008`) 소유(§5.6). 본 § 는 adapter 실패 → 해당 kind *매핑*만 명세한다. 어댑터 실패 매핑 (§8.2 · §9.4 grounded): | adapter 조건 | normalized kind | fallback | |---|---|---| | Storage API 부재 / `SecurityError`(private mode·정책 차단) | `STORAGE_UNAVAILABLE` | memory-only (§8.2) | | `setItem` quota 초과 | `STORAGE_QUOTA_EXCEEDED` | 허용 cache evict → memory-only (§8.2) | ### 3. Classification enforcement + `sensitive-forbidden` invariant > **Trace**: D2, D6 → [[raw/project-notes/ca-skeleton-frontend-operational-contract]] `FE-OC-013` · §5.5 · §9.4 · §13.2 · §15.2 · §6.1. > > - **UNSUPPORTED_IMPL_DECISION**: > - 거부 강제 지점(build-time lint vs runtime registry assert vs 둘 다) — hub 미권고. trade-off: lint = 조기 차단, runtime = 동적 등록도 방어. > - 금지 key 이름 패턴(정규식/glob) 구체 — §6.1 은 이름 목록(`SECRET`/`PASSWORD`/`PRIVATE_KEY`/`TOKEN`)만 제시. trade-off: 넓은 패턴 = 오탐, 좁은 패턴 = 누락. > - **OUT_OF_BRANCH_SCOPE**: CSP / secret-scan / `dangerouslySetInnerHTML` 등 브라우저 보안 경계 전반은 [[raw/branch-notes/feature-frontend-browser-security-boundary-contract]] (`FE-OC-019`) 소유(§13.2). 본 § 는 storage 등록 거부만. 강제 규약: - `classification: sensitive-forbidden` 항목은 등록 자체를 거부(§5.5 · §9.4). - key 이름에 `SECRET` / `PASSWORD` / `PRIVATE_KEY` / `TOKEN` 포함 시 거부(§6.1 정책을 storage 에 적용). - negative fixture: `token key registration attempt` → 반드시 실패(§15.2). ### 4. Quota fallback + correctness-critical policy > **Trace**: D5 → [[raw/project-notes/ca-skeleton-frontend-operational-contract]] §5.5 · §9.4 · §8.2. > > - **UNSUPPORTED_IMPL_DECISION**: > - eviction 순서 표기 형식(registry 필드 vs 별도 목록)과 `feature-disable` 시 UX notice 형식 — §5.5·§9.4 는 "허용 순서를 registry 에 기록"만 요구, 형식 미권고. trade-off. 값 등급별 fallback (§9.4 · §5.5 · §8.2 grounded): | value class | quota / unavailable 시 동작 | |---|---| | `public-preference` (예: `COLOR_SCHEME`) | memory fallback, silent — product flow 중단 없음 | | `opaque-cache` (예: `CHUNK_RELOAD_GUARD`) | 허용 cache evict 후 memory; guard 손실 허용 | | correctness-critical (mutation / idempotency record) | fallback 없음 → terminal; 임의 storage fallback 금지 | ## 엣지·실패·의존 - **실패·엣지 경로**: - Storage API 부재 / `SecurityError`(private mode·정책 차단) → `STORAGE_UNAVAILABLE`, memory-only, 대개 silent (§8.2). - `setItem` quota 초과 → `STORAGE_QUOTA_EXCEEDED`, 허용 cache evict 후 memory, feature 영향 시 non-blocking notice (§8.2). - previous `schemaVersion` 데이터 read → migration 또는 discard; discard 시 기본값 재생성 (D3 · §9.2). - `sensitive-forbidden` 값 등록 시도 → 등록 거부(negative fixture, §15.2). - correctness-critical 값의 storage 실패 → fallback 금지, terminal 처리 (D5 · §9.4). - **다른 계약 의존**: - [[raw/branch-notes/feature-frontend-clean-architecture-layering-contract]] (`FE-OC-002`) — `StoragePort` 를 application 이 소유하고 adapter 가 구현하는 layering·port 규약에 의존(§20 Dependency). 이 계약이 바뀌면 port 위치·주입 방식 영향. - [[raw/branch-notes/feature-frontend-error-classification-boundary-contract]] (`FE-OC-008`) — `STORAGE_UNAVAILABLE` / `STORAGE_QUOTA_EXCEEDED` kind 정의를 consume; 본 브랜치는 매핑만. - [[raw/branch-notes/feature-frontend-contract-registry-governance]] (`FE-OC-022`) — 8-registry single-owner·compatibility governance 에 storage snapshot 기여. - [[raw/branch-notes/feature-frontend-contract-compatibility-governance]] (`FE-OC-023`) — schema breaking-change migration·version-bump 판정 위임. - [[raw/branch-notes/feature-sample-feature-slice-contract-fixture]] (`FE-OC-024`) — sample slice 가 storage key 계약을 fixture 로 사용. - [[raw/branch-notes/feature-frontend-auth-session-integration-contract]] (`FE-OC-010`) — token lifecycle 외부 소유; 본 registry 는 token 저장 거부만. - [[raw/branch-notes/feature-frontend-browser-security-boundary-contract]] (`FE-OC-019`) — secret·storage 브라우저 경계 fixture 공동. ## 검증해야 할 주장 > hub 계약은 근거지만 내 프로젝트에서의 동작을 자동 보장하지 않는다. frontend repository 미생성이므로 전부 `needs-confirmation`. 검증 아티팩트는 §20 Measurable completion(namespace/version/classification/quota fallback tests) + §15.2 negative fixture 에서 도출. | Claim | Why uncertain | How to verify | Status | |---|---|---|---| | physical key 규약이 실제 코드에서 raw literal 사용을 0건으로 만든다 | repo·lint 규칙 미구현 | namespace/registry lint + "raw localStorage key literal" negative fixture (§5.1·§15.2) | `needs-confirmation` | | token key 등록 시도가 반드시 실패한다 | 강제 지점(build vs runtime) 미구현 | "token key registration attempt" negative fixture (§15.2) | `needs-confirmation` | | `schemaVersion` mismatch 시 migration-or-discard 가 결정적으로 동작 | migration 경로 미작성 | previous-version fixture + discard/default 재생성 test | `needs-confirmation` | | quota 초과 시 preference = memory fallback, correctness-critical = no fallback | 브라우저 quota 동작 환경차 | quota fallback 결정적 test(mock quota) + correctness-critical no-fallback assertion | `needs-confirmation` | | classification 3분류가 모든 항목에 강제된다 | registry validation 미구현 | 미분류 항목 등록 거부 unit test (FE-GATE-005 registries) | `needs-confirmation` | ## 관심사 커버리지 (coverage-auditor 자동 생성 — 있을 때) | 관심사 | 상태 | owner | 심각도 | 근거 | |---|---|---|---|---| ## 마주친 문제 - 없음 — `/branch-spec` fill 단계 (구현 전). ## 묶음 (이 branch에서 파생된 자료) ## 가져온 프로젝트 계약 | Ref | Owner | 요약 | Branch 적용 | |---|---|---|---| | `FE-GATE-005@1` | [[raw/branch-notes/feature-frontend-test-taxonomy-contract]] | unit 레벨이 실패하면 merge 를 MUST 차단하고 warning 으로 낮추면 안 됨 | import 참조로 적용 | | `FE-OC-002@1` | [[raw/branch-notes/feature-frontend-clean-architecture-layering-contract]] | `domain <- application <- presentation` 의존 방향과 application-owned output port를 MUST 지킴 | import 참조로 적용 | | `FE-OC-010@1` | [[raw/branch-notes/feature-frontend-auth-session-integration-contract]] | skeleton은 session state를 소비하되 token lifecycle을 MUST 소유하지 않음 | import 참조로 적용 | | `FE-OC-019@1` | [[raw/branch-notes/feature-frontend-browser-security-boundary-contract]] | browser bundle에 secret을 넣지 않고 untrusted HTML injection을 기본 금지 | import 참조로 적용 | | `FE-OC-023@1` | [[raw/branch-notes/feature-frontend-contract-compatibility-governance]] | API/config/storage/release schema의 breaking change는 migration 또는 version bump 없이 배포하면 안 됨 | import 참조로 적용 | ### Sub-branches (세부 작업) - 없음 — scaffolding 단계 ### 오류 기록 (이 branch 작업 중 발생) - 없음 — scaffolding 단계 ### 면접 준비 (이 작업에서 나올 수 있는 면접 질문) - 없음 — scaffolding 단계 ### 강의 (이 작업을 위해 학습한 강의) - 없음 — scaffolding 단계 ### job-posting tie-ins (이 작업에서 파생된 글감) - 없음 — scaffolding 단계 ## 관련 일일 노트 - 없음 — scaffolding 단계 ## 완료 후 정리 - PR 링크: TODO - 리뷰 메모: TODO - 머지 결과 / 배포 환경: TODO - **wiki 추출 대상**: 없음 — 전부 `planned` (frontend repository 미생성) - **추출하지 않을 항목**: D1–D6 전체 — 구현·검증 evidence 확보 전까지 추출 금지