29 KiB
title, source_type, status, id, kind, project, work_item, inherits, refines, overrides, depends_on, contract_packet, branch, parent_branch, related_projects, governing_docs, tags, created, target_merge, status_label, contract_packet_sha256, imports
| title | source_type | status | id | kind | project | work_item | inherits | refines | overrides | depends_on | contract_packet | branch | parent_branch | related_projects | governing_docs | tags | created | target_merge | status_label | contract_packet_sha256 | imports | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| branch / feature-frontend-auth-session-integration-contract | branch-note | raw | BR-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-008 | project-work-item | ca-skeleton-frontend-operational-contract | WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-008 |
|
|
1 | feature-frontend-auth-session-integration-contract |
|
|
|
2026-07-18 | in-progress | ec06d05939cbbe7c12c1a581115a07830894c4328344e6a5053c2162df756ab0 |
|
branch: feature-frontend-auth-session-integration-contract
Layer:
raw/branch-notes/— 단일 브랜치의 TODO·결정·진행 기록. 머지/종료 후 verified 결과는/ingest로wiki/projects/에 추출한다.
부모 (필수)
브랜치 계약 패킷
- 생성 시 프로젝트 개정:
1 - 패킷 스키마:
contract_packet: 1 - 완료 조건: AuthSessionPort·bounded 401 replay와 token lifecycle import 금지가 test로 고정된다
상속한 프로젝트 결정
| Decision Ref | Project Summary | Branch Application | Source |
|---|---|---|---|
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-AUTH-BOUNDARY-001@1 |
auth lifecycle은 외부 owner가 소유하고 skeleton은 AuthSessionPort만 소비한다 | token lifecycle 비소유와 bounded session recovery 경계에 적용 | raw/project-notes/ca-skeleton-frontend-operational-contract |
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-PORT-OWNERSHIP-001@1 |
output port interface는 application이 소유하고 adapter가 구현한다 | application-owned AuthSessionPort와 외부 auth adapter 경계에 적용 | raw/project-notes/ca-skeleton-frontend-operational-contract |
브랜치 지역 결정
기존 branch-local 결정은 아래
## Decision Evidence Map / 결정-근거 매핑의 D-row가 소유하며 이 packet에서 복제하지 않는다.
| Decision ID | Decision | Relation | Supporting Claims | Status |
|---|
선언한 예외
| Override ID | Overrides | Reason | Approval | Status |
|---|
목표
이 브랜치는 hub의 FE-OC-010("skeleton은 session state를 소비하되 token lifecycle을 MUST NOT 소유")을 구현 착수 가능한 명세로 내린다. 구체적으로 raw/project-notes/ca-skeleton-frontend-operational-contract FE-D017(auth lifecycle은 외부 owner, skeleton은 AuthSessionPort만 소비)을 근거로, application이 소유하는 AuthSessionPort 경계 · bounded 401 recovery state machine · recovery replay policy · auth 실패 정규화 · no-token-lifecycle 불변식을 planned 청사진으로 확정한다. 또한 이 경계가 라우팅·API client·browser security에 닿는 지점(FE-OC-005·FE-OC-006·FE-OC-019)에 대해 "무엇을 기여하고 무엇을 다른 owner 브랜치에 위임하는지"를 못박는다. token 발급/저장/refresh/rotation/logout은 외부 auth owner(Keycloak 등, raw/project-notes/keycloak-patterns-overview)가 소유하므로 이 노트는 그것을 명명만 하고 명세하지 않는다. 현재 frontend 구현 코드가 없어 모든 항목은 planned다.
- 이슈:
- PR:
범위
포함 범위
AuthSessionPort(application 소유 integration boundary port)의 소비 계약: opaque session state 읽기 + request 전attach(request)+ unauthenticated transition 통지 콜백 (FE-OC-010).- Bounded 401 recovery state machine:
authenticated → recovery-pending → {authenticated | unauthenticated | integration-failed}, logical request당 recovery callback 최대 1회, 두 번째 401은 terminal (hub §7.8). - Recovery 이후 replay policy:
safe1회 replay /keyedmutation은 stable idempotency key + backend replay contract일 때만 1회 /none(unkeyed) mutation은 replay 금지 (hub §7.8·§7.7). - Auth 실패 정규화 기여:
401→AUTH_REQUIRED,403→FORBIDDEN, attach/recovery adapter fault→AUTH_INTEGRATION_FAILURE(hub §8.2·§8.5). - no-token-lifecycle 불변식: skeleton은 token/secret을 browser storage·bundle·env·telemetry·error body에 저장/노출하지 않는다 (
FE-OC-019기여, hub §5.5·§6.1). - session-required route가
AuthSessionPortstate를 UX hint로만 소비하고 backend authorization을 최종 판단으로 두는 규칙 (FE-OC-005기여, hub §9.3).
제외 범위
의도적으로 제외 — 외부 auth owner 또는 다른 owner 브랜치 소유. 여기서는 명명만 하고 명세하지 않는다.
- Token lifecycle 전체 — authorization code exchange, token 저장 위치, access token refresh, refresh token rotation, logout propagation, revocation, IdP redirect detail, backend permission decision. 외부 auth owner 소유(raw/project-notes/keycloak-patterns-overview, hub §7.8 "Skeleton does not own").
- Route registry / navigation guard 메커니즘 (route ID/path/param validation/404/redirect-loop) — raw/branch-notes/feature-routing-navigation-guard-contract 의
FE-OC-005소유. 나는 session-state hint 소비만 기여. - Shared HTTP client transport 및 timeout/abort/retry algorithm — raw/branch-notes/feature-api-client-response-envelope-contract 의
FE-OC-006·FE-OC-009소유. attach·정규화는 그 client 안에서 실행되나 client 뼈대는 그 브랜치가 소유. - Error registry 구조 및 total-function 정규화 — raw/branch-notes/feature-frontend-error-classification-boundary-contract 의
FE-OC-008소유. 나는 3개 auth kind의 기대 매핑만 기여. - Storage registry 스키마 — raw/branch-notes/feature-frontend-storage-registry-contract 의
FE-OC-013소유.AUTH_TOKENforbidden 행의 불변식만 기여. - CSP/header/secret-scan browser boundary 메커니즘 — raw/branch-notes/feature-frontend-browser-security-boundary-contract 의
FE-OC-019소유. 나는 no-token-storage 불변식만 기여. - Telemetry redaction 인프라 — raw/branch-notes/feature-frontend-observability-logging-trace-contract 의
FE-OC-014소유. auth 이벤트의 forbidden attribute(token/principal) 규칙만 기여. - Architecture import-lint 강제 메커니즘 — raw/branch-notes/feature-frontend-architecture-enforcement-lint-contract 의
FE-OC-002소유. 나는 "token lifecycle 심볼은 auth adapter 밖에서 import 금지"라는 검사 대상 불변식만 정의.
근거 (필수, 최소 1개+)
| Source | 정당화하는 결정 |
|---|---|
| raw/project-notes/ca-skeleton-frontend-operational-contract | FE-D017/FE-OC-010 + §4.4(Port ownership) · §7.8(Auth integration boundary) · §8.2(failure matrix) · §5.5·§6.1(browser security) · §9.3(route behavior) — D1~D7의 1차 근거(project decision SSOT) |
| raw/project-notes/keycloak-patterns-overview | 외부 auth owner가 token 발급·저장·refresh·rotation·logout을 소유한다는 external-owner context(§3 token 종류, §2.1 token 위치·인증 강제 주체) — D1(경계 설정)·D6(token 브라우저 미저장)의 배경 근거 |
| raw/official-docs/react-router-official | route composition(<Routes>/<Route>, nested <Outlet/>; REACT-ROUTER-C1/C2)이 session-required route surface가 얹히는 라우팅 모드에 부합 — D7의 라우팅 context. ⚠ navigation guard 보안(REACT-ROUTER-C3 boundary)은 이 자료가 정당화하지 않음 → guard=UX hint는 project decision(D7) |
TODO
AuthSessionPort인터페이스 정의(application 소유): opaque session state getter +attach(request)header/credential callback + unauthenticated-transition callback — 등급:planned- 외부 auth adapter placeholder(
adapters/auth/)가 port 구현, composition-root boot step 6에서 주입 — 등급:planned - shared HTTP client 경유 bounded 401 state machine + replay policy 구현 — 등급:
planned - auth 실패 정규화 매핑(401/403/attach·recovery fault)을 error registry에 기여 — 등급:
planned - no-token-lifecycle import test(architecture fixture): token 저장/refresh 심볼을
adapters/auth/밖에서 import 시 실패 — 등급:planned - session-required route UX hint + backend authz 최종성 e2e(guarded route 403 처리) — 등급:
planned - negative fixtures: attach throw/reject·recovery invalid state →
AUTH_INTEGRATION_FAILURE; unkeyed mutation recovery → no replay — 등급:planned
진행 중 메모
/branch-spec 자체 채움(self-map). frontend 구현 repository 미식별 → 전 항목 planned. hub와 6개 archived official-doc이 유일 SSOT이며, auth lifecycle 근거는 raw/project-notes/keycloak-patterns-overview. 인라인 웹 리서치 0건(hub가 이미 충분).
결정 사항
- 2026-07-19: auth lifecycle은 외부 owner, skeleton은
AuthSessionPort만 소비 / 이유: token 발급·저장·refresh·rotation·logout·revocation은 IdP·backend가 소유하는 관심사이며 client-only SPA가 이를 소유하면 보안·release 경계가 흐려짐 / 검토한 대안: skeleton이 token lifecycle을 직접 소유(독립 auth product) / 근거: raw/project-notes/ca-skeleton-frontend-operational-contractFE-D017·FE-OC-010, raw/project-notes/keycloak-patterns-overview. - 2026-07-19:
AuthSessionPort는 application이 정의 소유, 외부 adapter가 구현, token 문자열을 domain/application model로 반환하지 않고 opaque state + attach callback 형태 우선 / 이유: dependency inversion 유지 + token이 layer 내부로 스며들지 않게 / 검토한 대안: adapter가 직접 token을 반환해 use case가 소비 / 근거: raw/project-notes/ca-skeleton-frontend-operational-contractFE-D010·FE-D009·FE-OC-002·§4.4. - 2026-07-19: 401 recovery는 bounded state machine, logical request당 recovery 1회, 2nd 401 terminal / 이유: recovery loop 차단 / 검토한 대안: 무제한 재인증 재시도 / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract §7.8·
FE-OC-006. - 2026-07-19: recovery replay는
safe1회 /keyed(+backend replay contract) 1회 /none금지 / 이유: duplicate write 방지 / 검토한 대안: 성공 후 무조건 replay / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract §7.8·§7.7·FE-D016. - 2026-07-19: auth 실패 정규화
401→AUTH_REQUIRED/403→FORBIDDEN/ attach·recovery fault→AUTH_INTEGRATION_FAILURE, raw body·token 미노출 / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract §8.2·§8.5·§5.6·FE-OC-008. - 2026-07-19: token/secret은 browser storage·bundle·env·telemetry·error body에 미저장·미노출;
AUTH_TOKENkey forbidden / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract §5.5·§6.1·§5.8·FE-OC-019. - 2026-07-19: session-required route는
AuthSessionPortstate를 UX hint로만 사용, backend authorization이 최종 / 이유: guard를 security control로 오해 방지 / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract §9.3·§7.8·FE-OC-005. (react-routerREACT-ROUTER-C3는 guard를 정당화하지 않음.)
결정-근거 매핑
각 결정과 raw source claim ID의 연결.
FE-D###/§참조는 hub project 링크에 붙인다(consistency hook 규약).
| Decision ID | Decision | 선택 조건 (언제 이 결정 / 언제 대안) | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|---|
| D1 | auth lifecycle은 외부 owner; skeleton은 AuthSessionPort만 소비하고 token 발급/저장/refresh/rotation/logout/revocation을 MUST NOT 소유 (FE-OC-010) |
client-only SPA + 외부 auth owner가 session interface를 제공하는 한 이 결정 유지 / skeleton이 독립 auth product로 scope 변경되면 재검토 (FE-D017 revisit trigger) |
raw/project-notes/ca-skeleton-frontend-operational-contract FE-D017·FE-OC-010; raw/project-notes/keycloak-patterns-overview (외부 owner가 token 종류·위치 소유) |
project-decision |
통합 adapter owner 미정 (FE-Q-006); guard가 security로 오해될 위험 (FE-RISK-005) |
| D2 | AuthSessionPort는 application이 정의 소유, 외부 adapter가 구현, token 문자열을 model로 반환하지 않고 opaque state + attach callback 형태 우선 |
dependency inversion 유지(adapter가 port 구현)하는 한 유지 / port가 domain invariant 자체를 표현해야 하는 concrete case면 재검토 (FE-D010 revisit) |
raw/project-notes/ca-skeleton-frontend-operational-contract FE-D010·FE-D009·FE-OC-002 §4.4 (AuthSessionPort row) |
project-decision |
attach 구현 세부(header supplier vs opaque credential)는 auth owner 결정 — §4.4가 "구현 세부는 auth owner가 정한다"로 유보 |
| D3 | 401 recovery는 bounded state machine(authenticated→recovery-pending→{authenticated|unauthenticated|integration-failed}), logical request당 recovery 콜백 ≤1회, 같은 request의 2nd 401은 terminal AUTH_REQUIRED |
외부 owner가 bounded recovery callback을 제공하면 이 machine 사용 / owner가 recovery를 안 하면 첫 401이 곧 terminal(unauthenticated). recovery loop 금지 | raw/project-notes/ca-skeleton-frontend-operational-contract §7.8 (session state table)·FE-OC-010·FE-OC-006 |
project-decision |
recovery callback의 timeout/bound 세부는 owner 계약에 의존 (FE-Q-006) |
| D4 | recovery 성공 후 replay: safe=같은 context 1회 / keyed=stable idempotency key + active backend replay contract일 때만 1회 / none(unkeyed)=MUST NOT replay(명시적 재시도 요구) |
idempotency mode로 분기 — backend replay contract 없으면 keyed도 replay 금지 |
raw/project-notes/ca-skeleton-frontend-operational-contract §7.8 (replay policy)·§7.7 (idempotency)·FE-D016·FE-OC-006 |
project-decision |
backend replay contract 존재 여부 미확정 (FE-Q-005); unsafe duplicate write 위험 (FE-RISK-006 인접) |
| D5 | auth 실패 정규화: 401→AUTH_REQUIRED, 403→FORBIDDEN, attach/recovery adapter가 throw/reject/invalid state→AUTH_INTEGRATION_FAILURE; raw body·token·principal은 failure·telemetry에 미포함 |
이 3 kind는 stable enum. backend가 다른 auth 상태를 쓰면 error 브랜치가 registry에 추가 후 매핑(재정의 아님) | raw/project-notes/ca-skeleton-frontend-operational-contract §8.2 (failure matrix 3 auth rows)·§8.5 (negative fixtures)·§5.6 (error enum)·FE-OC-008 |
project-decision |
error registry 구조는 error 브랜치 owner — 나는 매핑 값만 기여(경계 이탈 주의) |
| D6 | token/secret은 browser storage·bundle·env·telemetry·error body에 저장/노출 MUST NOT; AUTH_TOKEN storage key는 forbidden(sensitive-forbidden), token 저장은 외부 auth owner만 |
default off(브라우저 token storage 금지) / auth owner가 browser storage를 반드시 써야 하면 별도 threat model + owner evidence 필요(§6.1), skeleton default 아님 | raw/project-notes/ca-skeleton-frontend-operational-contract §5.5 (AUTH_TOKEN forbidden)·§6.1 (secret config)·§5.8 (telemetry forbiddenAttributes)·§8.1·FE-OC-019 |
project-decision |
XSS surface 시 token이 브라우저에 없어야 완화(keycloak note P2A 함정); CSP/scan은 browser-security 브랜치 owner |
| D7 | session-required route는 AuthSessionPort state를 UX hint로만 사용, backend authorization이 최종 권한 판단 — navigation guard는 보안 control이 아님 |
route access가 session-required/integration-defined일 때 hint 적용 / public이면 미적용. 최종 authz는 항상 backend(403→FORBIDDEN) |
raw/project-notes/ca-skeleton-frontend-operational-contract §9.3 (route behavior)·§7.8 ("guard는 UX hint")·FE-OC-005. (react-router REACT-ROUTER-C3는 guard 보안 미정당화) |
project-decision |
guard가 security로 오해 (FE-RISK-005) → e2e에서 403 처리 확인; route registry/redirect는 routing 브랜치 owner |
구현 가이드
전 항목
planned— frontend 코드 없음. 경로는 hub §4.6 Planned directory blueprint / §5.1 registry owner map에서 도출된plannedanchor다.
1. AuthSessionPort 인터페이스 (application 소유)
Trace: D1 + D2 ·
FE-OC-010/FE-OC-002· raw/project-notes/ca-skeleton-frontend-operational-contract §4.4 (Port ownership matrix) · §4.6 (blueprint).
- UNSUPPORTED_IMPL_DECISION: 아래 메서드 명(
getSessionState/attach/onUnauthenticated)과 "header-supplier callback" 표현은 내가 임의 선택 — hub §4.4는 "구현 세부는 auth owner가 정한다"로 shape만 유보(opaque state + attach callback, token 문자열 미반환). trade-off: §7.8의 attach·unauthenticated-transition 어휘를 거울 삼아 되묻기를 줄이되, 최종 signature는 auth owner 계약 확정 시 조정.
| 항목 | planned 값 |
근거 |
|---|---|---|
| Definition owner | application (integration boundary) |
§4.4 |
| Planned 위치 | src/application/ports/auth-session-port.js (정의), src/adapters/auth/ (구현) |
§4.6 |
| Consumer | routing (session hint) + API client interceptor(attach) | §4.4 |
| Input/Output | opaque session state / request-header attach callback (token 문자열 미반환) | §4.4 |
| Failure vocabulary | AuthRequired, AuthIntegrationFailure |
§4.4 |
| 주입 시점 | composition-root boot step 6 (auth integration adapter 주입) | §4.5 |
2. Bounded 401 recovery state machine
Trace: D3 ·
FE-OC-006/FE-OC-010· raw/project-notes/ca-skeleton-frontend-operational-contract §7.8 (session state table). 전부 hub 계약에서 도출.
- UNSUPPORTED_IMPL_DECISION: 없음 — 상태·전이·행동이 §7.8 표에 명시됨. 명시돼 있다는 것은 곧 owner 가 hub §7.8 이라는 뜻이므로 표를 여기에 복제하지 않는다.
state machine 본문은 raw/project-notes/ca-skeleton-frontend-operational-contract §7.8 소유다. 요약 한 줄: authenticated 에서 첫 401 이 bounded recovery 를 1회만 트리거하고, 같은 logical request 의 2번째 401 은 추가 recovery 없이 terminal AUTH_REQUIRED 로 끝난다. 본 브랜치가 소유하는 것은 그 전이를 AuthSessionPort 계약으로 내리는 부분이다.
3. Recovery replay policy
Trace: D4 ·
FE-OC-006/FE-OC-009· raw/project-notes/ca-skeleton-frontend-operational-contract §7.8 (replay policy) · §7.7 (idempotency) ·FE-D016. hub 계약에서 도출.
- UNSUPPORTED_IMPL_DECISION: 없음.
replay policy 본문은 raw/project-notes/ca-skeleton-frontend-operational-contract §7.8 소유다. 요약 한 줄: idempotency mode 별로 recovery 성공 후 replay 는 최대 1회이고 none(unkeyed) 는 replay 금지다.
replay + 일반 retry의 총 시도는 operation registry·test fixture가 추적하며 recovery loop를 만들 수 없다.
4. Auth 실패 정규화 매핑 (error registry 기여)
Trace: D5 ·
FE-OC-008(error 브랜치 owner에 기여) · raw/project-notes/ca-skeleton-frontend-operational-contract §8.2 (failure matrix) · §8.5 (negative fixtures) · §5.6 (error enum).
- UNSUPPORTED_IMPL_DECISION: 없음 — kind/action/telemetry가 §8.2·§5.6에 고정.
- OUT_OF_BRANCH_SCOPE: error registry의 스키마·total-function 정규화 뼈대는 raw/branch-notes/feature-frontend-error-classification-boundary-contract 의
FE-OC-008소유. 나는 아래 3행의 기대 매핑만 제공.
| Trigger (본 브랜치가 발생시키는 지점) | 기대 kind |
|---|---|
HTTP 401 |
AUTH_REQUIRED |
HTTP 403 |
FORBIDDEN |
| attach/recovery adapter throw·reject·invalid state | AUTH_INTEGRATION_FAILURE |
각 kind 의 retry·action·telemetry 규칙은 raw/project-notes/ca-skeleton-frontend-operational-contract §8.2 소유이며 여기에 옮겨 적지 않는다.
5. Browser-security 불변식 (auth) — FE-OC-019 기여
Trace: D6 ·
FE-OC-019(browser-security 브랜치에 기여) · raw/project-notes/ca-skeleton-frontend-operational-contract §5.5 (AUTH_TOKENforbidden) · §6.1 (secret config) · §5.8 (telemetry forbidden) · §8.1 (failure exclusions).
- UNSUPPORTED_IMPL_DECISION: 없음 — 금지 목록이 hub registry/config에 고정.
- OUT_OF_BRANCH_SCOPE: CSP/header/secret-scan lint 메커니즘은 raw/branch-notes/feature-frontend-browser-security-boundary-contract 의
FE-OC-019, storage 스키마는 raw/branch-notes/feature-frontend-storage-registry-contract 의FE-OC-013소유.
- token/secret을
localStorage/sessionStorage/bundle/import.meta.env//config.json에 저장 금지 (§6.1). AUTH_TOKENstorage key =forbidden+sensitive-forbidden, 외부 auth owner만 token 저장 (§5.5).- telemetry
forbiddenAttributes에 token·email·raw URL 포함, auth 이벤트는 route ID만 (§5.8·§8.2). - normalized failure에 raw body·token·authorization header·stack 미포함 (§8.1).
6. no-token-lifecycle 강제 (측정 항목 "no token lifecycle import tests")
Trace: D1 + D6 · raw/project-notes/ca-skeleton-frontend-operational-contract §4.2·§4.3 (dependency matrix) — §20 Measurable completion의 "no token lifecycle import tests".
- UNSUPPORTED_IMPL_DECISION: token-lifecycle 심볼 집합(예:
refresh/rotate/token-store)과 restricted-import glob은 내 임의 제안 — trade-off:adapters/auth/밖에서 token 저장·회전 심볼 import를 차단하는 최소 룰로 시작하되 오탐 시 auth owner 계약에 맞춰 조정.- OUT_OF_BRANCH_SCOPE: import-lint의 실행 메커니즘(dependency-cruiser/ESLint restricted imports fixture)은 raw/branch-notes/feature-frontend-architecture-enforcement-lint-contract 의
FE-OC-002소유. 나는 검사 대상 불변식만 정의.
- 불변식: token 발급·저장·refresh·rotation 심볼은
src/adapters/auth/내부에서만 존재/참조.domain/application/presentation은 이를 import 금지 (§4.3).
7. Route session-integration 접점 — FE-OC-005 기여
Trace: D7 ·
FE-OC-005(routing 브랜치에 기여) · raw/project-notes/ca-skeleton-frontend-operational-contract §9.3 (route behavior) · §7.8 · §5.2 (route access enum).
- UNSUPPORTED_IMPL_DECISION: 없음.
- OUT_OF_BRANCH_SCOPE: route registry 스키마·
access필드·redirect-loop·param validation은 raw/branch-notes/feature-routing-navigation-guard-contract 의FE-OC-005소유. 나는 아래 2 규칙만 기여.
access: session-required/integration-definedroute는AuthSessionPortstate를 UX hint로만 소비 (§9.3·§5.2).- backend authorization result가 최종 권한 판단이며, guard는 이를 대체하지 않는다 (§9.3,
FE-RISK-005).
엣지·실패·의존
- 실패·엣지 경로:
- attach callback이 throw/reject →
AUTH_INTEGRATION_FAILURE, unauthenticated-safe shell (hub §8.5). - recovery가 invalid state 반환 →
AUTH_INTEGRATION_FAILURE. - 같은 logical request의 두 번째
401→ 추가 recovery 없이 terminalAUTH_REQUIRED(loop 금지). none(unkeyed) mutation이 recovery 성공 → replay 금지, 명시적 재시도 요구.- recovery 대기 중 navigation/user abort →
REQUEST_ABORTED, 대기 취소(error event 금지). keyedmutation인데 active backend replay contract 부재 → replay 금지.
- attach callback이 throw/reject →
- 다른 계약 의존 (§20 Dependency + hub §4.3):
- raw/branch-notes/feature-frontend-clean-architecture-layering-contract 의
FE-OC-002(application-owned port + dependency rule)에 의존 — §20의 hard dependency. 이 계약이 바뀌면 port 소유 위치가 흔들림. - raw/branch-notes/feature-api-client-response-envelope-contract 의
FE-OC-006(shared client)에 의존 — attach·정규화·bounded state machine이 그 client 안에서 실행. timeout/abort/retry는 그 계약이 소유. - raw/branch-notes/feature-frontend-error-classification-boundary-contract 의
FE-OC-008(error registry)에 의존 — auth kind 3종이 그 registry에 존재해야 매핑 성립. - raw/branch-notes/feature-routing-navigation-guard-contract 의
FE-OC-005(route registry)에 의존 — session-requiredaccess필드가 존재해야 hint 접점 성립. - raw/branch-notes/feature-frontend-storage-registry-contract 의
FE-OC-013, raw/branch-notes/feature-frontend-browser-security-boundary-contract 의FE-OC-019, raw/branch-notes/feature-frontend-observability-logging-trace-contract 의FE-OC-014에 기여 — 각AUTH_TOKENforbidden·no-token-bundle·telemetry redaction 불변식.
- raw/branch-notes/feature-frontend-clean-architecture-layering-contract 의
검증해야 할 주장
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
AuthSessionPort가 token 문자열을 domain/application model로 반환하지 않는다 |
구현 코드 없음(planned) |
port contract test + no-token-lifecycle import test(§4.6 architecture fixture) | needs-confirmation |
| bounded 401 machine이 recovery loop를 만들지 않는다(request당 recovery ≤1, 2nd 401 terminal) | machine 미구현 | deterministic state-transition test(ClockPort + 주입된 401 시퀀스, §7.8) |
needs-confirmation |
| recovery replay가 unkeyed mutation을 replay하지 않는다 | 미구현 | negative fixture: recovery succeeds for unkeyed mutation → no replay (§8.5) | needs-confirmation |
attach/recovery adapter fault가 AUTH_INTEGRATION_FAILURE로 정규화된다 |
미구현 | negative fixture: attach throw/reject, recovery invalid state (§8.5) | needs-confirmation |
401→AUTH_REQUIRED·403→FORBIDDEN 정규화 + raw body/token 미노출 |
미구현 | error catalog test + redaction assertion(telemetry에 principal/token 없음, §8.2) | needs-confirmation |
| session-required route hint가 backend authz를 대체하지 않는다 | 미구현 | e2e: guarded route에서 backend 403 처리 확인 (FE-RISK-005) |
needs-confirmation |
| skeleton 어디에도 token이 browser storage/bundle에 저장되지 않는다 | 미구현 | secret scan + storage registry test(AUTH_TOKEN forbidden, §5.5·§6.1) |
needs-confirmation |
관심사 커버리지 (coverage-auditor 자동 생성 — 있을 때)
/coverage가 채우는 생성물이며 손으로 유지하지 않는다.
| 관심사 | 상태 | owner | 심각도 | 근거 |
|---|---|---|---|---|
TODO — /coverage 실행 전 |
missing | (없음) | 미평가 | TODO |
마주친 문제
없음 — scaffolding 단계
묶음 (이 branch에서 파생된 자료)
가져온 프로젝트 계약
| Ref | Owner | 요약 | Branch 적용 |
|---|---|---|---|
FE-OC-002@1 |
raw/branch-notes/feature-frontend-clean-architecture-layering-contract | domain <- application <- presentation 의존 방향과 application-owned output port를 MUST 지킴 |
import 참조로 적용 |
FE-OC-005@1 |
raw/branch-notes/feature-routing-navigation-guard-contract | route ID/path/params/access/loading/error owner는 route registry 하나여야 함 | import 참조로 적용 |
FE-OC-006@1 |
raw/branch-notes/feature-api-client-response-envelope-contract | 모든 HTTP는 shared client를 MUST 통과하고 timeout·abort·response parsing을 page에서 구현하면 안 됨 | import 참조로 적용 |
FE-OC-008@1 |
raw/branch-notes/feature-frontend-error-classification-boundary-contract | 모든 failure는 stable frontend error kind로 MUST 정규화하고 raw body·stack을 UI에 노출하면 안 됨 | import 참조로 적용 |
FE-OC-019@1 |
raw/branch-notes/feature-frontend-browser-security-boundary-contract | browser bundle에 secret을 넣지 않고 untrusted HTML injection을 기본 금지 | import 참조로 적용 |
Sub-branches (세부 작업)
없음 — scaffolding 단계
오류 기록 (이 branch 작업 중 발생)
없음 — scaffolding 단계
면접 준비 (이 작업에서 나올 수 있는 면접 질문)
없음 — scaffolding 단계
강의 (이 작업을 위해 학습한 강의)
없음 — scaffolding 단계
job-posting tie-ins (이 작업에서 파생된 글감)
없음 — scaffolding 단계
관련 일일 노트
없음 — scaffolding 단계
완료 후 정리
- PR 링크:
- 리뷰 메모:
- 머지 결과 / 배포 환경:
- wiki 추출 대상 (verified만,
wiki/projects/로만 추출):actually-implemented항목:locally-verified항목:prod-verified항목:
- 추출하지 않을 항목 (planned / documented-only / abandoned):