Files
llm-wiki/docs/superpowers/specs/2026-07-28-ca-skeleton-production-capability-feature-decomposition-design.md
T
DongHyeonkaandClaude Opus 5 7c4e8df248 docs: ca-skeleton production capability feature 분해 설계 + stack 드리프트 정정
ca-tmpl 의 production capability platform 설계(platform 1,346줄 + redis
6,771 + httpclient 7,030 + fileserver 2,467)를 llm-wiki 거버넌스로 편입하는
분해 설계. 2-tier(기술 런타임 / 능력 계약) 모델로 신규 branch 18개를 확정하고,
기존 branch 8건의 주도권을 신규 branch 로 이전하는 절차를 고정.

hub 드리프트 3건 중 2건을 코드 대조로 정정:
- Spring Boot 3.5.14 → 4.0.0 (src/build.gradle:8), DEC-…-STACK-FRAMEWORK-001
  revision 1 → 2 + WI 9행 pin 갱신
- ca-tmpl 경로를 desktop-server-git/clean-architecture-backend-template 로 정정

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 15:09:52 +09:00

51 KiB

CA Skeleton — Production Capability feature 분해 설계

일자 / Date: 2026-07-28 대상 문서 / Target: raw/project-notes/ca-skeleton-operational-contract.md 대상 코드 / Code: /home/donghyeon/workspace/desktop-server-git/clean-architecture-backend-template (이하 ca-tmpl, commit b3add01) 범위 / Scope: ca-tmpl 의 production capability platform 설계를 llm-wiki 거버넌스(project note + branch note)로 편입. 신규 branch 18개 + 기존 branch 8건 주도권 이전 + hub §별 델타. 요청 언어 / User language: ko 상태 / Status: 설계 승인 완료 (2026-07-28), 구현 계획 미작성


0. 이 문서의 지위

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

이 문서 자체는 구현 증거가 아니다. 여기 적힌 모든 계약·기본값·경로는 CLAUDE.md §6 기준 planned 또는 documented-only 다. 예외는 §13 드리프트 정정뿐이며, 그 절의 항목은 ca-tmpl 코드를 직접 읽어 확인한 actually-implemented 사실이다(각 행에 파일 경로 명시).


1. 배경과 조사 결과

1.1 사용자 요청

요청의 핵심은 두 가지다.

  1. adapter 가 운영 환경에 바로 못 쓴다. redis, fileserver, httpclient, messaging, notification, objectstorage, jpa, mongo, graphql, grpc, web, websocket 이 seam 수준에 머물러 있다.
  2. cross-cutting 이 PostgreSQL 에 묶여 있다. outbox·idempotency·lock·rate limit·cache 가 DB 한 곳으로만 해결되게 설계되어 있다. outbox 는 CDC 가 필요할 수 있고, lock 은 Redis 가 필요할 수 있으며, rate limit 은 정책에 따라 알고리즘을 갈아끼울 수 있어야 한다.

여기에 교육적 요구가 붙는다 — "자주 쓰는 함수를 기본 제공해서, 그걸 쓰다가 부딪히는 문제를 개발자가 알 수 있게" 하는 것. 사용자가 든 예가 정확히 그 성격이다: Redis 는 싱글스레드인데 왜 동시성 문제가 생기는가, 그리고 그 답으로서의 Lua.

명시적 비요구: 대기업 기술 블로그식 "이런 상황에서 이만큼 개선했다" 는 수치 서사는 만들지 않는다.

1.2 조사에서 드러난 사실 — 설계는 이미 있다

ca-tmpl 저장소에 요청 내용을 이미 판정한 설계가 존재한다.

문서 줄 수 다루는 범위
docs/superpowers/specs/2026-07-26-production-capability-platform-design.md 1,346 capability platform 전체 — provider 선택, readiness R0~R3, Redis role, 실패정책, outbox/CDC, Kafka, Mongo, HTTP, notification, object storage, file server, web/GraphQL/gRPC/WebSocket, 관측, Gradle, CI, 6-phase 로드맵
.../2026-07-26-redis-production-capability-design.md 6,771 Redis 심화 — role/deployment isolation, key model, payload/codec, atomic program registry, command·transaction·pipeline 의미, cache contract, rate limit, idempotency, lease/fencing, session, 관측, topology CI
.../2026-07-27-httpclient-production-capability-design.md 7,030 HTTP client 심화 — total deadline, retry/circuit breaker 순서, pool, DNS, SSRF, TLS/mTLS, 관측
.../2026-07-26-fileserver-production-capability-design.md 2,467 file server 심화 — staged publish, guarantee 모델, provider 3종, CSV safety, quota/retention

구현도 진행 중이다. commit b3add01 "feat: redis, fileserver, httpclient 런타임 시점 구현 추가" 기준으로 adapter/outbound/cache-redis 43개 파일(Lua program executor·catalog·descriptor, atomic primitives, key builder/namespace/digest, command admission, envelope codec 포함), httpclient 38개, fileserver 16개가 존재한다.

1.3 그런데 llm-wiki 에는 이 작업이 없다

hub 를 grep 한 결과:

  • §8.0 Work Item Registry 60행(WI-…-001~059) 중 capability platform 관련 행 0개
  • §6.1 안정 결정 레지스트리 25행 중 관련 결정 0개
  • §35 Implementation Coverage Checklist 에 redis/httpclient/fileserver 는 각각 cache-consistency·outbound-http-client-baseline·file-resource-handling 행으로 [~](결정 박힘, 코드 없음) 로 표기 — 실제로는 코드가 들어갔다
  • mongo / graphql / grpc / websocket / session-store / CDC / Kafka consumer 는 row 자체가 없음

코드가 문서를 앞질렀고, 그 사이 간극이 hub 의 거버넌스 밖에 있다. 이 설계의 목적은 그 간극을 branch-note 단위 소유권으로 덮는 것이다.

1.4 이 확장이 없으면 발생하는 실패

계약은 아래 실패를 막기 위해 존재한다(hub §26 Universal Acceptance Gate 질문 1).

실패 설명
거짓 R2 표기 seam 하나만 있는 capability 를 문서·startup 진단이 "production ready" 로 보고한다. 운영자가 없는 보증을 믿는다.
보증 등급 혼동 Redis idempotency claim + JDBC 업무 write 를 SAME_STORE_TRANSACTIONAL 로 오인해 crash 후 중복 실행이 발생한다.
CDC 전환 불가 가변 status row outbox 에 Debezium Outbox Event Router 를 붙일 수 없다는 사실을 전환 시점에 발견한다.
알고리즘 고착 rate limit 이 fixed window 하나뿐이라 burst 허용·평균율 제어가 필요한 정책을 표현할 수 없다.
조용한 경합 GET → 판단 → INCR → EXPIRE 를 원자적이라 믿고 작성해 카운터가 어긋나거나 TTL 이 유실된다. Redis 가 싱글스레드라는 사실이 이 오해를 강화한다.
캐시가 결함을 삼킴 codec·프로그래밍 결함이 blanket catch(Exception) fail-open 을 통과해 평범한 cache miss 로 위장된다.
세션 부재로 다중 파드 불가 JWT STATELESS 고정이라 세션 기반 인증이 필요한 순간 다중 파드에서 인증 상태를 공유할 수 없다.
비고정 fencing lease 기반 lock 을 correctness 보증으로 오용해 failover 후 stale holder 가 write 한다.
전체 객체 메모리 적재 object storage 가 byte[] 전용이라 대용량 업로드/다운로드가 힙을 그대로 소비한다.
미검증 활성화 bean 이름 존재만으로 multi-instance 안전을 보고해, 실제 분산 구현 없이 안전하다고 판정한다.

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

