Files
llm-wiki/raw/branch-notes/feature-frontend-auth-session-integration-contract.md
T

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
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-AUTH-BOUNDARY-001@1
DEC-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-PORT-OWNERSHIP-001@1
WI-CA-SKELETON-FRONTEND-OPERATIONAL-CONTRACT-002
1 feature-frontend-auth-session-integration-contract
ca-skeleton-frontend
ca-skeleton
raw/project-notes/ca-skeleton-frontend-operational-contract.md
branch
ca-skeleton
frontend
auth
security
javascript
oauth2
2026-07-18 in-progress ec06d05939cbbe7c12c1a581115a07830894c4328344e6a5053c2162df756ab0
FE-OC-002@1
FE-OC-005@1
FE-OC-006@1
FE-OC-008@1
FE-OC-019@1

branch: feature-frontend-auth-session-integration-contract

Layer: raw/branch-notes/ — 단일 브랜치의 TODO·결정·진행 기록. 머지/종료 후 verified 결과는 /ingestwiki/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: safe 1회 replay / keyed mutation은 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가 AuthSessionPort state를 UX hint로만 소비하고 backend authorization을 최종 판단으로 두는 규칙 (FE-OC-005 기여, hub §9.3).

제외 범위

의도적으로 제외 — 외부 auth owner 또는 다른 owner 브랜치 소유. 여기서는 명명만 하고 명세하지 않는다.

근거 (필수, 최소 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-contract FE-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-contract FE-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는 safe 1회 / 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_TOKEN key forbidden / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract §5.5·§6.1·§5.8·FE-OC-019.
  • 2026-07-19: session-required route는 AuthSessionPort state를 UX hint로만 사용, backend authorization이 최종 / 이유: guard를 security control로 오해 방지 / 근거: raw/project-notes/ca-skeleton-frontend-operational-contract §9.3·§7.8·FE-OC-005. (react-router REACT-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에서 도출된 planned anchor다.

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).

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_TOKEN forbidden) · §6.1 (secret config) · §5.8 (telemetry forbidden) · §8.1 (failure exclusions).

  • token/secret을 localStorage/sessionStorage/bundle/import.meta.env//config.json에 저장 금지 (§6.1).
  • AUTH_TOKEN storage 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-contractFE-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).

  • access: session-required/integration-defined route는 AuthSessionPort state를 UX hint로만 소비 (§9.3·§5.2).
  • backend authorization result가 최종 권한 판단이며, guard는 이를 대체하지 않는다 (§9.3, FE-RISK-005).

엣지·실패·의존

검증해야 할 주장

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):