선택 결정 근거
활성화 자세 optional Gradle 모듈 + capability flag default OFF, 모듈 내부는 완제품 core 는 지금처럼 가볍고, 안 쓰는 프로젝트는 의존성·기동시간 부담 0. frontend hub 의 FE-D026(capability default OFF)과 같은 자세
분해 단위 2-tier(기술 런타임 / 능력 계약) + 신규 branch 18개 Redis 심화 설계 6,771줄이 7개 관심사에 걸쳐 있어 branch 1개로 불가. 기술×능력으로 쪼개면 연결·키·코덱 결정이 5곳에 중복
Stack core stack 유지 + Optional Adapter Stack Matrix 신설 §34 의 "단일 stack 커밋" 정신을 각 optional 축에서도 유지(축마다 구현체 1개)
제공 깊이 port + adapter + 연산 툴킷 + 함정 게이트 사용자 요구의 교육적 성격을 계약으로 고정. unsafe recipe 와 atomic 대체를 문서·테스트에서 쌍으로 제시
기존 branch 충돌 주도권을 신규 branch 로 이전하고 동기화 사용자 지시(2026-07-28). Single-Owner 유지, 기존 branch 는 포인터만 보존

3. 범위

3.1 In scope

  • 신규 branch 18개의 소유 관심사 · Work Item · 결정 · 커버리지 행 확정
  • 기존 branch 8건의 주도권 이전(handover) 대상 D-row 와 동기화 절차 확정
  • hub §1·§2·§11·§25·§34·§35·§6.1·§8.0·§24·§31.1·§29 의 델타 확정
  • Capability Readiness Model(R0~R3) 과 capability card 필수 항목의 hub 편입
  • 능력별 실패정책 매트릭스(hub §11 Optional Adapters 절 대체)
  • ca-tmpl 코드 대조로 확인된 드리프트 3건 정정

3.2 Out of scope

사용자 제약을 문서에 못박는 항목이다. hub §2 "하지 않는 것" 에 추가한다.

  • 각 branch 의 심층 명세 — 본 문서는 소유권·경계·hub 델타까지다. 각 branch 의 D-row 와 §구현 가이드는 /branch-spec 이 별도 세션에서 채운다.
  • 성능 수치·개선 서사 — "무엇에서 무엇으로 개선" 형태의 측정 주장은 만들지 않는다. capacity 입력(키 크기, 연산율, 보존기간, 재시도 증폭)만 계약한다.
  • 도메인 로직 — 로그인 플로우, 결제 흐름, 재고 차감 같은 도메인 형태 레시피는 만들지 않는다. capability pack 은 안전한 저장·전송·조율을 제공하고 use case 는 적용 프로젝트가 쓴다.
  • vendor 선택 — 관리형 Redis/Kafka/Mongo 제공자, CDN, push 서비스, KMS 제공자.
  • exactly-once 주장 — DB 와 broker 를 걸친 exactly-once, Redis lock 의 strong correctness 는 코드·문서 어디에도 쓰지 않는다.
  • ca-tmpl 코드 작성 — 본 문서는 llm-wiki 거버넌스 산출물이다. 코드는 ca-tmpl repo 의 plan 이 소유한다.

3.3 Non-goal

  • 신규 capability 를 기본 활성화하는 것. 기본값은 전부 비활성이며 feature-capability-provider-selection-contract 의 gate 가 이를 증명한다.
  • 기존 60개 Work Item 의 의미 변경. §5 의 8건만 주도권이 이동하고 나머지는 그대로다.
  • llm-wiki 를 ca-tmpl 심층 설계의 사본으로 만드는 것. branch-note 는 결정과 근거를 소유하고, 구현 세부는 ca-tmpl 설계를 reference 한다.

4. 분해 — 2-tier 모델

4.1 왜 2-tier 인가

기술 1개 = branch 1개로 두면 Redis 가 무너진다. Redis 는 cache·rate limit·session·idempotency·lock 5개 능력과 role·key·codec·script 4개 기반이 한 기술 안에 겹쳐 있다.

반대로 능력×기술로 쪼개면(cache-redis, lock-redis, session-redis…) 연결 설정·키 스키마·직렬화·스크립트 카탈로그 결정이 5개 branch 에 중복된다. rules/consistency-contract.md 의 Single-Owner 위반이고, Redis 클라이언트 하나 바꿀 때 5곳을 고쳐야 한다.

그래서 축을 둘로 나눈다.

Tier T (기술 런타임)  — 클라이언트 · 연결 · 키 · 코덱 · 스크립트 · health · 보안
        ↑ provider 로 사용됨
Tier C (능력 계약)    — provider-neutral port · 보증(guarantee) · 실패정책 · 전략 registry
        ↑ 활성화 판정을 위임
Tier P (플랫폼)       — capability descriptor · provider 선택 · readiness · capability card

Redis 는 Tier T 2개 branch 가 소유하고, Tier C 5개 branch 에 provider 로만 등장한다. 중복 0.

4.2 신규 branch 18개

# Tier branch slug 소유 관심사 Work Item
1 P feature-capability-provider-selection-contract capability descriptor, provider: disabled|<id> 활성화 SSOT, readiness R0~R3, capability card 필수 항목, fail-fast 토폴로지 검증, 능력별 실패정책 매트릭스 WI-…-060
2 T feature-redis-runtime-role-isolation-contract cache/coordination/session 3-role 분리, 연결·TLS·ACL·pool·topology refresh, key model(namespace·digest·hash tag·version·bounds), payload envelope·codec·compatibility, role 별 health WI-…-061
3 T feature-redis-atomic-program-catalog-contract Lua/Function 카탈로그, ScriptDescriptor, EVALSHA + NOSCRIPT 재적재, bounded execution 규칙, unsafe multi-command recipe ↔ atomic 대체 쌍, golden vector WI-…-062
4 T feature-kafka-producer-runtime-contract acknowledgement-aware send, acks=all + idempotent producer, bounded delivery timeout, key/partition 순서, 압축·배치 한계, TLS/SASL, 스키마 serializer, graceful flush WI-…-063
5 T feature-kafka-consumer-inbox-contract 신규 adapter:inbound:messaging-kafka leaf, manual ack, handler/schema allowlist, bounded concurrency·queue, pause/resume, rebalance·max.poll, retry topic·DLT, InboxStorePort WI-…-064
6 T feature-mongo-runtime-baseline-contract URI/topology/TLS/credential/timeout/pool 설정, read preference·read/write concern, replica-set 트랜잭션 요구 검증, index manifest·drift·migration, change stream resume token·oplog window WI-…-065
7 T feature-objectstorage-streaming-lifecycle-contract streaming upload/download·range read, head/metadata, checksum 계약, 조건부 write(ETag/version), presigned, multipart start/complete/abort·orphan 회수, SSE/KMS, staged finalization WI-…-066
8 C feature-cache-strategy-registry-contract CacheRegionPort 결과 모델(HIT/MISS/NEGATIVE_HIT/DEGRADED), positive·negative·soft·hard TTL, jitter, single-flight, 전략 registry(cache-aside 기본 / SWR·refresh-ahead·probabilistic·L1L2·분산 stampede opt-in), 메모리 정책 소유 경계(maxmemory-policy = 배포 소유), 대량 무효화(SCAN+UNLINK) WI-…-067
9 C feature-edge-rate-limit-policy-registry-contract transport-edge 계약(RateLimitRequestRateLimitDecision), policyId registry, 알고리즘 6종 교체(fixed window / sliding counter / token bucket / sliding log / GCRA / leaky bucket), 키 차원(environment+policyId+tenant?+subjectHash), decision 기반 Retry-After, emergency fallback WI-…-068
10 C feature-session-auth-mode-contract jwt | redis-session 배타 프로파일, session 생성 정책·CSRF·쿠키 속성·session id 회전, 로그아웃 서버 세션 삭제, serializer 버전·허용 타입, 다중 파드 read/touch/expiry/logout 계약, rolling deploy 호환 WI-…-069
11 C feature-idempotency-ownership-protocol-contract owner token 기반 claim/renew/complete/release, 실행 lease 와 replay TTL 분리, ACQUIRED|REPLAY|IN_PROGRESS|FINGERPRINT_MISMATCH 결과, guarantee 3종(REQUEST_REPLAY/SAME_STORE_TRANSACTIONAL/EXTERNAL_IDEMPOTENCY), provider 공통 계약 suite WI-…-070
12 C feature-fenced-lock-coordination-contract FencedLockPort + leader election·semaphore·work claim 분리, fencing counter 와 lease 분리, 보호 자원의 high watermark 거부 규칙, lease-lost 신호, blind DEL·무한 watchdog 금지 WI-…-071
13 C feature-outbox-dispatch-mode-contract outbox_event(불변) + outbox_delivery(polling 전용 상태) 분리, dispatch-mode: disabled|polling|cdc 배타, aggregate sequence 순서, claim owner token, Debezium Outbox Event Router 매핑, 파티션 보존·정리 조건, 모드 전환 runbook WI-…-072
14 X feature-graphql-production-baseline-contract operation·field authorization, parser 문자/토큰/깊이 한계, cost/complexity 계측, persisted query allowlist, DataLoader·N+1 계약, cursor connection, error extension 정제, introspection 정책, 스키마 breaking-change gate WI-…-073
15 X feature-grpc-production-baseline-contract proto 생성·버전 규약·호환성 검사, TLS/mTLS, service/method authorization interceptor, 필수 deadline·cancellation 전파, 메시지·메타데이터 크기 한계, retry 허용 status, keepalive, streaming backpressure, health·drain, reflection 정책 WI-…-074
16 X feature-websocket-cluster-delivery-contract 인증된 handshake·재인증, destination 별 subscribe/send authorization, origin·frame 한계, heartbeat·idle timeout, bounded executor/queue·drop 정책, sequence/resume, broker relay 또는 durable 이벤트 브리지, 도메인 이벤트 직결 금지 WI-…-075
17 X feature-read-consistency-query-contract ReadConsistency(STRONG/READ_YOUR_WRITES/BOUNDED_STALENESS/EVENTUAL), opaque·서명·버전 cursor, page/sort/filter allowlist, primary/replica 라우팅 근거, projection checkpoint·lag, TransactionPort.inRead() 의 의미 고정 WI-…-076
18 X feature-notification-durable-delivery-contract best-effort ↔ durable 인터페이스 분리, 논리 template ID·버전·locale, provider quota·bounded retry, dedupe·provider idempotency key, delivery receipt·bounce·suppression, PII-safe 로그·큐 암호화·보존 WI-…-077

4.3 요청 항목과의 대응

사용자가 든 항목 흡수한 branch
redis (전반) #2 #3 기반 + #8 #9 #10 #11 #12 가 provider 로 소비
rate limit 알고리즘 교체 #9
Lua 로 동시성 해결 / 기본 제공 함수 #3 (카탈로그·descriptor·unsafe↔atomic 쌍) + #8 #9 #11 #12 (각 능력의 원자 연산)
캐시 전략·메모리 관리·maxmemory-policy·스탬피드 #8 (+ 배포 소유 경계는 #2)
redis session store / JWT → session 전환 #10
outbox → CDC #13
lock → Redis·Kafka 등 DB 밖 #12 (+ 기존 feature-distributed-lock-contract 는 efficiency mutex 유지)
idempotency → DB 밖 #11
messaging #4 #5
objectstorage #7
mongo #6
graphql / grpc / websocket #14 #15 #16
query (PostgreSQL 종속) #17
notification #18
observability 각 branch 의 계약에 포함(bounded metric·span·health). 신규 branch 없음 — 기존 feature-metrics-alerting-contract·feature-distributed-tracing-contract 가 owner
fileserver / httpclient / jpa / web 신규 branch 없음. 기존 owner 개정 — §5.3 참조

4.4 신규 branch 를 만들지 않는 4개 표면

이 판단은 설계의 일부이며 hub §25 SSOT Owner Map 에 근거를 남긴다.

  • fileserver — ca-tmpl 심층 설계 2,467줄이 feature-file-resource-handling-contract 의 범위와 정확히 겹친다. 신규 branch 는 DUPLICATE_CONTRACT_OWNER 다. 기존 branch 를 개정하고 심층 설계를 근거로 pin 한다.
  • httpclient — 마찬가지로 feature-outbound-http-client-baseline(D=11)이 owner다. total deadline·decorator 순서 정정은 그 branch 의 D-row 개정이다.
  • jpa/pool — pool sizing·timeout 계층은 feature-database-connection-pool-contract, 실패 분류는 feature-persistence-failure-baseline 이 owner다. replica 라우팅만 #17 로 이전한다.
  • web — trusted proxy chain, request deadline, graceful drain, multipart 한계는 각각 feature-security-operational-baseline·feature-runtime-health-lifecycle-contract·feature-boundary-validation-mapping-contract 가 이미 소유한다. edge rate limit 만 #9 로 이전한다.

5. 주도권 이전 (Ownership Handover)

사용자 지시: "기존 브랜치와 충돌하는 부분은 주도권을 새로 생성하는 브랜치로 넘기고 동기화."

5.1 이전 대상 8건

# 이전 관심사 기존 owner 이전 대상 D-row 신규 owner
H1 idempotency 저장소·프로토콜·TTL·fingerprint feature-rate-limit-idempotency-contract D2, D3, D6, D7, D8, D9 #11 feature-idempotency-ownership-protocol-contract
H2 rate limit 키·분산·알고리즘 feature-rate-limit-idempotency-contract D4, D5 #9 feature-edge-rate-limit-policy-registry-contract
H3 cache 전략(stampede·TTL·직렬화·negative·cluster) feature-cache-consistency-contract D3, D4, D5, D6, D7, D8, D9 #8 feature-cache-strategy-registry-contract
H4 cache 실패 등급(fail-open 경계) feature-cachestore-multi-backend-router D1, D2, D3 #8 (실패 등급) + #2 (backend 연결)
H5 correctness lock · fencing feature-distributed-lock-contract D6 #12 feature-fenced-lock-coordination-contract
H6 outbox 행 모델 · dispatch 전략 feature-domain-event-outbox-contract 행 상태 머신 관련 D-row 전량 #13 feature-outbox-dispatch-mode-contract
H7 session · 인증 모드 feature-security-operational-baseline session 관련 D-row #10 feature-session-auth-mode-contract
H8 multi-instance 활성화 검증 feature-background-job-async-contract (+ feature-runtime-health-lifecycle-contractStartupSafetyValidator 언급) scheduler/outbox lock 활성화 판정 #1 feature-capability-provider-selection-contract

2026-07-28 controller 메시지에서는 충돌 6건으로 보고했으나, 코드 대조 결과 H4(cache 실패 등급)와 H8(multi-instance 검증)이 추가되어 8건이다.

5.2 이전 절차 (branch 당 6단계)

rules/consistency-contract.md 의 Single-Owner + Reference-Only 를 그대로 적용한다.

  1. 신규 branch 가 owner 로 D-row 를 재작성한다. 이전이 아니라 재판정이다 — 기존 결정을 그대로 복사하지 않고, ca-tmpl 심층 설계와 코드 사실을 근거로 다시 판단한다.
  2. 기존 branch 의 해당 D-row 는 본문을 제거하고 포인터만 남긴다. 형식: | D<n> | **superseded → [[raw/branch-notes/<신규 slug>]] D<m>** — <1줄 요약> | … |. 재진술 금지.
  3. 기존 branch 의 §구현 가이드에서 이관 대상 cell 을 제거한다. CLAUDE.md §15.5 R3 OUT_OF_BRANCH_SCOPE. 이관 history 는 해당 branch 의 §Audit & Findings 에 보존한다.
  4. hub §25 SSOT Owner Map 의 owner 열을 교체하고, consumers/producers 열에 기존 branch 를 남긴다.
  5. 기존 branch 의 status_label 을 갱신한다. 관심사를 전량 이전한 branch(H1+H2 로 사실상 전부 이전되는 feature-rate-limit-idempotency-contract)는 delegated 로 표기하고, 부분 이전 branch 는 in-progress 를 유지한다.
  6. /sync 를 실행해 역참조를 전파한다. wiki_consistency_check.py 가 owner 교체 후 남은 재진술을 잡는다.

5.3 이전이 아니라 개정만 하는 3건

주도권은 그대로 두고 내용만 코드 사실에 맞춘다.

branch 개정 사유 근거
feature-outbound-http-client-baseline globalCallTimeout 이 실행 중 호출을 취소하지 않고 다음 재시도 진입 여부만 판정한다. decorator 순서가 문서와 다르다 ca-tmpl httpclient 심층 설계 §3, §15, §20
feature-file-resource-handling-contract 전체 파일 버퍼링 + 비원자 덮어쓰기. staged publish·fsync·rename 프로토콜로 개정 ca-tmpl fileserver 심층 설계 §11, §12
feature-integration-adapter-templates "optional adapter 는 disabled env 가 기본" 을 capability descriptor 모델로 대체 #1 이 활성화 SSOT 를 소유하게 되므로 template branch 는 소비자로 강등

6. Capability Readiness Model (hub 신설 §)

#1 branch 가 owner다. hub 에 §36 Capability Readiness Model 로 신설한다(§35 뒤에 붙인다 — 중간 삽입은 기존 절 참조를 어긋나게 한다).

6.1 Readiness 4단계

등급 의미 필요한 증거 CLAUDE.md §6 등급 대응
R0 Contract 타입·seam·placeholder 만 존재 unit test + architecture boundary test planned 또는 documented-only
R1 Local 단일 로컬 프로세스/로컬 서비스에서 동작 집중 통합 test + 한계 문서화 actually-implemented (partial)
R2 Production baseline 실제 provider, 안전한 설정, 실패 의미, health, metric, 보안, graceful lifecycle provider 계약 test + 실서비스 통합 + 동시성/실패 test + runbook locally-verified
R3 Scale/HA cluster·failover·rolling upgrade 검증 topology test + 호환 매트릭스 + 복구/용량 runbook prod-verified

금지: R0 seam 을 R2 provider 로 표기하는 것. 문서·startup 진단·capability card 모두에 적용된다. 이 금지는 hub §2 "하지 않는 것" 에 추가한다.

6.2 Capability card 필수 항목

각 R2 이상 capability 는 아래를 갖춘 card 를 branch-note 에 보유한다.

owner 모듈 · semantic port
provider ID 와 readiness 등급
보증(guarantee)과 명시적 비보증(non-guarantee)
기본 실패 정책과 허용되는 override
필요한 토폴로지 · 영속/축출 정책
설정 키와 secret
liveness/readiness 영향
bounded cardinality metric 과 trace span
적합/부적합 지침 · 비용 모델 · 자원 한계
흔한 unsafe recipe · 그것이 만드는 경합/실패 · 안전한 대체
집중/통합/실패 test 명령
rolling upgrade · 복구 노트
runbook 링크

"흔한 unsafe recipe ↔ 안전한 대체" 항목이 사용자 요구의 교육적 부분을 계약으로 고정하는 장치다. provider 는 card 가 주장하는 동시성·실패 의미를 증명하는 경합 test 를 통과해야 그 보증을 card 에 쓸 수 있다.

6.3 활성화 SSOT

provider: disabled | <provider-id>          # 선택 가능한 capability
dispatch-mode: disabled | polling | cdc     # 모드 축이 있는 capability (outbox)
enabled: true | false                       # provider·mode 축이 없는 leaf 에만

규범:

  • matchIfMissing=true, classpath 존재, local provider 기본값이 production capability 를 활성화해서는 안 된다.
  • 미사용 capability 는 연결·백그라운드 워커·스키마·암묵적 런타임 동작을 만들지 않는다.
  • legacy flag 를 한시적으로 유지하는 경우, SSOT 와의 불일치는 startup 오류다.
  • 활성화 판정은 bean 이름이 아니라 typed descriptor 로 한다(§13 드리프트 D3 참조).

7. 결정 레지스트리 신규 15행

hub 는 §25(legacy default)와 §6.1(DEC-…, 현행 SSOT)을 쌍으로 유지한다. 신규 결정은 §6.1 에 넣고, §25 Blocking Defaults 에는 활성화 자세 1행만 추가한다.

Summary 셀은 소비 branch 의 상속 표와 문자열이 정확히 일치해야 한다. 아래가 SSOT 다. 조사 앞 공백 없음(기존 §6.1 행 표기와 동일).

Decision ID Rev Domain Decision Summary Status Evidence
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-CAPABILITY-SELECTION-001 1 capability-selection production capability는 available by default이고 inactive by default이며 활성화는 typed descriptor 기반 provider 선택으로만 이뤄진다 active ca-tmpl platform 설계 §7
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-CAPABILITY-READINESS-001 1 capability-readiness 모든 capability는 R0~R3 readiness 등급과 capability card를 가지며 R0 seam을 R2 provider로 표기하지 않는다 active ca-tmpl platform 설계 §6
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-REDIS-ROLE-001 1 redis-role Redis는 cache·coordination·session 3개 role로 분리하고 key prefix나 DB number를 격리 수단으로 쓰지 않는다 active ca-tmpl redis 설계 §10
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-REDIS-PROGRAM-001 1 redis-program 다단계 read-decide-write는 버전 있는 atomic program으로만 제공하고 각 helper는 unsafe recipe와 안전한 대체를 쌍으로 문서화하며 경합 test로 증명한다 active ca-tmpl redis 설계 §13, §14
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-CACHE-STRATEGY-001 1 cache-strategy cache 기본 전략은 cache-aside와 after-commit 무효화이고 SWR·refresh-ahead·L1L2·분산 stampede 억제는 opt-in이며 maxmemory-policy는 배포 설정이 소유한다 conditional-default ca-tmpl platform 설계 §8.4
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-CACHE-FAILURE-001 1 cache-failure optional cache의 backend 실패는 fail open이고 codec·프로그래밍 결함은 해당 연산을 fail closed로 처리하며 cache miss로 위장하지 않는다 active ca-tmpl platform 설계 §7
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RATE-LIMIT-ALGORITHM-001 1 rate-limit-algorithm rate limit은 policyId 단위로 알고리즘을 선택하고 fixed window·sliding counter·token bucket을 기본 제공하며 sliding log·GCRA·leaky bucket은 opt-in이다 conditional-default ca-tmpl platform 설계 §8.5
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-SESSION-MODE-001 1 session-mode 인증 모드는 jwt와 redis-session이 배타이고 jwt가 default이며 redis-session은 전용 session role과 CSRF·쿠키·회전·다중 파드 계약을 동반한다 conditional-default ca-tmpl platform 설계 §8.6
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-IDEMPOTENCY-OWNERSHIP-001 1 idempotency-ownership idempotency는 owner token 기반 claim·renew·complete·release 프로토콜을 쓰고 실행 lease와 replay TTL을 분리하며 보증 등급을 명시한다 active ca-tmpl platform 설계 §9
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-LOCK-FENCING-001 1 lock-fencing DistributedLockPort는 efficiency mutex로 고정하고 correctness가 필요한 경로는 별도 FencedLockPort와 보호 자원의 high watermark 거부로만 보장한다 active ca-tmpl platform 설계 §10
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-OUTBOX-DISPATCH-001 1 outbox-dispatch outbox는 불변 event 행과 polling 전용 delivery 행을 분리하고 dispatch 모드는 polling과 cdc가 배타이며 append는 업무 write와 같은 트랜잭션에 남는다 active ca-tmpl platform 설계 §11.1, §11.2
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-DELIVERY-SEMANTICS-001 1 delivery-semantics end-to-end 메시징 보증은 at-least-once 전달과 멱등 consumer·inbox로 표현하고 DB와 broker를 걸친 exactly-once를 주장하지 않는다 active ca-tmpl platform 설계 §11.4
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MONGO-BASELINE-001 1 mongo-baseline MongoDB는 read preference·read concern·write concern을 명시하고 트랜잭션과 change stream은 replica-set 요건 검증을 통과할 때만 활성화한다 conditional-default ca-tmpl platform 설계 §12.3
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-READ-CONSISTENCY-001 1 read-consistency 조회는 ReadConsistency를 명시하고 replica 라우팅은 그 정책과 요청 문맥으로 결정하며 TransactionPort.inRead는 replica 사용을 뜻하지 않는다 active ca-tmpl platform 설계 §12.1
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-OPTIONAL-ADAPTER-001 1 stack-optional-adapter optional adapter stack은 축마다 구현체 하나를 고정하고 core stack과 분리된 matrix로 관리한다 active §34 Optional Adapter Stack Matrix

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

7.1 §25 Blocking Defaults 신규 1행

항목 기본 결정 SSOT branch 실패 조건
capability 활성화 production capability 는 모듈로 제공하되 기본 비활성. 활성화는 typed descriptor 기반 provider 선택으로만 feature-capability-provider-selection-contract classpath 존재·matchIfMissing·local provider 기본값으로 capability 가 활성화되거나, bean 이름 존재만으로 보증을 주장

8. Work Item Registry 신규 18행 (hub §8.0)

Applies Decisions 는 §7 의 신규 DEC 와 기존 DEC 를 섞어 pin 한다. Dependencies 는 Tier 순서(P → T → C → X)를 따른다.

Work Item ID branch slug 완료 조건 (측정가능) Applies Decisions Dependencies
WI-…-060 feature-capability-provider-selection-contract capability descriptor·provider 선택·readiness 등급 검증 test 가 통과하고 bean 이름 기반 판정이 제거된다 CAPABILITY-SELECTION-001@1, CAPABILITY-READINESS-001@1 -
WI-…-061 feature-redis-runtime-role-isolation-contract 3-role 연결·키·코덱·health 계약 test 와 incompatible co-location 거부 test 가 통과한다 REDIS-ROLE-001@1, STACK-OPTIONAL-ADAPTER-001@1 060
WI-…-062 feature-redis-atomic-program-catalog-contract program descriptor·golden vector·NOSCRIPT 재적재 test 와 unsafe recipe 경합 재현 test 가 통과한다 REDIS-PROGRAM-001@1 061
WI-…-063 feature-kafka-producer-runtime-contract acknowledgement·delivery timeout·순서·보안 설정 계약 test 가 통과한다 DELIVERY-SEMANTICS-001@1, EVENT-BROKER-001@1 060
WI-…-064 feature-kafka-consumer-inbox-contract inbound leaf 등록·manual ack·rebalance·DLT·inbox 멱등 계약 test 가 통과한다 DELIVERY-SEMANTICS-001@1, IDEMPOTENCY-OWNERSHIP-001@1 063, 070
WI-…-065 feature-mongo-runtime-baseline-contract concern·index manifest·replica-set 트랜잭션·change stream checkpoint test 가 통과한다 MONGO-BASELINE-001@1, STACK-OPTIONAL-ADAPTER-001@1 060
WI-…-066 feature-objectstorage-streaming-lifecycle-contract streaming·multipart·presigned·checksum·orphan 회수 계약 test 가 통과한다 CAPABILITY-READINESS-001@1, MODULE-LAYOUT-001@1 060
WI-…-067 feature-cache-strategy-registry-contract 전략 registry·TTL 4종·single-flight·실패 등급 분리 test 가 통과한다 CACHE-STRATEGY-001@1, CACHE-FAILURE-001@1 061
WI-…-068 feature-edge-rate-limit-policy-registry-contract 알고리즘 6종 교체·policy registry·decision 기반 Retry-After·fallback test 가 통과한다 RATE-LIMIT-ALGORITHM-001@1, RATE-LIMIT-001@1 062
WI-…-069 feature-session-auth-mode-contract 배타 인증 모드·CSRF·쿠키·회전·다중 파드 세션 계약 test 가 통과한다 SESSION-MODE-001@1 061
WI-…-070 feature-idempotency-ownership-protocol-contract owner token 프로토콜·lease 분리·보증 등급별 provider 공통 계약 test 가 통과한다 IDEMPOTENCY-OWNERSHIP-001@1, IDEMPOTENCY-001@1 060
WI-…-071 feature-fenced-lock-coordination-contract fencing token 단조성·high watermark 거부·lease-lost 신호 test 가 통과한다 LOCK-FENCING-001@1, SCHEDULER-LOCK-001@1 060
WI-…-072 feature-outbox-dispatch-mode-contract event/delivery 분리·모드 배타·CDC 라우팅·파티션 정리 조건 test 가 통과한다 OUTBOX-DISPATCH-001@1, DELIVERY-SEMANTICS-001@1 063
WI-…-073 feature-graphql-production-baseline-contract 깊이·복잡도·persisted query·field authorization·스키마 gate test 가 통과한다 CAPABILITY-READINESS-001@1, API-VERSIONING-001@1 060
WI-…-074 feature-grpc-production-baseline-contract proto 호환·TLS/mTLS·deadline·크기 한계·drain test 가 통과한다 CAPABILITY-READINESS-001@1, STACK-OPTIONAL-ADAPTER-001@1 060
WI-…-075 feature-websocket-cluster-delivery-contract handshake 인증·destination authorization·bounded queue·cluster 전달 test 가 통과한다 CAPABILITY-READINESS-001@1 060, 063
WI-…-076 feature-read-consistency-query-contract ReadConsistency·cursor·replica 라우팅·projection lag 계약 test 가 통과한다 READ-CONSISTENCY-001@1, TRANSACTION-001@1 060
WI-…-077 feature-notification-durable-delivery-contract durable/best-effort 분리·template 버전·receipt·dedupe 계약 test 가 통과한다 CAPABILITY-READINESS-001@1, RESILIENCE-001@1 072

ID 는 문서 가독성을 위해 WI-…-0NN 으로 축약했다. hub 에 옮길 때 전체 형식 WI-CA-SKELETON-OPERATIONAL-CONTRACT-0NN 로 쓴다. Applies DecisionsDEC-… 접두사도 마찬가지다. Status 는 전 행 planned.


9. 능력별 실패 정책 매트릭스 (hub §11 대체)

hub §11 의 ### Optional Adapters 절(3줄)을 아래 표로 대체한다. 전역 fail-open 이나 전역 fail-closed 는 없다.

Capability 기본 실패 정책 근거
optional cache (backend 실패) fail open — source 로 fallback, degraded 결과와 metric 노출 캐시 부재는 정확성 손실이 아니다
cache codec·프로그래밍 결함 fail closed (해당 연산) — 손상 항목 축출/격리, miss 로 위장 금지 결함을 miss 로 숨기면 영구 오염
security session store fail closed — 인증 상태를 지어내지 않는다 인증은 추측 대상이 아니다
keyed mutation idempotency fail closed 중복 write 방지가 목적
strict rate limit (남용·비용 경계) fail closed 또는 의도적으로 제한된 local emergency limiter 무제한 통과는 경계의 부재
availability 지향 rate limit 명시적 local emergency fallback, 조용한 무제한 통과 금지 저하는 허용, 은폐는 불가
efficiency lock 선언된 use case 정책에 따라 실패 또는 계속 중복 작업 방지가 목적
fenced correctness lock 획득·lease 상실 시 보호 작업 중단 중복 결과 차단이 목적
outbox append 업무 트랜잭션 롤백 append 는 업무 write 와 원자
outbox dispatcher 장애 write 는 계속 축적, lag·backlog 알림 전달 지연은 업무 차단 사유가 아니다
best-effort notification·message 명시적 fail open 이름과 계약에 best-effort 명시
durable notification·message outbox/inbox + 재시도 + 종단 실패 경로 유실 불가 경로

hub §7 Non-Retryable 기준의 cache unavailable when degradation is allowed 행은 이 표의 첫 두 행으로 세분화된다.


10. Optional Adapter Stack Matrix (hub §34)

§34 의 core Stack Matrix 는 그대로 유지하고(단 §13 D1 정정 적용), 그 아래에 새 표를 붙인다. "축마다 구현체 하나" 라는 §34 의 단일 stack 정신을 optional 축에도 적용한다.

Capability 축 선택 버전 상태 비고
Redis client Lettuce (Spring Data Redis) Spring Boot BOM transitive 도입 예정 LettuceRedisRuntime 이 이미 존재하나 SDK 의존성 추가는 Phase 1
Session store Spring Session Data Redis Spring Boot BOM transitive 도입 예정 redis-session 모드 활성 시에만
Kafka client spring-kafka Spring Boot BOM transitive 도입 예정 producer 먼저, consumer 는 신규 inbound leaf
CDC Debezium + Kafka Connect 배포 자산 도입 예정 애플리케이션 의존성 아님. connector 는 외부 배포
MongoDB Spring Data MongoDB Spring Boot BOM transitive opt-in 설정만 존재 replica-set 요건 검증 필요
Object storage AWS SDK v2 2.30.0 (ext.awsSdkVersion) 존재 모듈 scope BOM import
gRPC io.grpc + protobuf 1.68.1 (ext.grpcVersion) 존재 Boot BOM 미관리 → 모듈 scope BOM
GraphQL Spring for GraphQL Spring Boot BOM transitive 최소 구현 존재 production gate 미도입
Resilience Resilience4j Spring Boot BOM 외 존재 core 결정(RESILIENCE-001) 유지
통합 test Testcontainers (+ Toxiproxy) test scope 부분 존재 TESTCONTAINERS-001 정책 상속

Out of Stack (optional 축) — 명시적 거부:

  • lock/coordination: Redisson 을 lock provider 기본으로 삼지 않는다. Spring Integration LockRegistry 계열(JDBC/Redis)이 기본이며 Redisson 은 대안. ZooKeeper·etcd·Consul 은 범위 밖.
  • messaging: RabbitMQ·Pulsar·ActiveMQ 는 범위 밖. Redis Streams 는 Kafka 대체재가 아니라 후속 소규모 provider 후보.
  • cache: Ehcache·Hazelcast·Infinispan 은 범위 밖. L1 은 Caffeine.
  • search: Elasticsearch·OpenSearch 는 범위 밖(hub §35 F 영역 유지).

§34 의 "Stack 변경 절차" 4단계는 optional matrix 에도 그대로 적용된다.


11. hub 델타 요약

§ 변경 성격
§1 목표 마지막 문단에 capability platform 자세 1문단 추가 개정
§2 하지 않는 것 (a) "Kafka/Redis/Slack/Google Email을 기본 dependency로 무겁게 탑재하지 않음" → "available by default, inactive by default. 미사용 capability 는 연결·워커·스키마·런타임 부작용 0" 로 개정 (b) "R0 seam 을 R2 로 표기" 금지 1행 추가 (c) §3.2 Out of scope 6항 추가 개정
§7 cache unavailable 행을 §9 매트릭스로 위임하는 포인터 추가 개정
§11 ### Optional Adapters 3줄 → §9 실패정책 매트릭스로 대체 대체
§25 Blocking Defaults 1행 추가(§7.1) 추가
§25 SSOT Owner Map 신규 18행 + 이전 8건 owner 교체 추가·개정
§6.1 DEC 신규 15행(§7) 추가
§8.0 WI 신규 18행(§8) + 주도권 이전에 따른 기존 7행 갱신(008, 016, 024, 025, 038, 049, 052) 추가·개정
§24 branch 링크 18개 추가 추가
§31.1 GENERATED 목록 + 수기 목록에 18개 추가, 총계 갱신 추가
§34 core matrix 1행 정정(§13 D1) + Optional Adapter Stack Matrix 신설(§10) 정정·추가
§35 신규 18행 + 상태 승급 3건 + (없음) 해소 4건 + 분포 요약 갱신 추가·개정
§36 신설 Capability Readiness Model + capability card(§6) 신설
§29 ca-tmpl 심층 설계 4건을 근거 인덱스에 등록 추가
헤더(25번 줄) 경로 표기 규약 정정(§13 D2) 정정
§11 금지 목록 "R0 seam 을 R2 로 표기" 금지 1행 추가 추가

11.1 §35 커버리지 체크리스트 델타

상태 승급 3건 (코드 대조 결과):

기존 행 현재 표기 정정 표기 근거
Cache consistency [~] [*] adapter/outbound/cache-redis 43개 파일(test 13)
Outbound HTTP resilience [~] [*] adapter/outbound/httpclient 38개 파일(test 15)
File / Resource handling [~] [*] adapter/outbound/fileserver 16개 파일(test 5)

(없음) 해소 4건: MongoDB / GraphQL / gRPC / WebSocket 은 각각 신규 branch row 로 대체된다.

신규 18행: §4.2 의 branch 를 [ ](미시작) 로 등록하되, Redis foundation 2건은 [*](부분 구현) — Lua executor·catalog·descriptor·atomic primitives·key builder 가 이미 존재한다.


12. 신규 branch 생성 순서와 방법

18개를 한 세션에서 채우지 않는다. 각 branch 는 /branch <slug> 로 스캐폴딩한 뒤 /branch-spec 이 별도 세션에서 D-row 를 채운다.

1차 (플랫폼 — 나머지 전부가 이 결정을 상속):   #1
2차 (기술 런타임 — 능력의 provider):           #2 #3 → #4 #5, #6, #7
3차 (능력 계약 — 주도권 이전 대상 포함):        #8 #9 #10 #11 #12 #13
4차 (전송·조회):                              #14 #15 #16 #17 #18

각 차수 진입 조건:

  • 1차 완료 전 2차 착수 금지. capability descriptor 모양이 확정되지 않으면 모든 provider branch 가 활성화 계약을 각자 발명한다.
  • #2 완료 전 #3 착수 금지. key model·codec 이 program descriptor 의 입력이다.
  • 3차 각 branch 착수 시 §5.2 이전 절차 6단계를 함께 수행한다. 신규 D-row 작성과 기존 branch 포인터 치환을 같은 작업 단위로 묶지 않으면 두 owner 가 공존하는 기간이 생긴다.

각 branch-note 는 templates/branch-note-template.md 를 따르고, hub §24 의 Work Item Contract 7필드(Decision / Allowed / Forbidden / Required registry update / Required contract test / Failure condition / Canonical extraction target)를 채운다.


13. 드리프트 정정 (코드 근거)

이 절의 항목은 설계 제안이 아니라 ca-tmpl 코드를 읽어 확인한 사실이다. hub 를 코드에 맞춰 정정한다.

# 드리프트 hub 현재 값 코드 사실 근거 파일
D1 Spring Boot 버전 §34 Stack Matrix Framework = Spring Boot 3.5.14, §6.1 DEC-…-STACK-FRAMEWORK-001 동일 4.0.0 src/build.gradle:8id 'org.springframework.boot' version '4.0.0' apply false
D2 ca-tmpl 경로 헤더 25번 줄 /home/donghyeon/workspace/ca-tmpl/ /home/donghyeon/workspace/desktop-server-git/clean-architecture-backend-template/ 저장소 위치 확인(2026-07-28)
D3 multi-instance 활성화 판정 §6.1 SCHEDULER-LOCK-001 이 "DB advisory lock 사용" 만 규정 bean 이름 문자열 목록으로 판정 — distributedLockProvider, cacheStampedeProtection, outboxLeaderElection src/app-bootstrap/.../runtime/StartupSafetyValidator.java:23-27

D1 의 파급이 크다. §34 는 "모든 branch 가 상속하는 stack SSOT" 이고 §34 의 Stack 변경 절차는 sibling branch 영향 평가를 요구한다. 정정 시 grep -rn "project §34" raw/branch-notes/feature-*.md 로 영향 branch 를 식별한다. Spring Boot 4.0.0 은 3.5.x 대비 baseline 이 달라지므로, 각 branch 의 프레임워크 의존 결정(특히 security·web·data 계열)은 재평가 대상이다.

D2 는 llm-wiki 전역 35개 파일이 옛 경로를 참조한다(grep -rn "workspace/ca-tmpl" --include="*.md"). 본 설계의 실행 범위는 hub 1개 파일로 한정하고, 나머지는 별도 정리 작업으로 둔다 — 일괄 치환은 wiki/log.md 의 과거 실행 기록까지 바꾸게 되어 이력 왜곡이다.

D3 는 #1 branch 의 첫 번째 D-row 가 될 사실이다. StartupSafetyValidator 가 bean 이름만 확인하므로, 그 이름을 가진 아무 bean 이나 존재하면 multi-instance 안전으로 판정된다.

13.1 이번에 정정하지 않는 것

항목 이유
llm-wiki ↔ llm-wiki-private 미러 분기 ca-tmpl AGENTS.md:72,79 는 branch-note 캡처 대상을 llm-wiki-private 로 지정한다. 두 저장소의 hub 파일은 2026-07-28 기준 동일하다. 어느 쪽을 정본으로 둘지는 사용자 결정 사항이며, 본 설계는 작업이 지시된 llm-wiki 를 대상으로 한다. 두 저장소 동기화는 별도 작업으로 남긴다.
wiki/projects/ca-tmpl/ 16개 canonical 문서 본 설계는 raw layer(project note + branch note)만 다룬다. canonical 승급은 branch 완료 후 /ingest 경로다.

14. 근거 자료

14.1 프로젝트 내부 설계 (등급: internal-design-doc)

공식 문서 아님. 인용 시 "ca-tmpl 프로젝트 설계 결정" 으로 표기하고 외부 best practice 로 격상하지 않는다.

문서 본 설계에서 인용한 절
ca-tmpl 2026-07-26-production-capability-platform-design.md §3(현재 상태), §6(readiness), §7(provider 선택·실패정책), §8(Redis), §9(idempotency), §10(lock), §11(outbox/Kafka), §12(query/persistence), §13(outbound), §14(inbound), §15(관측)
ca-tmpl 2026-07-26-redis-production-capability-design.md §10(role), §11(key), §12(payload), §13(program registry), §14(command 의미), §15(cache contract)
ca-tmpl 2026-07-27-httpclient-production-capability-design.md §3, §15(total deadline), §17~§20(retry/CB/순서)
ca-tmpl 2026-07-26-fileserver-production-capability-design.md §11(상태 머신), §12(staged publish), §13(guarantee)

14.2 코드 사실 (등급: actually-implemented)

사실 파일
모듈 19개 고정 검증 src/settings.gradle (expectedModuleCount = 19), src/config/architecture/modules.json
RateLimitAlgorithmFIXED_WINDOW 단일, transport edge 소재 src/adapter/inbound/web/.../ratelimit/RateLimitAlgorithm.java
CacheStoreOptional<String> get / void put 만 노출 src/adapter/outbound/cache-redis/.../CacheStore.java
CacheRegionPort 등 신규 cache 계약이 이미 도입됨 src/application-core/.../application/cache/ (7개 파일)
IdempotencyStorePort 에 owner token 없음 (complete(scope, …) / discard(scope)) src/application-core/.../idempotency/IdempotencyStorePort.java:24-42
DistributedLockPort.tryAcquire(key, waitTime, leaseTtl) — fencing 없음 src/application-core/.../lock/DistributedLockPort.java:29
outbox 행이 PENDING/IN_FLIGHT/PUBLISHED/DEAD 로 가변 src/application-core/.../outbox/OutboxEventStatus.java
ObjectStoragePortbyte[] 전용 src/application-core/.../storage/ObjectStoragePort.java:29,38
관리 엔드포인트가 STATELESS + CSRF 비활성 src/app-bootstrap/.../management/security/ManagementSecurityConfig.java:26-27
Redis Lua 실행 기반 존재 src/adapter/outbound/cache-redis/.../RedisLuaProgramExecutor.java, RedisProgramCatalog.java, RedisProgramDescriptor.java, RedisAtomicPrimitives.java

14.3 외부 공식 문서 (branch-note Sources 시드)

각 branch 의 /branch-spec 단계에서 verbatim 인용과 함께 raw/official-docs/ 로 수집한다. 본 설계는 링크만 예약하며, 아직 인용 근거로 쓰지 않는다.

branch 1차 수집 대상
#2 #3 Redis 공식 — eval-intro(스크립팅·원자성), key eviction, distributed locks patterns / Spring Data Redis scripting
#8 Redis eviction / AWS ElastiCache caching strategies(기존 raw/official-docs/cache-aside-vs-write-through-aws.md 재사용)
#9 Redis rate-limiter use case
#10 Spring Session Redis API
#12 Redis distributed locks(fencing 서술) / 기존 raw/official-docs/cache-redisson-rlock-vs-setnx.md
#13 Debezium Outbox Event Router
#4 #5 Kafka design(delivery semantics·transactions), producer configs
#6 MongoDB read concern / write concern / change streams
#7 Amazon S3 object integrity
#14 GraphQL Java limits
#15 gRPC deadlines / retry
#16 Spring WebSocket broker relay
#17 (기존 feature-application-query-bypass-contract Sources 상속)

15. 검증과 게이트

15.1 본 설계 실행의 완료 조건

hub 편집이 아래를 모두 만족해야 완료다.

  1. /lint 통과 — canonical 우회·status 미달 파생·registry 누락 검사
  2. /sync 통과 — 이전 8건의 owner 교체 후 재진술 0
  3. hub §35 의 분포 요약 숫자가 실제 row 수와 일치
  4. 신규 18개 slug 가 §8.0 / §24 / §31.1 / §35 / §25 다섯 곳에 모두 등장
  5. §7 의 Decision Summary 문자열이 §6.1 과 각 branch-note 상속 표에서 완전 일치(조사 앞 공백 포함)
  6. §13 드리프트 3건이 코드 근거 링크와 함께 정정됨

15.2 각 신규 branch 의 승급 게이트

hub §26 Universal Acceptance Gate 10문항 + §23 promotion contract 6필드를 그대로 적용한다. 추가로 capability branch 는 아래 2개를 더 만족해야 documented-only 를 벗어난다.

  • capability card 의 보증(guarantee)과 비보증(non-guarantee)이 둘 다 작성되어 있다.
  • card 가 주장하는 동시성·실패 의미를 증명하는 경합 test 이름이 명시되어 있다.

16. 미해결 질문

# 질문 영향 처리
Q1 llm-wiki 와 llm-wiki-private 중 어느 쪽이 정본인가 18개 branch-note 를 어디에 만들지 사용자 결정 필요. 본 설계는 llm-wiki 기준
Q2 Spring Boot 4.0.0 전환이 기존 46개 branch 결정에 미치는 영향 security·web·data 계열 결정 재평가 §13 D1 정정 후 grep -rn "project §34" 로 영향 평가 별도 수행
Q3 feature-rate-limit-idempotency-contractdelegated 로 두는가, 폐기하는가 WI-016 의 처리 본 설계는 delegated 유지(WI-016 은 두 신규 WI 로 대체 표기). 폐기는 branch 이력 손실
Q4 Kafka inbound leaf 추가로 모듈이 19 → 20 이 된다 settings.gradle:23expectedModuleCount = 19 하드코딩 #5 branch 의 D-row 로 처리. 모듈 registry migration 절차 필요
Q5 adapter:outbound:cache-redis 모듈명이 Redis 기술 전반을 담게 된다 이름과 책임 불일치 ca-tmpl 설계가 rename 을 별도 승인 대상으로 유예. #2 branch 가 이름 유지 여부를 결정