Files
llm-wiki/raw/project-notes/ca-skeleton-operational-contract.md
T

234 KiB
Raw Blame History

title, source_type, status, confidence, tags, related_projects, last_reviewed, diagrams, architecture_review, status_label, project_revision, url, semantic_surface_exclusions
title source_type status confidence tags related_projects last_reviewed diagrams architecture_review status_label project_revision url semantic_surface_exclusions
CA Skeleton Operational Contract project-note raw unknown
project-note
ca-skeleton
ca-tmpl
clean-architecture
observability
error-handling
ca-skeleton
ca-tmpl
2026-05-26
ca-skeleton/architecture-modules-2026-05-26
ca-skeleton/architecture-runtime-topology-2026-05-26
ca-skeleton/sequence-request-flow-mermaid
ca-skeleton/sequence-outbox-publish-mermaid
ca-skeleton/sequence-tenant-context-mermaid
2026-05-26 active 1
artifact-registry|legacy hub has no project-local Artifact Registry; harness/source/typed-contracts.json is authoritative until migration
contract-gate-registry|legacy hub has no project-local Contract/Gate Registry; harness/source/typed-contracts.json is authoritative until migration
flow-stage-registry|legacy hub has no project-local Flow/Stage Registry; harness/source/typed-contracts.json is authoritative until migration

CA Skeleton Operational Contract

이 문서는 도메인/비즈니스 로직을 제거한 Clean Architecture skeleton에서 기본 제공해야 하는 운영 실패/관측성/경계 검증 계약의 canonical SSOT입니다. Phase A/B/C1/D1/D2 모두 2026-05-22 완료. 본 문서는 ca-tmpl 운영 계약의 canonical SSOT. Phase C2는 2026-05-27 feature-skeleton-package-blueprint-contract 범위에서 일부 진입: package/module blueprint와 architecture guardrail은 별도 ca-tmpl git repo에서 local verification 완료. 나머지 registry/generated constants/sample fixture/outbox/security 등 Phase C2 항목은 계속 pending.

경로 표기 규약: 본 문서가 reference하는 ca-tmpl/docs/... 경로는 별도 git repo (/home/donghyeon/workspace/ca-tmpl/)의 docs/ 디렉터리를 의미. registry yaml과 runbook stub은 운영 artifact라 LLM Wiki(wiki/projects/)에 두지 않고 ca-tmpl repo에 위치. 본 canonical contract 문서만 LLM Wiki에 잔존.

자세한 phase 진척과 closure는 §28 Review Remediation Ledger 참조.


1. 목표

이 skeleton의 목표는 많은 adapter를 미리 구현하는 것이 아닙니다.

어떤 adapter를 붙여도
같은 방식으로 실패를 분류하고
같은 방식으로 로그와 trace를 남기며
같은 방식으로 응답을 반환하고
같은 테스트 계약으로 깨짐을 감지하는 구조

도메인/비즈니스 로직은 제거합니다. 대신 운영 실패 분류, 경계 validation, mapper, structured response, structured logging, distributed tracing, env-driven configuration, repository access permission, adapter failure contract, API schema, transaction/concurrency, runtime lifecycle, sample domain fixture, domain onboarding, use case/port contract, domain modeling guardrails, business rule validation, domain event/outbox, metrics/alerting, secret/config source, management endpoint security, tenant policy, file/resource handling, cache consistency, background job/async, API compatibility, CI quality gate, build/release supply chain, container runtime, operational runbook, data retention/privacy, developer experience 기준을 기본 제공해야 합니다.

2. 하지 않는 것

  • ProblemDetail 사용 안 함. 자체 structured envelope 응답을 사용.
  • 특정 비즈니스 도메인 예외를 기본 제공하지 않음.
  • 단, skeleton 계약 검증을 위한 sample domain fixture는 둠. 이 sample은 비즈니스 기능이 아니라 contract 검증 도구임.
  • Kafka/Redis/Slack/Google Email을 기본 dependency로 무겁게 탑재하지 않음.
  • raw exception, SQL, token, request/response body를 클라이언트 응답이나 기본 로그에 노출하지 않음.
  • wiki/interview/, wiki/portfolio/, wiki/blog/로 직접 파생하지 않음. 먼저 wiki/projects/ canonical 문서로 승급.

3. Structured API Response Contract

성공 응답:

success: true
data: <payload>
meta.requestId
meta.traceId
meta.correlationId

실패 응답:

success: false
error.code
error.category
error.message
error.retryable
error.details
meta.requestId
meta.traceId
meta.correlationId

error.details는 validation field error처럼 클라이언트가 수정할 수 있는 안전한 정보만 담습니다.

클라이언트 응답에 금지:

  • exception class name
  • stack trace
  • SQL / SQL parameter
  • token / password / secret
  • raw request body
  • raw response body
  • upstream raw error body
  • internal dependency endpoint

4. Boundary Validation & Mapper Contract

모든 경계는 mapper와 validation 책임을 가집니다.

request -> application

  • HTTP DTO validation 수행.
  • malformed body, missing parameter, type mismatch, unsupported media type 분류.
  • request DTO를 application command/query로 변환하는 mapper 필수.
  • controller에서 domain object 직접 생성 금지.

application -> domain

  • command/query invariant 검증.
  • use case policy 검증.
  • repository access capability 검증.
  • domain에는 normalized input만 전달.

domain -> application

  • domain invariant violation은 application error로 번역.
  • domain object를 response DTO로 직접 노출 금지.

application -> response

  • response mapper에서 public field만 노출.
  • nullable / empty / default value 정책을 mapper 책임으로 둠.
  • internal diagnostic context를 response payload에 섞지 않음.

filter / interceptor

  • requestId, traceId, correlationId 생성/전파.
  • MDC key 초기화와 정리.
  • response header propagation.
  • filter에서 business error를 생성하지 않음.

5. Exception Ownership Contract

presentation

  • Spring MVC 기본 예외 처리.
  • validation, authentication, authorization, access denied 처리.
  • unreadable body, unsupported media type, no handler, type mismatch 처리.
  • client-safe structured response 생성.

application

  • use case policy violation 처리.
  • repository access permission violation 처리.
  • external dependency result 해석.
  • domain exception을 application error로 번역.

domain

  • business invariant violation만 표현.
  • infrastructure exception, HTTP/JPA/Security exception을 알지 않음.

infrastructure

  • DB/JPA, outbound HTTP, cache, messaging, notification provider 예외를 operational error로 변환.
  • raw exception이 presentation까지 새면 contract 위반.

6. Operational Error Category

기본 category (error.category enum — foundation SSOT, 10개, raw/branch-notes/feature-operational-error-observability-foundation D10):

  • VALIDATION
  • AUTH
  • AUTHZ
  • NOT_FOUND
  • CONFLICT
  • RATE_LIMIT
  • TRANSIENT_DEPENDENCY
  • PERMANENT_DEPENDENCY
  • DATA_INTEGRITY
  • INTERNAL

2026-06-01 정합 (F1): 이전 13-category 목록(AUTHENTICATION/AUTHORIZATION/PERSISTENCE/DEPENDENCY/SECURITY/MESSAGE/CACHE/NOTIFICATION 포함)은 stale 이었다. §21 Error Registry 요약(L810/L814) 의 resolved 10-enum 및 foundation branch D10 과 §8 Structured Log 가 모두 10-enum 을 사용하므로 본 §6 을 정합. 명명 매핑(§21 L814, "Phase A 4차 audit Conflict 13 해소"): AUTHENTICATION→AUTH, AUTHORIZATION→AUTHZ, PERSISTENCE→{DATA_INTEGRITY, TRANSIENT_DEPENDENCY}, DEPENDENCY→{TRANSIENT_DEPENDENCY, PERMANENT_DEPENDENCY}, SECURITY→AUTHZ(repository access denial), MESSAGE/CACHE/NOTIFICATION→TRANSIENT_DEPENDENCY(transient infra failure). per-code 의 정확한 category 는 ca-tmpl/docs/registries/error-codes.yaml 가 authoritative (§21 category 분포: TRANSIENT_DEPENDENCY 15 · AUTH 8 · INTERNAL 8 · VALIDATION 6 · CONFLICT 4 · AUTHZ 3 · DATA_INTEGRITY 3 · RATE_LIMIT 1 · PERMANENT_DEPENDENCY 1 · NOT_FOUND 0).

기본 code (각 code 의 category 는 위 10-enum + error-codes.yaml authoritative — 아래 목록의 옛 category 명은 위 매핑으로 해석):

  • VALIDATION_FAILED
  • MAPPING_FAILED (2026-05-29 추가, VALIDATION category — mapper-internal 실패: record canonical constructor IllegalArgumentException wrap, MapStruct NPE, ACL normalization 실패. MappingException 으로 명시적 wrap 필수. 도출: raw/branch-notes/feature-boundary-validation-mapping-contract D10 + §구현 가이드 §3)
  • BATCH_PARTIAL_FAILURE (2026-05-29 추가, VALIDATION category — bulk endpoint 의 부분/전체 실패. HTTP 200 + envelope.success=false. BulkEnvelope.partial(...) 라우팅. 도출: raw/branch-notes/feature-boundary-validation-mapping-contract D14 + §구현 가이드 §1)
  • AUTHENTICATION_FAILED
  • AUTHORIZATION_FAILED
  • RESOURCE_NOT_FOUND
  • CONFLICT
  • DATA_INTEGRITY_VIOLATION
  • DB_UNAVAILABLE
  • DB_QUERY_FAILED
  • EXTERNAL_BAD_REQUEST
  • EXTERNAL_UNAUTHORIZED
  • EXTERNAL_FORBIDDEN
  • EXTERNAL_TIMEOUT
  • EXTERNAL_UNAVAILABLE
  • MESSAGE_PUBLISH_FAILED
  • CACHE_UNAVAILABLE
  • NOTIFICATION_SEND_FAILED
  • REPOSITORY_ACCESS_DENIED
  • INTERNAL_ERROR

§6 는 ca-tmpl 전체 error vocabulary 의 SSOT. 개별 branch-note (예: feature-boundary-validation-mapping-contract) 의 §구현 가이드 §1 (error code 표) 은 본 §6 의 부분 view. branch-note §구현 가이드에 본 §6 vocabulary 외의 도메인 특화 code (USER_NOT_FOUND, POST_NOT_FOUND, DUPLICATE_EMAIL 등) 작성 금지 — ca-tmpl skeleton 은 도메인 없이 만드는 영역이므로 도메인 특화 code 는 별도 프로젝트가 도메인 얹을 때 추가하는 영역.

코드 vocabulary 추가 절차: 신규 code (예: MAPPING_FAILED, BATCH_PARTIAL_FAILURE) 는 본 §6 등록이 선행 조건. branch-note 의 §구현 가이드에서 code 를 사용 하기 전에 본 §6 에 추가. 등록 전 사용 시 branch-note 에 provisional 표시.

7. Non-Retryable 기준

retryable 기본값:

  • DB connection unavailable
  • transient lock failure
  • query timeout
  • upstream 429
  • upstream 5xx
  • connect timeout
  • read timeout
  • DNS temporary failure
  • message publish temporary failure
  • cache unavailable when degradation is allowed

non-retryable 기본값:

  • validation failure
  • authentication failure
  • authorization failure
  • malformed token
  • invalid signature
  • unsupported media type
  • deterministic conflict
  • upstream 400 caused by invalid request
  • repository access permission violation

8. Structured Log Contract

JSON log 기본 필드:

  • timestamp
  • level
  • app
  • profile
  • logger
  • message
  • traceId
  • requestId
  • correlationId
  • operation
  • error.code
  • error.category
  • error.retryable
  • dependency.name
  • dependency.type
  • duration_ms

2026-06-01 명명 정합 (F2/D19): JSON 로그의 필드 명은 mdc-keys.yaml 의 snake_case 가 authoritative — 즉 위 traceId/requestId/correlationId 는 실제 로그에서 trace_id/request_id/correlation_id/span_id (snake) 로 출력된다(§21 L855 MDC core 6 + log extension 13 모두 snake). camelCase 표기는 §3 응답 envelope (meta.traceId …) 의 표현이며, kebab-case 는 HTTP header (X-Request-Id) 표현이다. 동일 식별자의 계층별 표현 매핑(snake↔camel↔kebab)은 foundation branch D19 (raw/branch-notes/feature-operational-error-observability-foundation §구현 가이드 §3) 가 SSOT. envelope camelCase 표기 자체의 owner 는 §25 의 schema-serialization.

로그 종류:

  • request log
  • application log
  • dependency log
  • security event log
  • audit log

로그 금지:

  • PII
  • secrets
  • token
  • password
  • authorization header
  • raw request body
  • raw response body
  • SQL parameter

기본 level 기준:

  • client validation 4xx: INFO 또는 WARN
  • auth/authz failure: WARN
  • dependency failure: ERROR
  • internal 5xx: ERROR

Distributed Tracing Contract

  • trace context는 inbound HTTP, outbound HTTP, async job, message publish/consume 경계에서 전파해야 함.
  • traceId는 관측성 상관관계의 최상위 식별자이고, requestId는 inbound HTTP 요청 단위 식별자이며, correlationId는 business-neutral workflow 식별자로 사용.
  • baggage에는 PII, token, user raw identifier, request body derived value를 넣지 않음.
  • async/job/message boundary에서는 부모 trace context가 없을 경우 새 trace를 만들고 correlationId는 유지.
  • sampling, exporter, propagation header는 env로 제어.
  • log에는 traceId, spanId, requestId, correlationId를 같은 이름으로 남김.

9. Env-driven Runtime Configuration

서버별 운영 전환이 env로 가능해야 합니다.

기본 env:

  • APP_NAME
  • APP_PROFILE
  • ERROR_EXPOSE_DETAILS
  • ERROR_EXPOSE_VALIDATION_DETAILS
  • LOG_FORMAT
  • LOG_LEVEL
  • LOG_BODY_ENABLED
  • LOG_PII_GUARD_ENABLED
  • TRACE_ENABLED
  • REQUEST_ID_HEADER
  • CORRELATION_ID_HEADER
  • DB_URL
  • DB_USERNAME
  • DB_PASSWORD
  • DB_POOL_MAX_SIZE
  • DB_CONNECTION_TIMEOUT_MS
  • HTTP_CONNECT_TIMEOUT_MS
  • HTTP_READ_TIMEOUT_MS
  • HTTP_RETRY_ENABLED
  • HTTP_CIRCUIT_BREAKER_ENABLED
  • KAFKA_ENABLED
  • REDIS_ENABLED
  • SLACK_ENABLED
  • GOOGLE_EMAIL_ENABLED
  • SECURITY_JWT_ISSUER
  • SECURITY_JWT_AUDIENCE
  • CORS_ALLOWED_ORIGINS

기준:

  • local/dev/staging/prod env matrix 작성.
  • 잘못된 env 값은 가능한 한 startup에서 fail-fast.
  • prod에서 body logging 기본 금지.
  • prod에서 error detail 노출 기본 금지.

10. Repository Access Permission Contract

Read/write repository 분리는 기본 전제입니다. 추가로 use case 단위 capability 정책을 둡니다.

use case capability:

  • READ_REPOSITORY
  • WRITE_REPOSITORY
  • SENSITIVE_READ
  • BULK_WRITE
  • TRANSACTION_REQUIRED
  • EXTERNAL_OUTBOUND_ALLOWED

기준:

  • use case에 허용 capability를 선언.
  • 선언되지 않은 repository capability 사용은 contract violation.
  • repository access permission violation은 일반 internal error가 아니라 skeleton contract violation으로 분류.
  • 테스트로 capability 위반을 감지.

11. Adapter Failure Contract

Persistence

  • Data integrity violation
  • lock conflict
  • query timeout
  • DB unavailable
  • JPA system failure
  • SQL/parameter 로그 금지

추후 branch 분해 대상 (deferred, 아직 owner branch 없음)raw/branch-notes/feature-persistence-failure-baseline §Audit & Findings 에서 OUT_OF_BRANCH_SCOPE 로 분리된 2건. failure-baseline branch In-scope(실패 분류) 밖이라 별도 branch 가 필요하나 미생성:

  • disaster recovery restore drill (D7): backup 존재가 아니라 restore drill 통과 기준 (§18 Data Retention/Privacy backup/restore 책임 경계 + Operational Runbook 와 연계). 내부 RTO/RPO 정책 — 외부 공식 근거 없음.
  • read replica lag threshold (D8): replica 기본 미사용, 활성화 시 max lag threshold + stale-read 허용 endpoint 명시. 부모에 replica 전용 계약 섹션 부재 — 신설 필요. 착수 시 /branch feature-disaster-recovery-restore-drill · /branch feature-read-replica-lag-contract 로 전개.

Outbound HTTP

  • RestClient 기본.
  • 400/401/403/404/409/429/5xx/timeout/DNS/connect failure 분류.
  • dependency log field 필수.
  • body logging 기본 금지.

Security

  • JWT Resource Server 기준.
  • missing token, malformed token, expired token, invalid signature, issuer mismatch, audience mismatch, claim mapping failure 분리.
  • token/PII 로그 금지.

Optional Adapters

  • Kafka: publish/consume/deserialization/retry/DLQ/idempotency/correlationId 기준.
  • Redis: cache miss는 장애 아님. unavailable은 degrade 가능 여부로 분류.
  • Slack/Email: notification failure가 core use case를 막을지 명시.

12. Test Contract

테스트로 강제할 계약:

  • structured error response schema
  • validation details exposure policy
  • raw exception leakage 방지
  • structured log field 존재
  • PII/token/body 미기록
  • retryable classification
  • requestId/traceId/correlationId propagation
  • env profile matrix smoke test
  • repository capability violation detection
  • adapter failure mapping

13. API Contract Surface

응답 envelope만으로는 API contract가 완성되지 않습니다. 다음 표면도 skeleton 기준으로 고정해야 합니다.

  • API versioning path/header 기준.
  • pagination / sorting / filtering 요청/응답 표준.
  • idempotency key header와 command 중복 처리 기준.
  • request size limit과 payload too large 실패 분류.
  • multipart/file upload 실패 분류.
  • content negotiation 실패 분류.
  • enum/date/timezone/BigDecimal JSON 직렬화 기준.
  • unknown JSON field 허용/거부 기준.
  • OpenAPI schema와 실제 응답 contract 일치 검증.

14. Transaction / Concurrency Contract

쓰기 use case와 persistence adapter는 concurrency 실패 기준을 가져야 합니다.

  • transaction boundary는 application use case 책임으로 두되 Spring @Transactional 직접 import는 금지하고 TransactionPort 또는 TransactionalUseCaseRunner로 추상화.
  • read-only use case는 read-only transaction 기준을 가짐.
  • optimistic lock, pessimistic lock, deadlock, lock timeout 분류.
  • duplicate command와 idempotent command 구분.
  • command retry 시 중복 write 방지 기준.
  • outbox pattern 도입 기준.
  • transaction required repository capability와 실제 transaction boundary 일치 검증.

15. Runtime / Lifecycle Contract

서버 운영에서 business logic 없이도 발생하는 lifecycle 실패를 다룹니다.

  • actuator health/readiness/liveness 기준.
  • graceful shutdown 기준.
  • startup validation 기준.
  • migration failure 처리 기준.
  • scheduled job 실패 기준.
  • async executor/thread pool rejection 기준.
  • memory/disk/temp file/resource exhaustion 분류.
  • JVM timezone/system clock 기준.

16. Schema / Serialization Contract

DTO와 JSON schema가 암묵적으로 흘러가지 않도록 serialization 기준을 둡니다.

  • date/time은 timezone 정책을 명시.
  • money/decimal은 scale/rounding 정책을 명시.
  • enum은 unknown value 처리 기준을 명시.
  • null/empty/missing field 의미를 구분.
  • response field rename은 API versioning과 연결.
  • OpenAPI schema drift를 테스트로 감지.

17. Sample Domain Fixture

도메인/비즈니스 로직은 제거하지만, skeleton 계약 검증을 위한 sample domain은 둡니다.

기본 sample:

sample-portfolio

sample domain이 검증해야 할 것:

  • create/read/update/delete 흐름.
  • request DTO -> command/query -> domain -> persistence -> response mapper.
  • validation failure.
  • not found.
  • conflict.
  • optimistic lock.
  • pagination.
  • repository capability.
  • idempotent create/update.
  • outbound adapter 호출 금지/허용 use case.

기준:

  • sample은 sample package/module/profile 아래 격리.
  • 실제 프로젝트에서 제거 가능해야 함.
  • sample은 business feature가 아니라 skeleton contract fixture임.
  • sample domain 결과를 portfolio/blog/interview로 직접 파생하지 않음.
  • sample-portfolio은 worklog create/read/update/close 흐름, status transition, assignee/owner policy, optimistic lock, idempotent create, pagination, repository capability를 검증하기 위한 최소 fixture로 둠.

18. Control Plane Contract

운영자는 API 응답과 로그만 보지 않습니다. 서버를 배포, 감시, 보호, 장기간 유지보수하기 위한 제어면도 skeleton 기준에 포함합니다.

Metrics / Alerting

  • HTTP latency/error rate metric.
  • dependency latency/error rate metric.
  • DB pool metric.
  • JVM/process metric.
  • retry/circuit breaker metric.
  • alert severity는 P1, P2, P3를 기본값으로 사용.

Secrets / Config Source

  • env와 secret manager 사용 범위.
  • local .env 허용 범위.
  • prod secret 노출 금지.
  • config dump 금지.
  • secret rotation 절차와 rotation 후 startup validation 기준.

Management / Actuator Security

  • actuator endpoint allowlist.
  • health detail exposure 기준.
  • metrics endpoint 인증 기준.
  • management port 분리 여부.
  • prod에서 env/configprops 노출 금지.

Tenant Context Policy

  • multi-tenancy 지원 여부를 명시.
  • tenant header 허용/금지 기준.
  • tenant scoped repository 기준.
  • tenant leakage 테스트 기준.

File / Resource Handling

  • upload size limit.
  • temp file cleanup.
  • download streaming failure.
  • content type sniffing 금지.
  • path traversal 방지.

Cache Consistency

  • cache aside 기준.
  • stale cache 허용 범위.
  • cache stampede 방지.
  • key naming / TTL / invalidation 실패 기준.

Background Job / Async Boundary

  • async exception handling.
  • executor saturation.
  • scheduled job overlap.
  • job id/correlationId.
  • retry/backoff.
  • shutdown 중 job 처리.

API Compatibility / Deprecation

  • breaking change 정의.
  • response field removal 금지 기준.
  • deprecated field 정책.
  • migration window 기준.

CI Quality Gates

  • format/lint/test/contract test/OpenAPI drift check/security scan이 CI에서 분리된 gate로 실행되어야 함.
  • branch merge 전 실패 가능 gate와 warning-only gate를 구분.
  • contract violation은 warning-only로 두지 않음.
  • optional adapter test는 adapter enabled matrix에서만 실행.

Build / Release / Supply Chain

  • dependency version locking 기준.
  • container image base와 non-root runtime 기준.
  • SBOM 생성 여부.
  • vulnerability severity별 release block 기준.
  • rollback 가능한 artifact versioning 기준.

Container Runtime

  • JVM memory/container limit 기준.
  • timezone/locale 기준.
  • healthcheck command 기준.
  • graceful shutdown signal 기준.
  • writable filesystem 최소화 기준.

Operational Runbook

  • alert 발생 시 확인할 dashboard/log query/runbook link 기준.
  • dependency 장애, DB unavailable, auth failure spike, 5xx spike, queue lag, cache unavailable별 1차 대응 기준.
  • degrade 가능한 장애와 즉시 fail-fast해야 하는 장애를 구분.

Data Retention / Privacy

  • application log, security event log, audit log 보존 기간 기준.
  • PII redaction과 pseudonymization 기준.
  • backup/restore 책임 경계.
  • sample data와 real data 혼동 방지 기준.

Developer Experience

  • local bootstrap command 기준.
  • .env.example 필수 key 기준.
  • Testcontainers 또는 local dependency 대체 기준.
  • smoke test command 기준.
  • sample profile 실행/비활성화 기준.

19. Domain Application Readiness Contract

이 skeleton은 도메인/비즈니스 로직을 포함하지 않지만, 실제 도메인을 얹을 때 바로 같은 구조로 개발할 수 있어야 합니다.

Domain Feature Slice

새 도메인 기능은 최소 slice 단위로 추가합니다.

presentation request/response DTO
request mapper
application command/query
use case
input port / output port
domain model / value object / domain rule
persistence model / repository adapter
response mapper
contract test
architecture rule

기준:

  • controller가 use case 외부의 domain/persistence type을 직접 알면 실패.
  • application use case는 input port를 구현하고 output port에만 의존.
  • infrastructure adapter는 output port를 구현.
  • domain은 Spring/JPA/HTTP/security/logging type을 알지 않음.
  • 새 feature는 sample-portfolio의 구조를 복제하되 sample package에 의존하지 않음.

Use Case / Port Contract

  • command use case와 query use case를 구분.
  • write use case는 transaction/capability/idempotency 기준을 명시.
  • read use case는 pagination/filtering/sorting과 sensitive read capability를 명시.
  • outbound dependency가 필요한 use case는 EXTERNAL_OUTBOUND_ALLOWED capability를 명시.
  • use case method는 raw DTO, entity, HTTP request, JPA repository를 직접 받지 않음.

Domain Modeling Guardrails

  • entity, value object, domain service, domain event를 구분.
  • value object는 생성 시점에 자기 불변식을 검증.
  • aggregate 외부에서 내부 상태를 임의 변경하지 못하게 함.
  • domain rule은 presentation validation이나 JPA constraint에만 의존하지 않음.
  • domain exception은 business invariant만 표현하고 operational error code를 직접 알지 않음.

Business Rule Validation

  • syntax/shape validation은 request DTO에서 처리.
  • use case policy validation은 application에서 처리.
  • business invariant는 domain에서 처리.
  • persistence uniqueness/integrity는 infrastructure에서 operational error로 변환하되, 필요한 경우 application/domain policy로 사전 검증.
  • 같은 규칙을 여러 경계에 중복 구현할 때는 목적을 명시.

Domain Event / Outbox

  • domain event는 domain fact만 표현하고 transport detail을 모름.
  • integration event 발행은 application/infrastructure 경계에서 변환.
  • transactional publish가 필요하면 outbox 기준을 사용.
  • event handler 실패는 retryable/non-retryable과 DLQ/runbook 기준을 가짐.
  • event payload에는 PII/secrets/raw body를 넣지 않음.

Sample Removal / Project Adoption

  • sample-portfolio은 새 프로젝트 생성 시 제거 가능해야 함.
  • 제거 후에도 operational/error/log/env/test/architecture contract는 남아야 함.
  • 새 도메인은 sample-portfolio을 import하지 않고 구조만 참고.
  • sample 제거 smoke test를 둬서 skeleton core와 sample fixture 결합을 감지.

20. Skeleton Blueprint Contract

실제 구현자는 문서의 원칙뿐 아니라 module boundary와 package 위치를 함께 알아야 합니다. Phase C2 기본값은 Gradle multi-module + Clean Architecture / Hexagonal boundary 입니다. module boundary가 1차 강제선이고, module 내부 package는 2차 책임 분류입니다. 단일 모듈 구조는 demo/readme용 축소형으로만 허용하며, 아래 responsibility mapping을 보존해야 합니다.

20-0. Implementation status (2026-05-27)

feature-skeleton-package-blueprint-contract 범위는 ca-tmpl repo에서 B안 기준으로 local implementation 완료. 구현 범위는 Gradle module include, module build dependency matrix, package anchor, reference blog package 이동, ArchUnit/Gradle guardrail, README/agent rule update이다. 검증은 ./gradlew verifyCleanArchitectureDependencies, ./gradlew :app-bootstrap:test --tests '*CleanArchitectureTest', ./gradlew :adapter-web:test --tests '*SettingsTest', ./gradlew test 통과로 locally-verified 처리한다.

제외/잔여: sample-portfolio은 fixture anchor만 있고 실제 worklog sample은 미구현. application/port/inapplication/port/out package anchor는 존재하지만 reference blog repository port는 아직 domain/repository에 남아 있다 (feature-application-port-usecase-contract branch에서 application/port/out으로 이동). Spring Modulith verifier는 도입하지 않았다. 운영 배포가 아니므로 prod-verified 항목은 없다.

settings.gradle
  rootProject.name = 'ca-skeleton'
  include 'app-bootstrap'
  include 'domain-core'
  include 'application-core'
  include 'adapter-web'
  include 'adapter-persistence'
  include 'adapter-outbound'
  include 'shared-contract'
  include 'sample-portfolio'

app-bootstrap/
  src/main/java/{basePackage}/bootstrap/
    CaSkeletonApplication
    config/
  src/test/java/{basePackage}/bootstrap/
    smoke/

shared-contract/
  src/main/java/{basePackage}/shared/
    response/
    error/
    headers/
    logging/
    tracing/
    metrics/
    registry/
    annotation/
  src/test/java/{basePackage}/shared/
    contract/

domain-core/
  src/main/java/{basePackage}/domain/
    # framework-neutral POJO domain model (production)
  src/test/java/{basePackage}/domain/

application-core/
  src/main/java/{basePackage}/application/
    usecase/
    command/
    query/
    capability/      # @UseCaseRepositoryAccess, Idempotency enum
    transaction/     # TransactionPort, TransactionalUseCaseRunner
  src/test/java/{basePackage}/application/

adapter-web/
  src/main/java/{basePackage}/
    adapter/web/
      dto/
      exception/
      auth/
    presentation/    # presentation-specific (e.g., grpc)
  src/test/java/{basePackage}/adapter/web/

adapter-persistence/
  src/main/java/{basePackage}/adapter/persistence/
    # entity/repository/mapper/migration sub-packages 도메인 추가 시 생성
  src/test/java/{basePackage}/adapter/persistence/

adapter-outbound/
  src/main/java/{basePackage}/adapter/outbound/
    # httpclient/messaging/cache/notification sub-packages 도메인 추가 시 생성
  src/test/java/{basePackage}/adapter/outbound/

shared-contract/
  src/main/java/{basePackage}/shared/
    tracing/
    metrics/
    request/
    logging/
    headers/
    response/        # envelope, BulkEnvelope
    error/           # OperationalError, error codes
  src/test/java/{basePackage}/shared/

app-bootstrap/
  src/main/java/{basePackage}/
    # Spring Boot Application + bean wiring
  src/test/java/{basePackage}/

sample-portfolio/
  src/main/java/{basePackage}/sample/portfolio/
    domain/
      worklog/       # WorkLog domain entity + value objects (Period, WorkCategory, etc.)
    application/
      command/       # CreateWorkLogCommand, UpdateWorkLogCommand, DeleteWorkLogCommand
      query/         # GetWorkLogQuery, ListWorkLogsQuery, GetRepoStatsQuery
      port/          # outbound port (e.g., RepoStatsPort)
      exception/     # WorkLogNotFoundException
      worklog/       # use case implementations (Create/Get/List/Update/Delete/GetRepoStats)
    adapter/
      web/
        controller/  # WorkLogController
        dto/
          request/   # CreateWorkLogRequest, UpdateWorkLogRequest, ...
          response/  # WorkLogResponse, RepoStatsResponse, ...
        mapper/      # WorkLogWebMapper
        error/       # DomainExceptionHandler, PortfolioErrorCode
      persistence/
        entity/      # WorkLogEntity
        repository/  # WorkLogJpaRepository, WorkLogRepositoryAdapter
        mapper/      # WorkLogPersistenceMapper
        config/      # JpaConfig
      outbound/
        repostats/   # external API adapter (RepoStatsPortClient + ACL mapper)
  src/test/java/{basePackage}/sample/portfolio/
    domain/
    application/
    adapter/

기준:

  • domain-core는 framework-neutral POJO domain model만 담고 Spring / JPA / HTTP DTO / Redis / Kafka / client library를 알지 않음.
  • application-core는 use case, command/query, inbound/outbound port, policy validation을 담고 domain-coreshared-contract에만 의존함.
  • adapter-web은 controller, HTTP DTO, mapper, filter, presentation exception mapping을 담고 application port를 호출함.
  • adapter-persistence는 JPA entity, Spring Data repository, persistence mapper, migration integration을 담고 application outbound port를 구현함.
  • adapter-outbound는 outbound HTTP, messaging, cache, notification adapter 구현체를 담고 application outbound port를 구현함.
  • shared-contract는 response envelope, error code, header/MDC/metric registry, tracing/logging contract, 공통 annotation처럼 skeleton-wide operational contract만 담고 business/domain concept를 담지 않음.
  • app-bootstrap은 runtime composition root이며 Spring Boot application, bean wiring, profile config를 담음. domain policy 구현을 담지 않음.
  • sample-portfolio은 contract 검증 fixture이며 production feature가 아님. production module이 sample-portfolio을 import하거나 dependency로 선언하면 실패.
  • package/module 위치가 다르면 architecture rule 문서에 responsibility mapping을 명시해야 함.

Module dependency rule:

Module May depend on Must not depend on
domain-core (none) or shared-contract value-only types Spring, JPA, HTTP DTO, Redis/Kafka/client libraries, adapter modules
application-core domain-core, shared-contract adapter-*, app-bootstrap, Spring Web/JPA implementation APIs
adapter-web application-core, domain-core, shared-contract adapter-persistence, adapter-outbound direct implementation coupling
adapter-persistence application-core, domain-core, shared-contract adapter-web, app-bootstrap
adapter-outbound application-core, domain-core, shared-contract adapter-web, app-bootstrap
app-bootstrap all runtime modules domain policy implementation
sample-portfolio all runtime modules only as fixture consumer production module importing sample-portfolio

21. Contract Registry

100점 기준에서는 중요한 문자열과 enum이 문서 곳곳에 흩어지면 안 됩니다. 본 섹션의 7개 registry는 raw markdown 결정 사항과 별도로 implementation artifact yaml(ca-tmpl/docs/registries/ 하위)에서 단일 source of truth로 관리합니다. yaml은 Phase B 산출물이며, ca-tmpl 실 코드 단계(Phase C2)에서 generated constants의 source가 됩니다. 본 섹션의 inline 요약은 reader 편의용이며 정확한 row 정의는 yaml을 참조합니다.

SSOT yaml 위치

registry yaml 파일 row 수 (2026-05-22) owner branch
Error Codes ca-tmpl/docs/registries/error-codes.yaml 49 (skeleton-level; NOT_FOUND/도메인별 VALIDATION row는 도메인 도입 시 추가) feature-operational-error-observability-foundation (category enum SSOT)
Env Keys ca-tmpl/docs/registries/env-keys.yaml 51 feature-env-driven-runtime-configuration
Secrets Classification ca-tmpl/docs/registries/secrets-classification.yaml 15 feature-secrets-config-source-contract
HTTP Headers ca-tmpl/docs/registries/headers.yaml 15 feature-api-contract-baseline (cross-owner: idempotency, tracing, tenant, compat, security)
MDC / Log Keys ca-tmpl/docs/registries/mdc-keys.yaml 19 (foundation core 6 + log extension 13) feature-operational-error-observability-foundation
Metrics ca-tmpl/docs/registries/metrics.yaml 25 feature-metrics-alerting-contract
Repository Access Capabilities ca-tmpl/docs/registries/capabilities.yaml 7 feature-repository-access-permission-contract

총 196 rows. 모든 row에 source branch + line 인용 yaml comment 포함. 추측 row 0건 (source-grounded only).

Error Registry 요약 (yaml 정합)

  • error.category enum (foundation SSOT, 10개): VALIDATION / AUTH / AUTHZ / NOT_FOUND / CONFLICT / RATE_LIMIT / TRANSIENT_DEPENDENCY / PERMANENT_DEPENDENCY / DATA_INTEGRITY / INTERNAL
  • 카테고리별 row 분포: TRANSIENT_DEPENDENCY 15 · AUTH 8 · INTERNAL 8 · VALIDATION 6 · CONFLICT 4 · AUTHZ 3 · DATA_INTEGRITY 3 · RATE_LIMIT 1 · PERMANENT_DEPENDENCY 1 · NOT_FOUND 0 (도메인 도입 시 추가)
  • row schema: code (UPPER_SNAKE_CASE), category, http_status, retryable, retry_after_seconds, owner_branch, owner_layer, client_safe_message, log_level, runbook_link, compatibility_impact, required_test
  • runbook 정책: retryable=true 모두 + category ∈ {AUTH, AUTHZ, RATE_LIMIT, INTERNAL, TRANSIENT_DEPENDENCY, PERMANENT_DEPENDENCY} 이면서 retryable=false인 row는 runbook_link 필수. client-error(VALIDATION/NOT_FOUND/CONFLICT/DATA_INTEGRITY + retryable=false)는 면제.
  • 명명 정합: AUTHENTICATIONAUTH, AUTHORIZATIONAUTHZ, PERSISTENCEDATA_INTEGRITY/TRANSIENT_DEPENDENCY 매핑 (Phase A 4차 audit Conflict 13 해소).

Response Envelope 요약

envelope schema는 feature-operational-error-observability-foundation SSOT. 필수 field:

field required rule
success yes boolean only
data success only public payload, domain/entity 직접 노출 금지
error.code failure only error-codes.yaml row의 code
error.category failure only foundation enum 10개 중 하나
error.message failure only client-safe, raw exception/stack/SQL/token 금지
error.retryable failure only error-codes.yaml의 retryable값과 일치
error.details optional validation field error shape(field, rejectedValue(masked), code, message)
meta.requestId yes (camelCase) mdc-keys.yaml의 request_id (snake) ↔ envelope camel mapping
meta.traceId yes tracing disabled에서도 opaque id 유지 + sampled=false
meta.correlationId yes mdc correlation_id mapping
meta.page paged only page, size, optional total, sort 정보 (성능 함정 회피, cursor pagination은 별도 endpoint)
meta.idempotency.replayed idempotent replay only replay 응답 명시

Header Registry 요약 (headers.yaml)

  • naming: HTTP 표준은 kebab-case (X-Request-Id, X-Tenant-Id, X-Api-Version, Idempotency-Key, Retry-After, Deprecation, Sunset, X-RateLimit-Limit/Remaining/Reset), W3C trace context는 lowercase (traceparent, tracestate), security 표준 (Authorization, WWW-Authenticate).
  • direction 분포: inbound 3 · outbound 7 · both 5.
  • mdc_key 매핑 (mdc-keys.yaml과 cross-link): X-Request-Id↔request_id, X-Correlation-Id↔correlation_id, traceparent↔trace_id, X-Tenant-Id↔tenant_id.
  • envelope_meta_field 매핑: meta.requestId, meta.traceId, meta.correlationId.

Secrets Registry 요약 (env-keys.yaml, secrets-classification.yaml)

  • env-keys: 51 row, prefix APP_ (Spring native env는 prefix 없이 별도 row, 예: SPRING_PROFILES_ACTIVE, SERVER_PORT). 15개 영역: profile/identity · datasource/pool · outbound HTTP · tracing · log · security/CORS · JWT · tenant · cache/Redis · messaging · notification adapter · file upload · runtime/lifecycle · async executor · sample.
  • secrets-classification: 15 row, 3-tier:
    • secret 6: DB_PASSWORD, JWT_SIGNING_KEY, OAUTH_CLIENT_SECRET, EXTERNAL_API_KEY, REDIS_PASSWORD, PSEUDONYMIZATION_SALT
    • sensitive-config 4: SLACK_WEBHOOK_URL, GOOGLE_OAUTH_CLIENT_ID, DATASOURCE_USERNAME, DATASOURCE_URL
    • public-config reference 5: APP_PROFILE, APP_NAME, SERVER_PORT, SPRING_PROFILES_ACTIVE, OTEL_EXPORTER_OTLP_ENDPOINT (본 yaml은 reference만, env-keys.yaml에서 정의)
  • rotation 정책: restart-only (default) · dual-bind-60s (DB credential) · overlap-24h (JWT signing key, idempotency TTL invariant) · salt-rotation-90d (pseudonymization salt) · manual (webhook/OAuth client ID)
  • masking: secret은 full_except_last_4, 기타 none. prod profile에서 __LOCAL_DEV_ prefix value 발견 시 startup fail.
  • reload: no-runtime-reload (env-driven branch SSOT, secret rotation은 restart validation 또는 dual-bind 책임).

Metrics Registry 요약 (mdc-keys.yaml, metrics.yaml)

  • MDC keys: snake_case 강제 (foundation SSOT). core 6: request_id, trace_id, span_id, correlation_id, tenant_id, user_principal (pseudonymized only). log extension 13: operation, method, status, duration_ms, dependency_name, dependency_type, outcome, error_code, source_ip_anon (last octet zeroed), actor, action, target, event_type.
  • propagation matrix: http(5)/async(5)/message(4)/none(14). background-job-async TaskDecorator 단일 owner가 async/message boundary propagation 책임. user_principal은 log only, header/baggage forbidden.
  • metrics: Micrometer dot.case + unit suffix(.seconds/.bytes/.total). cardinality bounds 강제: status_code≤7, uri_template≤200, dependency_name≤50, error_code≤100 (error-codes.yaml row 상한과 정합), tenant_id≤1000 (raw ULID 금지, mapping id 또는 cohort bucket), outcome≤5. high-cardinality tag forbidden: user_id, request_id, raw_url, raw_query, raw_header_value, ip_address.
  • percentile: HTTP/DB/dependency timer는 p50/p90/p95/p99. histogram bucket은 SLO-driven (잠정 SLO p99 = 1s).
  • alert severity P1/P2/P3 정량 기준은 metrics.yaml의 alert_severity_thresholds field. 잠정 SLO 기반.

Capability Registry 요약 (capabilities.yaml)

7개 capability:

capability enforcement notes
READ_REPOSITORY ArchUnit 일반 read
WRITE_REPOSITORY ArchUnit create/update/delete
SENSITIVE_READ ArchUnit (marker는 registry-managed metadata) PII/secret-like field read
BULK_WRITE ArchUnit (threshold N > 100) batch mutation
TRANSACTION_REQUIRED ArchUnit + TransactionPort cross-link Spring @Transactional 직접 import forbidden
EXTERNAL_OUTBOUND_ALLOWED ArchUnit outbound HTTP/message/notification. outbox row INSERT는 in-process(불요), polling publisher의 broker publish는 outbound(필요)
CROSS_TENANT_ADMIN ArchUnit tenant 활성 시 cross-tenant 접근 명시 선언

enforcement: ArchUnit annotation-based rule SSOT. compile-time annotation processor alternative, runtime AOP forbidden.

Registry 변경 절차

  1. raw 결정은 branch note의 결정 사항 / Decisionized Work Items 표에 먼저 작성.
  2. SSOT yaml의 row 추가/수정. row 위 yaml comment에 source branch + line 인용.
  3. compatibility_impact 분류 (none / additive / behavior-change / breaking).
  4. 관련 contract test 추가/수정.
  5. ca-tmpl 실 코드(Phase C2)의 generated constants 재생성 (build task).
  6. branch note의 TODO 항목 drain (registry-governance step 6).

registry 기준:

  • 새 error/env/header/log/metric/capability를 추가할 때 registry yaml 없이 branch TODO만 추가하면 실패.
  • registry 항목은 test contract와 연결되어야 함 (required_test field).
  • registry 변경은 backward compatibility와 migration 영향을 기록해야 함 (compatibility_impact field).
  • yaml row의 source comment가 branch note 라인 인용 없이 추가되면 review fail.

22. Sample-portfolio Contract Matrix

sample-portfolio은 기능 예제가 아니라 skeleton 계약 검증 fixture입니다.

scenario layer path verifies expected failure if broken
create worklog success request DTO -> command -> use case -> domain -> repository -> response mapper, command validation, write capability, transaction, envelope controller가 domain/entity를 직접 생성하거나 반환
create worklog validation failure presentation -> error handler validation details, client-safe error, no raw exception malformed request가 500 또는 raw exception으로 노출
create worklog idempotent replay presentation/application/persistence Idempotency-Key, duplicate write 방지, replay meta retry 시 worklog 중복 생성
get worklog success query use case -> read port -> response mapper query/read capability, response mapper persistence entity가 response로 노출
get worklog not found application -> error registry RESOURCE_NOT_FOUND, 404, retryable false not found가 500 또는 DB exception으로 노출
list worklogs pagination query -> repository -> response meta pagination meta, sorting/filtering contract pagination 정보가 data payload에 섞임
update worklog conflict domain/application conflict classification, status transition rule invalid transition이 성공하거나 500 발생
close worklog optimistic lock persistence/application optimistic lock -> conflict/retry policy lock failure가 raw JPA exception으로 노출
unauthorized worklog update security/application auth/authz separation, no PII log 401/403 분류 혼동 또는 token log
outbound forbidden use case application capability EXTERNAL_OUTBOUND_ALLOWED enforcement capability 없이 외부 adapter 호출
sample disabled startup runtime/profile sample prod 비활성화 prod profile에서 sample endpoint 노출
sample removal smoke build/test core contract와 sample fixture 분리 sample 제거 후 app/context/contract test 실패

sample-portfolio minimum model:

model required fields purpose
WorkLogId 26-char uppercase Crockford base32 ULID (예: 01ARZ3NDEKTSV4RRFFQ69G5FAV, regex ^[0-9A-HJKMNP-TV-Z]{26}$) — raw/branch-notes/feature-resource-identifier-contract D19 SSOT value object / path variable mapping
WorkLogTitle normalized non-empty string request validation + domain invariant
WorkLogStatus OPEN, IN_PROGRESS, CLOSED enum serialization + transition conflict
WorkLogVersion numeric version optimistic locking
WorkLogOwner pseudonymized principal id authorization/log privacy
IdempotencyKey opaque key duplicate write prevention

sample-portfolio rule:

  • OPEN -> IN_PROGRESS -> CLOSED만 허용.
  • CLOSED worklog은 update 불가.
  • owner 또는 allowed assignee만 update 가능.
  • create는 idempotent command로 처리.
  • list는 pagination/sorting/filtering contract를 사용.
  • sample package는 production package에서 import 금지.

23. Branch Canonical Promotion Criteria

branch note는 아래 산출물이 있어야 wiki/projects canonical 문서로 승급할 수 있습니다.

artifact required rule
Decision table yes 기본값/예외/금지/실패 조건 포함
Work item contract yes 각 TODO가 Decision/Allowed/Forbidden/Registry/Test/Failure/Canonical target으로 재작성되어야 함
Registry update if token changed error/env/header/log/metric/capability 변경 시 필수
Sample-portfolio verification if applicable sample scenario 또는 sample removal로 검증
Contract test mapping yes 어떤 테스트가 깨지는지 명시
Architecture rule mapping boundary related only package/import/dependency 위반 기준 명시
Runbook/log/metric mapping operational related only 운영자가 확인할 field와 alert 연결
Adoption note yes 실제 도메인 feature가 따라야 할 규칙 명시
Out-of-scope note yes branch가 책임지지 않는 영역 명시

promotion failure:

  • TODO가 “기준 작성” 수준으로만 남아 있으면 승급 실패.
  • TODO가 Work Item Contract 필드를 채우지 않으면 승급 실패.
  • registry 영향이 있는데 registry update가 없으면 승급 실패.
  • sample-portfolio 또는 sample removal 검증 경로가 없으면 승급 실패.
  • 실제 도메인 feature adoption 기준이 없으면 승급 실패.

8.0 실행계획

Project contract v2의 branch handoff SSOT. 기존 §24 목록에는 dependency가 없으므로 revision 1에서는 -로 보존하며, 각 완료 조건은 §23의 promotion contract 6필드와 해당 branch gate 통과로 고정한다.

Work Item ID branch slug 완료 조건 (측정가능) Applies Decisions Dependencies Status
WI-CA-SKELETON-OPERATIONAL-CONTRACT-001 feature-operational-error-observability-foundation error·observability 6필드 contract와 contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-ERROR-ENVELOPE-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-002 feature-boundary-validation-mapping-contract boundary·mapping 6필드 contract와 negative fixture가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MAPPING-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-003 feature-log-management-contract log field·masking contract와 verification test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-ERROR-ENVELOPE-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-004 feature-env-driven-runtime-configuration env configuration 6필드 contract와 invalid-config test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-005 feature-repository-access-permission-contract repository access rule과 forbidden fixture가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TRANSACTION-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-006 feature-persistence-failure-baseline persistence failure mapping과 integration test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-DATABASE-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TESTCONTAINERS-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-007 feature-outbound-http-client-baseline timeout·retry·circuit-breaker contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TESTCONTAINERS-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-008 feature-security-operational-baseline security failure·header contract와 negative test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-009 feature-integration-adapter-templates optional adapter template가 core broker abstraction을 침범하지 않는다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-EVENT-BROKER-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-010 feature-contract-verification-test-suite release-blocking contract suite가 OpenAPI drift를 검출한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-OPENAPI-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-TEST-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-011 feature-api-contract-baseline /v1 API와 envelope/OpenAPI contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-OPENAPI-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-012 feature-transaction-concurrency-contract transaction·concurrency failure fixture가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TRANSACTION-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-DATABASE-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-013 feature-runtime-health-lifecycle-contract startup·readiness·shutdown lifecycle test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MIGRATION-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-014 feature-sample-domain-contract-fixture sample domain fixture가 module contract를 검증하고 제거 smoke가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-015 feature-schema-serialization-contract JSON·date·decimal serialization contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-JSON-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-016 feature-rate-limit-idempotency-contract principal·tenant key scope와 replay/rate-limit test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-IDEMPOTENCY-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RATE-LIMIT-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-017 feature-migration-startup-contract Flyway 실패·진행 중 readiness가 healthy가 아님을 검증한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MIGRATION-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-MIGRATION-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-018 feature-architecture-enforcement-rules forbidden module/import fixture가 ArchUnit gate에서 실패한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-ARCHTEST-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-019 feature-metrics-alerting-contract metric key·cardinality·alert contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-ERROR-ENVELOPE-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-020 feature-secrets-config-source-contract secret source·classification·leakage negative test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-021 feature-management-actuator-security-contract management endpoint exposure·authorization test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-022 feature-tenant-context-policy tenant propagation·clear negative fixture가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-023 feature-file-resource-handling-contract file size·type·storage boundary test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-024 feature-cache-consistency-contract after-commit invalidation·stampede failure fixture가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-DATABASE-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-025 feature-background-job-async-contract duplicate scheduler/outbox execution 방지 test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-SCHEDULER-LOCK-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-EVENT-BROKER-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-026 feature-api-compatibility-deprecation-contract /v1 compatibility·deprecation contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-027 feature-distributed-tracing-contract request·trace correlation contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-ERROR-ENVELOPE-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-028 feature-ci-quality-gates-contract architecture·contract·OpenAPI blocking gate가 분리 실행된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-OPENAPI-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-TEST-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-029 feature-build-release-supply-chain-contract Gradle release·SBOM·signature artifact가 생성된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-030 feature-container-runtime-contract non-root·memory·health container contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-CONTAINER-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-031 feature-operational-runbook-contract 각 failure category에 trigger·diagnosis·recovery drill이 연결된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-BOOTSTRAP-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-032 feature-data-retention-privacy-contract retention·deletion·masking contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-033 feature-developer-experience-contract fresh environment에서 ./gradlew bootstrap이 성공한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-BOOTSTRAP-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-034 feature-domain-feature-onboarding-contract 신규 domain slice가 module·test checklist를 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-035 feature-application-port-usecase-contract application port와 transaction runner architecture test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TRANSACTION-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-036 feature-domain-modeling-guardrails domain model forbidden dependency fixture가 실패한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-037 feature-business-rule-validation-contract validation ownership·mapper failure contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MAPPING-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-ERROR-ENVELOPE-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-038 feature-domain-event-outbox-contract broker-agnostic outbox와 duplicate execution test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-EVENT-BROKER-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-SCHEDULER-LOCK-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-039 feature-sample-removal-adoption-contract sample 제거 후 production module smoke test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-040 feature-skeleton-package-blueprint-contract Gradle module graph가 declared layout과 일치한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-041 feature-contract-registry-governance registry single-owner·schema·OpenAPI drift gate가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-ERROR-ENVELOPE-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-OPENAPI-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-042 feature-test-taxonomy-fixture-contract test level별 fixture가 실행되고 container 사용 정책을 지킨다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TESTCONTAINERS-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-TEST-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-043 feature-implementation-readiness-scorecard readiness 각 항목이 binary evidence link로 판정된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-BOOTSTRAP-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-044 feature-webhook-outbound-contract signature·replay·retry·observability contract test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-045 feature-streaming-response-contract 지원 protocol과 timeout·failure contract test가 고정된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-046 feature-resource-identifier-contract ULID format·PostgreSQL uuid persistence·SecureRandom test가 통과한다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-DATABASE-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-RANDOM-001@1 - planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-047 feature-application-query-bypass-contract query bypass의 허용 경계·mapping·transaction 영향과 검증 test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TRANSACTION-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MAPPING-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-035, WI-CA-SKELETON-OPERATIONAL-CONTRACT-012, WI-CA-SKELETON-OPERATIONAL-CONTRACT-024, WI-CA-SKELETON-OPERATIONAL-CONTRACT-007, WI-CA-SKELETON-OPERATIONAL-CONTRACT-006 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-048 feature-authentication-authorization-contract authentication·authorization ownership, error mapping, forbidden dependency test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-ERROR-ENVELOPE-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-ARCHTEST-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-008, WI-CA-SKELETON-OPERATIONAL-CONTRACT-005, WI-CA-SKELETON-OPERATIONAL-CONTRACT-018, WI-CA-SKELETON-OPERATIONAL-CONTRACT-014, WI-CA-SKELETON-OPERATIONAL-CONTRACT-022, WI-CA-SKELETON-OPERATIONAL-CONTRACT-001 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-049 feature-cachestore-multi-backend-router cache backend 선택·fallback·failure routing과 contract test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-TEST-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-024 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-050 feature-database-connection-pool-contract connection pool 설정·lifecycle·metric·failure gate가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-DATABASE-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-004, WI-CA-SKELETON-OPERATIONAL-CONTRACT-006, WI-CA-SKELETON-OPERATIONAL-CONTRACT-035, WI-CA-SKELETON-OPERATIONAL-CONTRACT-019 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-051 feature-dependency-vulnerability-management-contract scanner·severity·suppression·update·license 정책과 CI failure gate가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-028, WI-CA-SKELETON-OPERATIONAL-CONTRACT-030, WI-CA-SKELETON-OPERATIONAL-CONTRACT-029 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-052 feature-distributed-lock-contract lock provider·lease·transaction commit ordering과 failure test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-SCHEDULER-LOCK-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TRANSACTION-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-DATABASE-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-004, WI-CA-SKELETON-OPERATIONAL-CONTRACT-025, WI-CA-SKELETON-OPERATIONAL-CONTRACT-024, WI-CA-SKELETON-OPERATIONAL-CONTRACT-017, WI-CA-SKELETON-OPERATIONAL-CONTRACT-018 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-053 feature-messaging-multibroker-router broker 선택·routing·fallback과 core transport-neutrality test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-EVENT-BROKER-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-038 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-054 feature-notification-provider-spi notification provider SPI·routing·failure contract와 test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-053, WI-CA-SKELETON-OPERATIONAL-CONTRACT-049 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-055 feature-persistence-auditing-contract persistence audit actor·time·mapping·transaction contract test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TRANSACTION-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MAPPING-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-DATABASE-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-056, WI-CA-SKELETON-OPERATIONAL-CONTRACT-048, WI-CA-SKELETON-OPERATIONAL-CONTRACT-006, WI-CA-SKELETON-OPERATIONAL-CONTRACT-012, WI-CA-SKELETON-OPERATIONAL-CONTRACT-017 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-056 feature-runtime-context-propagation-contract runtime context capture·propagation·cleanup과 architecture/contract test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-LANGUAGE-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-TEST-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-ARCHTEST-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-002, WI-CA-SKELETON-OPERATIONAL-CONTRACT-001, WI-CA-SKELETON-OPERATIONAL-CONTRACT-025, WI-CA-SKELETON-OPERATIONAL-CONTRACT-027, WI-CA-SKELETON-OPERATIONAL-CONTRACT-022 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-057 feature-sample-portfolio-public-access sample public endpoint allowlist와 authenticated endpoint negative test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-TEST-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-048, WI-CA-SKELETON-OPERATIONAL-CONTRACT-021 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-058 feature-startup-failure-log-suppression suppressible startup failure 조건과 retained actionable error test가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-BOOTSTRAP-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-ERROR-ENVELOPE-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-001, WI-CA-SKELETON-OPERATIONAL-CONTRACT-017 planned
WI-CA-SKELETON-OPERATIONAL-CONTRACT-059 feature-static-analysis-quality-contract static analysis 도구·threshold·CI failure mapping과 fixture가 명시된다 DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1, DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-TEST-001@1 WI-CA-SKELETON-OPERATIONAL-CONTRACT-028, WI-CA-SKELETON-OPERATIONAL-CONTRACT-029, WI-CA-SKELETON-OPERATIONAL-CONTRACT-018 planned

24. Branch 실행 계획

Legacy reference (v1). 아래 link 목록과 공통 promotion 설명은 이력·navigation용이다. stable branch ID·decision pin·dependency의 SSOT는 위 Work Item Registry다.

모든 branch note는 아래 품질 기준을 만족해야 합니다.

Decision: 기본 선택값이 있는가?
Allowed: 허용되는 변형이 명확한가?
Forbidden: 금지 사항이 명확한가?
Required config/log/test: 구현자가 빠뜨리면 안 되는 필드가 있는가?
Failure condition: 어떤 상태면 build/review에서 실패인지 명확한가?
Wiki extraction target: canonical 문서로 승급될 위치가 정해져 있는가?

TODO는 작업 목록이 아니라 미완성 계약입니다. 각 TODO는 branch 완료 전에 아래 Work Item Contract로 재작성되어야 합니다.

field required rule
Decision yes 구현자가 선택해야 하는 기본값
Allowed yes 허용되는 예외와 조건
Forbidden yes 절대 금지되는 구현/문서 상태
Required registry update conditional error/env/header/log/metric/capability 변경 시 필수
Required contract test yes 계약 위반 시 실패해야 하는 테스트
Failure condition yes review/build에서 실패로 판정할 상태
Canonical extraction target yes wiki/projects 승급 위치

25. Default Decisions

Legacy reference (v1). 아래 default와 owner map은 세부 rationale·branch-local owner 설명을 보존한다. project-wide 결정의 현재 owner와 상속 기준은 ## 6.1 Project Decision Registry / 안정 결정 레지스트리다. branch-owned D-row는 project registry로 복제하지 않는다.

이 섹션은 branch 착수자가 자기 해석으로 갈라지지 않도록 하는 기본 결정값입니다. branch 작업 중 더 나은 기준이 발견되면 이 값을 바꾸되, 변경 사유와 대체 테스트 계약을 함께 남깁니다.

Blocking Defaults

아래 15개 항목은 모든 branch의 선행 default입니다. 이 표와 충돌하는 branch note는 해당 branch가 아니라 이 프로젝트 노트를 먼저 수정해야 합니다.

항목 기본 결정 SSOT branch 실패 조건
package layout Gradle multi-module을 기본으로 두고 domain-core / application-core / adapter-* / shared-contract / app-bootstrap / sample-portfolio 책임을 분리 feature-skeleton-package-blueprint-contract module boundary와 package responsibility가 혼재되어 새 기능 위치를 판정할 수 없음
transaction boundary Spring @Transactional을 application 구현체에 직접 두지 않고 TransactionPort 또는 TransactionalUseCaseRunner로 추상화 feature-application-port-usecase-contract application layer가 Spring transaction annotation을 직접 import
mapper tool 기본은 수기 mapper + record canonical constructor. MapStruct는 optional profile이며 generated code exemption 필요 feature-boundary-validation-mapping-contract mapper 도구가 branch마다 다르거나 generated code 예외가 architecture rule에 없음
error envelope schema envelope schema와 error.category enum은 foundation branch가 단일 owner feature-operational-error-observability-foundation business/schema/validation branch가 envelope field를 독자 정의
OpenAPI drift drift 집행 권한은 verification suite가 단일 owner, API/schema branch는 producer feature-contract-verification-test-suite OpenAPI snapshot과 실제 envelope가 불일치해도 build 통과
migration runner Flyway를 app startup에서 실행하되 readiness는 migration 완료 후에만 healthy. 운영에서 별도 job 전환 가능 feature-migration-startup-contract migration 실패 또는 진행 중 readiness가 healthy
scheduler/outbox lock single-instance 기본. multi-instance 활성화 시 DB advisory lock을 기본값으로 사용 feature-background-job-async-contract scheduled job/outbox publisher가 multi-instance에서 중복 실행 가능
broker Kafka 강제 안 함. core는 broker-agnostic outbox contract만 제공하고 Kafka는 optional adapter feature-domain-event-outbox-contract domain event가 Kafka transport type을 직접 가짐
circuit breaker/retry Resilience4j 기본, Spring Retry는 simple blocking retry에만 예외 허용 feature-outbound-http-client-baseline retry/circuit breaker metric 이름과 정책이 adapter마다 다름
container base image Temurin JRE slim 기본, distroless는 runtime debug/runbook 보강 후 허용 feature-container-runtime-contract base image가 branch마다 다르거나 non-root/JVM memory 기준이 없음
API versioning URI prefix /v1 기본, X-Api-Version은 compatibility 실험용 보조 header feature-api-contract-baseline 같은 endpoint가 path/header/media type versioning을 섞어 사용
idempotency key scope (authenticatedPrincipal, idempotencyKey, useCaseName) 기본, tenant 활성화 시 tenant를 앞에 추가 feature-rate-limit-idempotency-contract user 간 key collision 또는 use case 간 replay 오염 가능
rate-limit key authenticated는 principal 기준, unauthenticated는 IP + normalized route 기준. tenant 활성화 시 tenant를 prefix로 추가 feature-rate-limit-idempotency-contract tenant/user/API key/IP 기준이 branch마다 다름
bootstrap command ./gradlew bootstrap 기본. 없는 경우 ./gradlew test + docker compose up wrapper로 제공 feature-developer-experience-contract 신규 팀이 첫 실행 명령을 문서에서 판정할 수 없음
Testcontainers policy persistence/outbound integration test부터 강제, unit/architecture/contract test는 Testcontainers 금지 feature-test-taxonomy-fixture-contract contract test가 컨테이너 의존으로 느려지거나 CI 실패 원인을 흐림

SSOT Owner Map

동일 계약을 여러 branch가 다루더라도 owner는 하나입니다. owner 외 branch는 producer 또는 consumer로만 기록합니다.

새 결정 추가 전 본 표 grep 의무 — 동일 영역의 owner 가 이미 있으면 충돌 검토.

contract area single SSOT owner consumers/producers rule
OpenAPI / schema drift feature-contract-verification-test-suite api baseline, compatibility, schema serialization verification이 release-blocking 판정권을 가짐
idempotency key feature-rate-limit-idempotency-contract api baseline, transaction, outbox, tenant key shape와 replay semantics는 한 곳에서만 변경
DLQ / retry policy feature-background-job-async-contract outbox, outbound HTTP dead-letter abstraction은 background branch가 소유
error envelope schema feature-operational-error-observability-foundation business validation, schema serialization envelope field와 category enum은 foundation에서만 final
requestId/traceId/correlationId meaning feature-operational-error-observability-foundation distributed tracing, log management ID 의미와 required 여부는 foundation에서 final
sample-portfolio fixture feature-sample-domain-contract-fixture verification, DX, scorecard, onboarding sample scenario와 minimum model은 sample fixture branch만 변경
actuator/health endpoint shape feature-runtime-health-lifecycle-contract management actuator security runtime-health가 shape owner, security는 exposure policy owner
MDC/log key standard feature-operational-error-observability-foundation log management, metrics alerting key 이름은 foundation registry와 일치해야 함
HTTP status ↔ envelope error.code 매핑 raw/branch-notes/feature-operational-error-observability-foundation (registry error-codes.yamlhttp_status column) api-contract-baseline D11 (mapping consistency contract test producer) individual mapping 변경은 registry-governance 절차 + foundation branch SSOT
API versioning (/v1 URI prefix) raw/branch-notes/feature-api-contract-baseline D2/D6 api-compatibility-deprecation (Sunset header 발행 시점) path version 외 supplemental header (X-Api-Version) 만 허용
HTTP header registry (headers.yaml 15 rows) feature-api-contract-baseline (cross-owner: idempotency, tracing, tenant, compat, security 모두 cross-cite) tracing/tenant/security/compat 모든 branch 새 header 추가는 본 registry yaml + api-baseline branch 경유
HTTP method 지원/실패 분류 (D12 405/Allow, D13 HEAD/OPTIONS) raw/branch-notes/feature-api-contract-baseline D12/D13 (no counterpart — leaf) 405 응답 + Allow MUST, HEAD MUST 자동 mirror
PATCH content type + mapper raw/branch-notes/feature-boundary-validation-mapping-contract B2 (ArchUnit no_merge_patch_json_media_type_string enforced) api-contract-baseline D14 (정정 — content type 정책만 consume) RFC 7396 (merge-patch+json) / RFC 6902 (json-patch+json) 모두 미채택application/json only · absent/null/value 3-상태 wrapper
Conditional request (ETag / If-Match / If-None-Match / 304 / 412) raw/branch-notes/feature-api-contract-baseline D15 sample-portfolio fixture (WorkLogVersion 이 ETag derivation source) DB optimistic lock 과 HTTP 412 가 동일 conflict 의 두 표현
Response cache policy + Vary header raw/branch-notes/feature-api-contract-baseline D16 (HTTP header 정책) feature-cache-consistency-contract (cache layer 구현 SSOT) default Cache-Control: no-store, Vary 의무
Long-running operation (LRO) raw/branch-notes/feature-api-contract-baseline D17 (polling-only) webhook callback 패턴은 별도 feature-webhook-outbound-contract 202 + Location: /v1/operations/{id} + polling endpoint
Pagination index base + size cap raw/branch-notes/feature-api-contract-baseline D18 (no counterpart — leaf) page 0-indexed, size default 20 / max 100
Resource URL naming convention raw/branch-notes/feature-api-contract-baseline D19 ArchUnit/architecture branch (controller mapping 검증) plural + lowercase + AIP-122 regex
Sort parameter syntax raw/branch-notes/feature-api-contract-baseline D20 schema-serialization (field name case 정합) Spring Pageable native ?sort=field,direction
Filter parameter syntax raw/branch-notes/feature-api-contract-baseline D21 (no counterpart — leaf, 복잡 filter 는 future) flat key=value (equality only)
Cursor pagination shape raw/branch-notes/feature-api-contract-baseline D22 feature-security-operational-baseline (HMAC key rotation cross-link) opaque base64 + HMAC + 24h TTL
Bulk operation URL pattern raw/branch-notes/feature-api-contract-baseline D23 raw/branch-notes/feature-boundary-validation-mapping-contract B14 (BulkEnvelope.partial — async only), foundation (BATCH_PARTIAL_FAILURE — async only), raw/branch-notes/feature-api-contract-baseline D17 LRO 결합 (async batch 의 polling endpoint) AIP-136 colon-verb (:batchCreate) + AIP233-C7 sync MUST atomic + partial failure 는 async LRO 만
Response Date header raw/branch-notes/feature-api-contract-baseline D24 (no counterpart — leaf) Spring/Tomcat default 자동 발행, 비활성화 금지
CORS allowlist / preflight policy raw/branch-notes/feature-security-operational-baseline D9 raw/branch-notes/feature-api-contract-baseline D13 (OPTIONS preflight envelope 우회 정책 consume) wildcard + credentials 금지 (FETCH-CORS-C3 normative)
WWW-Authenticate / Server / X-Powered-By header suppression feature-security-operational-baseline api-contract-baseline API branch 는 forbid 만 cross-cite
JSON field naming case (camelCase vs snake_case) feature-schema-serialization-contract api-contract-baseline (envelope meta.* 가 camelCase 라는 cross-cite) Jackson default + project-internal 결정
Date/Time/Decimal serialization feature-schema-serialization-contract api-contract-baseline ISO-8601 UTC + BigDecimal HALF_UP 등
Webhook outbound contract (2026-05-31 신설) feature-webhook-outbound-contract (scaffolding 단계) api-contract-baseline (inbound API surface 와 분리) signature/replay/retry/observability — 결정 박힌 후 본 표 update
Streaming response (SSE/WebSocket/long-poll/chunked) (2026-05-31 신설) feature-streaming-response-contract (scaffolding 단계) api-contract-baseline (out of scope 분리) 1차 결정: 지원 여부 자체
Resource ID format (ULID 26-char Crockford base32) raw/branch-notes/feature-resource-identifier-contract D1~D19 api-contract-baseline (URL path variable), boundary (ArchUnit rules), idempotency (Idempotency-Key 별개 명시), log-management (PII 분류), security (SecureRandom 의무) ULID time-ordered + project §34 PostgreSQL uuid native + sample-portfolio WorkLogId = "01ARZ3NDEKTSV4RRFFQ69G5FAV"
General-purpose distributed lock provider (distributedLockProvider bean 메커니즘 / tx commit 정합 / lease 계약) (2026-06-12 신설) raw/branch-notes/feature-distributed-lock-contract D1~D8 background-job-async (scheduler/outbox 적용처 — consume), cache-consistency (Redis 분기 의존성 공유), env-driven-runtime-configuration (flag + presence 강제 owner) bean 이름·메커니즘·해제 vs commit 순서는 본 branch 단일 owner. cache stampede lock(CACHE_STAMPEDE_LOCK_TIMEOUT)은 cache branch 소유로 불변
Dependency vulnerability policy (SCA 스캐너 / CVSS 차단 임계값 / KEV override / suppression governance / 보안 update 자동화 / license scan) (2026-06-15 신설) raw/branch-notes/feature-dependency-vulnerability-management-contract D1~D10 ci-quality-gates (vuln scan gate wiring — consume), container-runtime (image scan wiring — 동일 severity 정책 consume), build-release-supply-chain (release-block posture + dependency-locking 선행조건 producer) scanner·severity·suppression·update·license 정책은 본 branch 단일 owner. ci-gates D5 의 OWNER_AMBIGUITY(scanner 미결) + supply-chain D2(severity)/D3(update) 의 UNSUPPORTED 스텁이 본 branch 로 위임 정합

Cross-Branch Decision Conflict Check Procedure

새 결정 추가 전 다음 절차 의무 (cross-branch SSOT 충돌 차단):

  1. 본 §25 SSOT Owner Map 의 contract area 컬럼 grep — 동일 영역의 owner 가 이미 있는지 확인.
    • 동일 owner 가 있으면: 본 branch 가 new owner 가 아닌 consumer/producer 로만 결정 가능.
    • 동일 owner 가 없으면: 본 branch 가 new owner 가 될 수 있음 — 그러나 주제어 다른 결정이 sibling branch 에 있을 수 있음 → 2번 진행.
  2. sibling branch grepgrep -rn "<주요 키워드>" raw/branch-notes/feature-*.md 로 sibling 의 §결정 사항 / §Decision Evidence Map / §Decisionized Work Items 에 동일 키워드 검색.
    • 예: PATCH 결정 추가 전 grep -rn "PATCH\|merge-patch" raw/branch-notes/feature-*.md 로 boundary branch B2 사전 발견 가능했음.
  3. 충돌 발견 시 적용 기준:
    • 검증 깊이 우선: ArchUnit / static rule / contract test 가 있는 결정이 SSOT.
    • 결정 도메인 우선: 결정이 어느 영역의 자연스러운 책임인지 — PATCH mapper 는 boundary 영역.
    • 시간 순서: 같은 깊이 + 같은 도메인이면 먼저 박힌 결정이 SSOT, 늦게 박은 것이 정정.
  4. 본 §25 표에 신규 row 추가 — 결정 박은 후 본 표에 owner + consumers/producers + rule 명시.

이 절차는 추후 /lint 명령 또는 wiki-adversarial-reviewer 가 자동 검사하도록 확장 가능 (현재는 수동 절차).

Multi-Instance Guardrail

이 skeleton의 core contract는 기본적으로 single-instance에서 완결됩니다. HPA, multi-replica scheduler, distributed rate limit, outbox publisher leader election, migration concurrent startup, distributed cache lock은 multi-instance contract package가 활성화될 때만 지원 범위에 들어옵니다.

6.1 안정 결정 레지스트리

Project contract v2의 project-wide decision SSOT. §25의 15개 blocking default와 §34 Stack Commitment를 stable ID로 pin한다.

Decision ID Revision Domain Decision Summary Status Owner Evidence
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001 1 module-layout Gradle multi-module에서 domain-core·application-core·adapter-*·shared-contract·app-bootstrap·sample-portfolio 책임을 분리한다 active raw/project-notes/ca-skeleton-operational-contract §25 Blocking Defaults package layout
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TRANSACTION-001 1 transaction application은 Spring transaction annotation 대신 TransactionPort 또는 TransactionalUseCaseRunner를 사용한다 active raw/project-notes/ca-skeleton-operational-contract §25 transaction boundary
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MAPPING-001 1 mapping 수기 mapper와 record canonical constructor가 default이며 MapStruct는 optional profile이다 active raw/project-notes/ca-skeleton-operational-contract §25 mapper tool
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-ERROR-ENVELOPE-001 1 error-envelope foundation이 envelope schema와 error.category enum의 단일 owner다 active raw/project-notes/ca-skeleton-operational-contract §25 error envelope schema
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-OPENAPI-001 1 openapi verification suite가 OpenAPI drift의 release-blocking 판정권을 소유한다 active raw/project-notes/ca-skeleton-operational-contract §25 OpenAPI drift
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MIGRATION-001 1 migration Flyway는 startup에서 실행하고 migration 완료 후에만 readiness를 healthy로 전환한다 active raw/project-notes/ca-skeleton-operational-contract §25 migration runner
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-SCHEDULER-LOCK-001 1 scheduler-lock single-instance가 default이며 multi-instance scheduler/outbox는 DB advisory lock을 사용한다 conditional-default raw/project-notes/ca-skeleton-operational-contract §25 scheduler/outbox lock
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-EVENT-BROKER-001 1 event-broker core는 broker-agnostic outbox를 제공하고 Kafka는 optional adapter로 둔다 active raw/project-notes/ca-skeleton-operational-contract §25 broker
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001 1 resilience Resilience4j가 default이며 Spring Retry는 simple blocking retry에만 허용한다 active raw/project-notes/ca-skeleton-operational-contract §25 circuit breaker/retry
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-CONTAINER-001 1 container Temurin JRE slim이 default이며 distroless는 debug/runbook 보강 후 허용한다 conditional-default raw/project-notes/ca-skeleton-operational-contract §25 container base image
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001 1 api-versioning URI prefix /v1이 default이며 X-Api-Version은 compatibility 실험용 보조 header다 active raw/project-notes/ca-skeleton-operational-contract §25 API versioning
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-IDEMPOTENCY-001 1 idempotency idempotency scope는 principal·key·useCase이며 tenant 활성화 시 tenant를 prefix한다 active raw/project-notes/ca-skeleton-operational-contract §25 idempotency key scope
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RATE-LIMIT-001 1 rate-limit authenticated는 principal, unauthenticated는 IP와 normalized route를 rate-limit key로 사용한다 active raw/project-notes/ca-skeleton-operational-contract §25 rate-limit key
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-BOOTSTRAP-001 1 bootstrap 신규 환경의 default 진입 명령은 ./gradlew bootstrap이다 active raw/project-notes/ca-skeleton-operational-contract §25 bootstrap command
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-TESTCONTAINERS-001 1 testcontainers Testcontainers는 persistence/outbound integration test에 사용하고 unit·architecture·contract test에서는 금지한다 active raw/project-notes/ca-skeleton-operational-contract §25 Testcontainers policy
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-LANGUAGE-001 1 stack-language application language는 Java 21 LTS다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix Language
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001 1 stack-framework framework는 Spring Boot 3.5.14다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix Framework
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-ORM-001 1 stack-orm ORM은 Spring Boot transitive Hibernate ORM 6.5.x다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix ORM
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-JSON-001 1 stack-json JSON stack은 Spring Boot transitive Jackson 2.18.x다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix JSON
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-DATABASE-001 1 stack-database database는 PostgreSQL 16 단일 stack이다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix DB
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-MIGRATION-001 1 stack-migration schema migration tool은 Spring Boot transitive Flyway다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix Migration
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001 1 stack-build build tool은 Gradle Groovy DSL이다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix Build tool
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-TEST-001 1 stack-test test framework는 JUnit 5다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix Test framework
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-ARCHTEST-001 1 stack-archtest architecture test는 archunit-junit5 1.3.0을 사용한다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix Architecture test
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-RANDOM-001 1 stack-random ULID·idempotency key·token 생성의 random source는 SecureRandom이다 active raw/project-notes/ca-skeleton-operational-contract §34 Stack Matrix Random source
area single-instance default multi-instance activation requirement
scheduler single worker only DB advisory lock 또는 ShedLock contract test
outbox publisher one publisher in app process publisher ownership lock + duplicate publish idempotency
rate limiter in-memory or app-local policy allowed only for local/dev Redis/distributed counter + tenant/principal key contract
migration runner one app startup runner platform-level one-shot job or migration lock verification
cache stampede local test policy only distributed lock or stale-while-revalidate policy
idempotency key concurrency DB unique constraint required serializable insert-or-read contract test

multi-instance를 지원한다고 말하려면 위 행 중 적용 영역의 contract test가 있어야 합니다. 없으면 문서와 README에 single-instance skeleton이라고 명시합니다.

Minimum Missing-Area Defaults

아래 영역은 full implementation이 없어도 skeleton default는 있어야 합니다.

area default owner branch
deployment manifest sync app shutdown timeout, terminationGracePeriodSeconds, preStop, readiness/liveness/startup probe 값을 한 표에서 관리 feature-container-runtime-contract
DSR delete/export request는 core domain out of scope이나 PII inventory, redaction point, audit log retention은 privacy branch가 관리 feature-data-retention-privacy-contract
feature flag runtime toggle은 optional. 기본은 env-startup flag이며 canary/runtime flag 도입 시 registry row 필요 feature-env-driven-runtime-configuration
signed artifact SBOM + image digest를 기본으로 하고, release branch에서 Cosign/SLSA provenance를 delivery target으로 둠 feature-build-release-supply-chain-contract
dependency upgrade Renovate 또는 Dependabot 중 하나를 선택하고 security PR은 CI quality gate와 연결 feature-build-release-supply-chain-contract
JWT key rotation JWKS refresh failure, stale key, unknown kid, rotation overlap window를 security failure catalog에 포함 feature-security-operational-baseline
JVM ergonomics -XX:MaxRAMPercentage=75, UTC timezone, OOMKilled vs JVM OOM 분류를 container/runtime branch가 소유 feature-container-runtime-contract
CORS allowlist + preflight cache seconds는 security branch owner, gateway override 시 mapping 필요 feature-security-operational-baseline
항목 기본 결정 예외 허용 조건 테스트 실패 조건
response envelope field success, data, error, meta 외부 gateway 표준이 이미 존재할 때만 adapter에서 변환 실패 응답에 error.code, error.category, meta.requestId 누락
error code naming category 기반 UPPER_SNAKE_CASE provider-specific code는 dependency.code에만 보관 raw exception class name을 code로 사용
repository capability annotation @UseCaseRepositoryAccess AOP 대신 ArchUnit/compile-time checker를 쓸 경우 이름만 변경 가능 선언 없는 write/bulk/sensitive repository 접근
env prefix application-owned key는 APP_ prefix 사용 Spring/infra 표준 env는 원래 이름 유지 동일 의미 env가 profile마다 다른 이름으로 존재
log schema OpenTelemetry semantic convention을 우선 참고하고 app-specific field는 app.*, error field는 error.*로 둠 수집기가 ECS를 강제하면 adapter mapping 문서 필요 trace/log/error field naming이 branch마다 다름
tracing implementation Micrometer Tracing + OpenTelemetry exporter 기준 exporter 미사용 local profile 가능 traceId가 inbound/outbound/async/log에서 연결되지 않음
optional adapter packaging optional module로 분리하고 disabled env가 기본 단순 문서 샘플은 sample source set 허용 disabled adapter bean이 기본 앱 시작에 필요
sample domain sample-portfolio 더 작은 fixture가 모든 계약을 검증할 때만 변경 sample 없이 boundary/repo/transaction/error 계약을 검증
OpenAPI drift generated OpenAPI snapshot + contract test mature openapi-diff 도구 도입 가능 schema와 실제 envelope/field가 불일치해도 build 통과
idempotency storage DB table 기반 key/result/status/ttl 저장 Redis는 optional adapter에서만 보조 저장소 retry 시 duplicate write 발생
migration tool Flyway 기본 조직 표준이 Liquibase일 때만 변경 migration 실패 후 readiness가 healthy
metric naming Micrometer naming + low-cardinality tag만 허용 수집기 표준 prefix가 있을 때 mapping userId/orderId 같은 high-cardinality tag 사용
alert severity P1, P2, P3 조직 on-call 표준 명칭 사용 가능 severity 없는 alert
secret manager 기본 계약은 env/secret file, prod는 external secret manager 연동 가능하도록 추상화 local은 .env 허용 prod에서 secret/config dump 노출
actuator management port prod/staging은 분리 권장, local/dev는 app port 허용 platform ingress가 별도 보호를 제공할 때만 단일 port prod에서 env/configprops 노출
multi-tenancy skeleton core는 out of scope, tenant header는 기본 거부 tenant branch에서 명시 활성화 tenant context 없이 tenant-scoped repository 접근
file upload/download sample v1에는 미포함, core contract만 제공 file branch에서 sample fixture 추가 가능 path traversal/content type/size limit 미검증
cache consistency core contract에 원칙을 두고 Redis optional adapter에서 구현 in-memory sample cache는 테스트 전용 cache miss를 장애로 분류하거나 invalidation 실패를 무시
domain onboarding template domain-core / application-core / adapter-* / shared-contract 기준으로 read/write module slice를 추가 read-only feature는 write/idempotency/outbox 구성을 생략 가능 controller/use case/domain/repository 중 하나만 단독 추가되어 계약 검증 불가
command/query split command use case와 query use case 분리 단순 admin endpoint도 명시적으로 하나를 선택 write use case가 query naming으로 transaction/capability를 우회
port naming inbound는 *UseCase, outbound는 *Port 조직 표준 이름이 있으면 branch에서 대체 가능 application이 infrastructure adapter 구현체를 직접 의존
domain event domain event와 integration event 분리 외부 발행이 없는 내부 event는 integration mapping 생략 가능 domain event가 Kafka/HTTP/Slack 같은 transport detail을 가짐
sample adoption sample-portfolio은 제거 가능한 fixture이며 새 도메인은 구조만 참고 교육용 프로젝트에서는 sample 유지 가능 production package가 sample package를 import
package blueprint domain-core / application-core / adapter-* / shared-contract / app-bootstrap / sample-portfolio 멀티모듈 기본 구조 사용 demo/readme용 single-module 축소형은 같은 responsibility mapping 보존 시 허용 domain/business code가 shared-contract 또는 adapter module에 들어감
registry governance error/env/header/log/metric/capability는 registry로 관리 외부 platform 표준이 있으면 mapping table 필수 문자열/enum이 문서나 구현에 ad hoc으로 흩어짐
test taxonomy unit/contract/architecture/slice/integration/smoke를 분리 작은 프로젝트는 디렉터리만 합칠 수 있음 contract test와 integration test가 섞여 실패 원인을 구분 못함
readiness score canonical 승급 전 scorecard 전 항목 통과 raw 초안 단계는 미통과 허용 미통과 항목이 있는데 100점 문서로 선언

26. Universal Acceptance Gate

각 branch는 완료 전에 아래 질문에 모두 답할 수 있어야 합니다. 하나라도 답하지 못하면 canonical 문서로 승급하지 않습니다.

1. 이 기준은 어떤 실패를 막는가?
2. 구현자가 선택해야 하는 기본값은 무엇인가?
3. 허용되는 예외는 무엇이며 조건은 무엇인가?
4. 절대 금지되는 것은 무엇인가?
5. 어떤 env/log/response/test field가 필수인가?
6. 어떤 테스트가 깨져야 이 계약 위반을 알 수 있는가?
7. sample-portfolio으로 검증 가능한가?
8. sample-portfolio 제거 후에도 skeleton core에 남는가?
9. 실제 도메인 feature가 이 기준을 그대로 따라갈 수 있는가?
10. 이 내용을 wiki/projects canonical 문서의 어느 섹션으로 승급할 것인가?

100점 기준은 문장 완성도가 아니라 contract 강제력입니다.

문서만 읽고도 구현 방향이 하나로 수렴하고,
테스트만 봐도 계약 위반을 감지할 수 있으며,
sample-portfolio을 제거한 뒤에도 실제 도메인 feature가 같은 구조로 들어갈 수 있어야 한다.

27. 100점 Readiness Scorecard

아래 항목 중 하나라도 No이면 이 skeleton은 100점이 아닙니다.

영역 질문 통과 기준
구조 새 도메인 feature의 위치가 명확한가? module blueprint와 onboarding slice가 일치
응답 모든 성공/실패 응답이 envelope를 따르는가? OpenAPI snapshot과 contract test로 강제
오류 error category/code/status/retryable/log level이 registry에 있는가? ad hoc error string 금지
경계 request/application/domain/response/filter mapper가 모두 있는가? 경계 우회 architecture test
예외 raw exception이 presentation까지 새지 않는가? leakage contract test
로그 필수 log field와 금지 field가 테스트되는가? log capture test
trace inbound/outbound/async/message trace가 연결되는가? propagation contract test
env profile별 env matrix와 fail-fast가 있는가? startup smoke test
repo use case capability와 repository capability가 매칭되는가? architecture/contract test
adapter 모든 dependency failure가 같은 언어로 분류되는가? adapter failure mapping test
domain domain이 framework-neutral한가? forbidden import test
sample sample-portfolio 제거 후 core가 살아 있는가? sample removal smoke test
CI contract violation이 release-blocking인가? CI quality gate
운영 alert/runbook/metric/log/trace가 연결되는가? operational runbook link
보안 token/PII/secret/body가 노출되지 않는가? privacy/log leakage test

28. Review Remediation Ledger

이 섹션은 2026-05-22 senior review의 지적을 100% 추적하기 위한 ledger입니다. Closed by default는 이 raw project note와 branch note에 기본값/owner/failure condition이 반영되었다는 뜻이고, 구현 완료를 뜻하지 않습니다.

Critical Defaults

review item closed by default owner branch required branch evidence
package layout Gradle multi-module Clean Architecture (domain-core, application-core, adapter-*, shared-contract, app-bootstrap, sample-portfolio) feature-skeleton-package-blueprint-contract module dependency rule + package blueprint + architecture rule
transaction boundary application responsibility via TransactionPort/TransactionalUseCaseRunner, no direct Spring transaction import feature-application-port-usecase-contract forbidden import test + write use case contract
mapper tool manual mapper + record canonical constructor; MapStruct optional with generated exemption feature-boundary-validation-mapping-contract mapper boundary test
error envelope schema SSOT foundation branch owns envelope/category/ID meanings feature-operational-error-observability-foundation envelope contract test
OpenAPI drift SSOT verification suite owns drift gate feature-contract-verification-test-suite generated snapshot + drift check
migration runner Flyway app startup default, readiness healthy only after migration success feature-migration-startup-contract migration failure startup/readiness test
scheduler/outbox lock single-instance default, DB advisory lock or ShedLock required for multi-instance feature-background-job-async-contract overlap/duplicate publish test
broker broker-agnostic outbox core, Kafka optional adapter feature-domain-event-outbox-contract transport-free domain event test
circuit breaker/retry Resilience4j default, Spring Retry limited exception feature-outbound-http-client-baseline retry/circuit metrics test
container base image Temurin JRE slim default; distroless requires runbook/debug proof feature-container-runtime-contract non-root + JVM memory smoke
versioning /v1 URI prefix default; X-Api-Version supplemental only feature-api-contract-baseline OpenAPI version path test
idempotency key scope (principal, key, useCaseName), tenant prefix if enabled feature-rate-limit-idempotency-contract duplicate replay/tenant collision test
rate-limit key authenticated principal; unauthenticated IP + normalized route; tenant prefix if enabled feature-rate-limit-idempotency-contract 429 envelope + key scope test
bootstrap tool ./gradlew bootstrap default feature-developer-experience-contract bootstrap smoke
Testcontainers policy integration tests only; unit/contract/architecture no container feature-test-taxonomy-fixture-contract test taxonomy ownership table

SSOT Closures

duplicated area single owner consumer rule
OpenAPI/schema drift feature-contract-verification-test-suite API/schema branches produce artifacts only
idempotency key feature-rate-limit-idempotency-contract transaction/outbox/API/tenant consume key shape
DLQ/retry policy feature-background-job-async-contract outbox/outbound map their failures into the common DLQ vocabulary
error envelope schema feature-operational-error-observability-foundation business/schema branches cannot add envelope fields
trace/request/correlation ID semantics feature-operational-error-observability-foundation tracing/log branches consume names and meanings
sample-portfolio fixture feature-sample-domain-contract-fixture verification/DX/scorecard/onboarding consume scenarios
actuator/health endpoint shape feature-runtime-health-lifecycle-contract management security controls exposure only
MDC/log key standard feature-operational-error-observability-foundation log/metric branches use registry names

Multi-Instance Closures

risk default closure required if multi-instance is claimed
distributed scheduler lock single worker only ShedLock or DB advisory lock test
outbox publisher leader election one publisher in app process publisher ownership lock + idempotent publish
distributed rate limit local/dev only Redis/distributed counter contract
migration concurrent startup one app startup runner platform job or migration lock proof
cache distributed lock/stampede local test policy only distributed lock or stale-while-revalidate proof
idempotency concurrent arrival DB unique insert-or-read concurrent replay test

Missing Area Closures

missing area default closure owner branch
deployment manifest sync app timeout, terminationGracePeriodSeconds, preStop, startup/readiness/liveness probes must share one table feature-container-runtime-contract
API gateway/WAF/Ingress gateway may reject TLS/request-size/WAF before app; app must document envelope bypass and log correlation feature-security-operational-baseline
DSR delete/export privacy branch owns DSR intake, identity verification, export/delete workflow, audit evidence feature-data-retention-privacy-contract
disaster recovery/restore drill backup without restore drill is non-compliant; quarterly local/staging restore smoke default feature-persistence-failure-baseline
feature flag system env-startup flags default; runtime/canary flags need registry row and owner feature-env-driven-runtime-configuration
signed artifact/SLSA/provenance SBOM + image digest baseline; Cosign signature and provenance are release targets feature-build-release-supply-chain-contract
dependency upgrade policy Renovate default, Dependabot allowed if org standard feature-build-release-supply-chain-contract
JWT key rotation/JWKS refresh unknown kid, stale JWKS, refresh failure, overlap window are explicit security failures feature-security-operational-baseline
JVM ergonomics -XX:MaxRAMPercentage=75, UTC, OOMKilled vs JVM OOM classification feature-container-runtime-contract
DB read replica/lag primary reads default; replica use requires max lag threshold and stale-read contract feature-persistence-failure-baseline
CORS preflight/origin allowlist explicit allowlist, credentials policy, max-age default, gateway override mapping feature-security-operational-baseline
antivirus/file scanning upload scanning is off by default; external gateway/worker/app-owner decision must be documented feature-file-resource-handling-contract

Conflict Closures

conflict closure
domain logger ban vs invariant diagnostics domain still has no logger; application translates invariant violation and logs client-safe reason code outside domain
@Transactional vs application independence direct Spring transaction import forbidden; transaction port abstraction required
tracing disabled vs required traceId generated opaque trace id remains in envelope; exporter/sampling may be disabled
migration readiness race startup/readiness remains unhealthy until migration success and startup validation complete

Self-Contradiction Closures

contradiction closure
Work Item Contract exists but TODOs stay vague branch notes must add Decisionized Work Items before canonical promotion; TODO list remains raw backlog only
scorecard 100점 but calculator out of scope scorecard branch owns manual formula and evidence table; automation is optional, formula is not
runbook link required but unverifiable runbook branch defines link format and CI/link-check smoke; broken placeholder links fail promotion

Phase A / B / C1 Closures (2026-05-22)

4차 audit 이후 다음 phase가 진행되었으며, 산출물은 본 문서와 ca-tmpl/docs/registries/ 하위 yaml로 분리됩니다.

phase scope 산출물 status
Phase A numeric conflict 15건, SSOT violation 7건, TODO drain 28+ 파일, 표 양식 자기모순(Work Item Contract 7-required → 4 mandatory + 3 conditional relax), 자기 중복 4건, intent clarification 5건 43 branch note 수정 closed
Phase B 7개 registry yaml 본문 작성 (총 196 rows, source-grounded) ca-tmpl/docs/registries/{error-codes,env-keys,secrets-classification,headers,mdc-keys,metrics,capabilities}.yaml closed
Phase C1 본 canonical contract 문서에 yaml SSOT reference 반영 + Phase A/B closures 기록 본 문서 §21 + §28 갱신, frontmatter last_reviewed: 2026-05-22 closed
Phase D1 test contract 정밀화 (VAGUE 38건 → IMPLEMENTABLE, PARTIAL 88건의 3개 공통 패턴(capability marker / disabled detection / claim parsing) 결정 박기) 43 branch note 정밀화 closed
Phase D2 runbook stub 5종 작성 (release-blocking 5 category 첫 운영 시나리오) ca-tmpl/docs/runbooks/*.md closed
Phase C2 ca-tmpl 실 skeleton 코드 (별도 git repo) build.gradle, application-*.yml, ArchUnit rules, TransactionPort, @UseCaseRepositoryAccess, capability enum, sample-portfolio entity/use case/fixture, Flyway script, OpenAPI snapshot, CI workflow, Cosign/SLSA, docker-compose.yml, .env.example (env-keys.yaml에서 generated) pending (external)

Phase A 세부 closures

Numeric conflicts (4차 audit L1 / 15건): executor await 25s→19s (background-job-async); database defaultREAD_COMMITTED (application-port-usecase, transaction-concurrency SSOT 위임); AUTHORIZATIONAUTHZ (business-rule-validation enum 정합); MDC 4 vs 6 rationale (background-job span_id 자동·user_principal opt-in); "9 base + 2 = 11" 통일 (contract-verification); tenant_id cardinality vs ULID 분리 (metric tag 미사용, mapping id/cohort bucket); error_code cardinality registry 동기화; audit log retention 단일 owner = data-retention; outbox claim isolation = READ_COMMITTED + SKIP LOCKED 명시; log 10% vs trace 1% sampling 의도 분리; idempotency 24h vs JWT rotation 24h invariant; NESTED/NEVER forbidden 일관; alert dedup 5분 vs P1 2분 noise 억제 의도; file size 3계층 defense-in-depth (Spring 10MB / global 12MB / gateway 20MB); outbound HTTP shutdown retry suppression.

SSOT violations (4차 audit L1 / 7건): audit retention 단일 owner = feature-data-retention-privacy-contract (log-management는 형식만 owns); outbox claim transaction isolation 명시 = feature-domain-event-outbox-contract; TaskDecorator SSOT = feature-background-job-async-contract (tenant/security 모두 consumer); security ↔ secrets 양방향 cross-link; runtime-health ↔ integration-adapter 양방향 cross-link; identifier 표기 layer mapping (MDC snake_case / envelope camelCase / HTTP header kebab-case) = feature-distributed-tracing-contract; flaky quarantine SSOT = feature-ci-quality-gates-contract (test-taxonomy consumer).

TODO drain (28+ 파일): stale planned TODO를 표 row link 또는 제거. needs-confirmation 2건 의도적 retain (verification PII forbidden 구현 메커니즘 / scorecard real-domain dry-run checklist SSOT 분담).

Self-duplicates 해소 (4건): transaction-concurrency isolation 2회→1회, management-actuator-security prod allowlist 2회→final list 1회, developer-experience DX Defaults 표 deprecated → Decisionized SSOT, ci-quality-gates Gate Matrix → Gate Ownership Matrix SSOT.

표 양식 자기모순: feature-architecture-enforcement-rules의 Work Item Contract 메타 표를 "7 required" → "4 mandatory (Decision/Allowed/Forbidden/Required contract test) + 3 conditional (Required registry update / Failure condition / Canonical extraction target)"로 relax. 14+ 파일의 5-column 표가 더 이상 자기모순 아님.

Intent clarifications (5건): log 10% vs trace 1% sampling 의도 분리 (운영 진단 vs cost 제어), idempotency TTL ≤ JWT rotation overlap window invariant, negative cache 60s vs eventual consistency window 5s 독립축, alert dedup 5분 + P1 2분 noise 억제, file size 3계층 defense-in-depth.

Phase B 세부 closures

7개 yaml 본문 작성 결과:

yaml rows 주요 정합 포인트
error-codes.yaml 49 category 분포 TRANSIENT_DEPENDENCY 15 · AUTH 8 · INTERNAL 8 · VALIDATION 6 · CONFLICT 4 · AUTHZ 3 · DATA_INTEGRITY 3 · RATE_LIMIT 1 · PERMANENT_DEPENDENCY 1 · NOT_FOUND 0. runbook coverage 100%.
env-keys.yaml 51 15개 영역. APP_ prefix 강제. reload_policy: restart-only default. classification cross-link with secrets-classification.yaml.
secrets-classification.yaml 15 secret 6 / sensitive-config 4 / public-config reference 5. rotation policy 5종 (restart-only / dual-bind-60s / overlap-24h / salt-rotation-90d / manual). prod sentinel prefix __LOCAL_DEV_ 검증.
headers.yaml 15 naming 정합 (kebab/lowercase/W3C). direction inbound 3 / outbound 7 / both 5. mdc_key + envelope_meta_field cross mapping 4쌍.
mdc-keys.yaml 19 foundation core 6 + log extension 13. propagation matrix (http 5 / async 5 / message 4 / none 14). cardinality_safe_for_metric flag로 metric tag 적격 9 / 부적격 10 분리.
metrics.yaml 25 Micrometer dot.case + unit suffix. cardinality bounds 강제. P1/P2/P3 정량 threshold. high-cardinality forbidden tag 0건.
capabilities.yaml 7 enforcement ArchUnit SSOT (AOP forbidden). BULK_WRITE threshold N>100. EXTERNAL_OUTBOUND_ALLOWED의 outbox in-process 제외 명시.

품질 정합:

  • 모든 row에 source branch + line 인용 yaml comment.
  • 추측 금지 원칙 준수 (source에 명시되지 않은 row 0개).
  • Cross-registry 정합 (header ↔ MDC ↔ envelope, env ↔ secrets, capability ↔ repository-access ↔ TransactionPort).
  • Runbook coverage 정책 100% (error-codes.yaml row 검증).
  • 명명 규칙 일관: error UPPER_SNAKE / env APP_ prefix / MDC snake / header kebab / W3C lowercase / metric dot.case.

Phase C1 closures (this update)

  • §21 Contract Registry 본문 6개 inline 표를 yaml SSOT reference + 요약 7개 subsection으로 재구성. inline 표의 stale category 명명(AUTHENTICATION/AUTHORIZATION/PERSISTENCE/DEPENDENCY/MESSAGE/CACHE/NOTIFICATION)을 foundation enum(AUTH/AUTHZ/DATA_INTEGRITY/TRANSIENT_DEPENDENCY/PERMANENT_DEPENDENCY)으로 정합. 더 이상 inline ≠ yaml 충돌 없음.
  • §28에 Phase A/B/C1 closures 추가. Phase D1/D2/C2는 pending으로 명시.
  • Header note(> 이 문서는...)에 phase 진척 한 줄 추가.
  • frontmatter last_reviewed: 2026-05-22로 갱신.

Phase D1 closures (2026-05-22)

Test contract 정밀화 + cross-cutting 결정 + needs-confirmation 해소.

VAGUE → IMPLEMENTABLE (38건):

owner branch item 수 정밀화 패턴
feature-implementation-readiness-scorecard 6 각 readiness 기준을 yaml registry row count + CI step grep + manual evidence column으로 측정 가능하게 (scorecard는 onboarding dry-run consume only — SSOT는 feature-domain-feature-onboarding-contract)
feature-operational-runbook-contract 4 alert payload field 명시 + runbook link target file 존재 verify + placeholder regex 검출
feature-test-taxonomy-fixture-contract 3 PR diff regex로 contract/architecture test 동반 변경 강제 + sample fixture prod profile 누출 검출
feature-contract-verification-test-suite 2 ArchUnit으로 contract test의 도메인 import 금지 + 9 base contract test enumeration
feature-developer-experience-contract 2 fresh-clone-smoke CI job + verifyReadmeCommands Gradle task
feature-container-runtime-contract 3 server.shutdown=graceful property verify + temp cleanup 3 trigger + JVM OOM exit code 검출
feature-file-resource-handling-contract 2 TempFileCleanupContractTest 3 trigger + antivirus position branch note grep
feature-env-driven-runtime-configuration 1 @FeatureFlag/APP_FEATURE_* row 존재 verify
feature-secrets-config-source-contract 1 @RefreshScope bean 금지 verify
feature-ci-quality-gates-contract 3 workflow yaml의 needs/if gate + openapi-diff exit code + sample-removal-smoke job verify
feature-background-job-async-contract 2 ApplicationListener bean verify + ShedLock LockProvider 등록 verify
feature-cache-consistency-contract 2 @Cacheable sync=true ArchUnit + RedissonClient bean verify when multi-instance
feature-domain-modeling-guardrails 2 @ValueObject 생성자 protection + @AggregateRoot setter visibility ArchUnit
feature-domain-event-outbox-contract 1 OutboxPublisherLeaderElectionContractTest 2-context dedup verify
feature-security-operational-baseline 1 SecurityFilterChain.getFilters() snapshot diff
feature-management-actuator-security-contract 1 branch ownership boundary ArchUnit

PARTIAL 공통 패턴 결정 (3종):

패턴 owner branch 결정
capability marker feature-repository-access-permission-contract Java annotation @UseCaseRepositoryAccess(value=Capability[]), retention RUNTIME, target METHOD. Capability enum은 capabilities.yaml SSOT와 1:1. consumer는 annotation consume only.
disabled adapter detection feature-integration-adapter-templates 3-layer: (1) startup Spring @ConditionalOnProperty, (2) build-time ArchUnit noClasses().that().resideInAPackage("..application..").should().dependOnClassesThat().resideInAPackage("..adapters.{disabled}.."), (3) runtime fail-fast AdapterDisabledException. adapter 추가 시 env-keys.yaml에 row 필수.
claim parsing (multi-instance) feature-env-driven-runtime-configuration env APP_MULTI_INSTANCE_ENABLED boolean. true 시 ShedLock + Redisson + outbox SKIP LOCKED + distributed rate limiter + platform migration job 5종 contract test 모두 활성 강제. 6개 branch가 consume.

needs-confirmation closures (2건):

항목 결정
PII/token/body log forbidden 구현 메커니즘 structured field whitelist + Logback masking 이중 layer. (1) Logback %mask converter (regex `(?i)(token
scorecard real-domain dry-run checklist SSOT SSOT = feature-domain-feature-onboarding-contract의 New Domain Module Slice + Read/Write Difference Table. scorecard는 consume only.

Phase D2 closures (2026-05-22)

Release-blocking 5 category에 대한 runbook stub 5종 작성.

파일 category error_codes 적용 severity
ca-tmpl/docs/runbooks/auth-token-rotation-failure.md AUTH AUTH_TOKEN_EXPIRED, AUTH_KID_UNKNOWN, AUTH_JWKS_UNAVAILABLE, AUTH_TOKEN_INVALID_SIGNATURE P1
ca-tmpl/docs/runbooks/authz-cross-tenant-violation.md AUTHZ AUTHZ_INSUFFICIENT_PERMISSION, AUTHZ_TENANT_MISMATCH P2/P1
ca-tmpl/docs/runbooks/rate-limit-exceeded.md RATE_LIMIT RATE_LIMIT_EXCEEDED, IDEMPOTENT_IN_FLIGHT P3/P2
ca-tmpl/docs/runbooks/internal-error-spike.md INTERNAL INTERNAL_ERROR, INTERNAL_AUTH_MISCONFIGURATION, JVM_OOM P1
ca-tmpl/docs/runbooks/dependency-unavailable.md TRANSIENT_DEPENDENCY + PERMANENT_DEPENDENCY DEPENDENCY_TIMEOUT/CONNECT_FAILED/DNS_FAILED/CIRCUIT_OPEN/5XX_SERVER, CACHE_UNAVAILABLE, DB_UNAVAILABLE P1/P2

모든 runbook stub은 다음 7 section 표준 구조: Trigger / First Response (5분 이내) / Diagnosis / Mitigation / Escalation / Recovery·Verification / Related. frontmatter에 status: stub 명시 — 도메인 도입 시 실제 운영 사례·임계·dashboard URL로 보강 필요.

error-codes.yaml의 모든 release-blocking row의 runbook_link field가 위 5 파일 중 1개로 resolve됨을 verify (Phase D2 contract test). 미resolve 시 fail.

Pending (Phase D 이후)

pending item reason owner
canonical 승급 (wiki/projects/ 본격 진입) Phase D 완료 후 본 문서를 wiki/projects/ca-skeleton-operational-contract.md로 이동 + status: verified. registries/runbooks는 ca-tmpl repo로 이전됐으므로 wiki/projects/ca-tmpl/ subdirectory 불요, flat 위치로 승급. Phase D 완료 시점
ca-tmpl 실 코드 (Phase C2) 별도 git repo. registry yaml을 consume하는 generated constants build task 포함 external
외부 근거 wiki/concepts/ 합성 (Phase E) §29의 6개 topic을 각각 wiki/concepts/{topic}.md canonical 문서로 합성 (concept-template 형식, status draftreviewed) Phase E 별도

29. 외부 근거 / 대안 조사 인덱스 (2026-05-22)

본 contract의 6개 핵심 결정에 대해 외부 source(공식 문서·RFC·대기업 기술블로그·GitHub repo)를 조사하여 raw/official-docs/raw/company-tech-blogs/에 raw 54개 파일로 저장. 각 raw 파일은 owning branch-note와 양방향 wikilink로 연결됨. 비교 분석은 추후 wiki/concepts/ 합성 단계(Phase E)에서 6개 concept 문서로 정리.

Topic 1 — Architecture Layout

  • ca-tmpl 결정: Gradle multi-module Clean Architecture / Hexagonal boundary (domain-core, application-core, adapter-*, shared-contract, app-bootstrap, sample-portfolio)
  • 대안 조사: feature-first package / layer-first / hexagonal pure / Spring Modulith / onion
  • Owning branch-notes:
  • raw 12개: branch-note의 "외부 근거" 섹션에 full list
  • 비교 핵심: ca-tmpl Phase C2는 module boundary로 application/domain과 adapter를 물리 분리한다. buckpal은 feature/package 내부 port-adapter 책임 분리 참고로 유지하고, Spring Modulith는 기본값이 아니라 향후 module verification 보강 대안으로 둔다. layer-first는 초기 학습 비용 최저지만 도메인 증가 시 응집도 폭락.

Topic 2 — Transaction Boundary

  • ca-tmpl 결정: TransactionPort + TransactionalUseCaseRunner abstraction (@Transactional 직접 import forbidden)
  • 대안 조사: TransactionPort (baseline, ca-tmpl) / @Transactional direct / TransactionTemplate programmatic / Functional Resource monad / Custom TransactionInterceptor AOP
  • Owning branch-notes:
  • raw 8개: branch-note 외부 근거 섹션 참조
  • 비교 핵심: ca-tmpl은 "Spring 의존 숨김" 진영(소수파). 다수파는 @Transactional 직접 부착(testability 낮지만 boilerplate 최저, Reflectoring 표준 baseline). Functional monad는 testability 최고지만 팀 학습 비용 큼. UNIL 팀이 2024-05에 ca-tmpl과 동일 진화 경로(@Transactional → output port + TransactionTemplate)를 거친 사례 존재.

Topic 3 — Outbox Pattern

  • ca-tmpl 결정: DB outbox table polling + FOR UPDATE SKIP LOCKED (PostgreSQL/MySQL 양쪽)
  • 대안 조사: SKIP LOCKED polling (baseline) / Debezium CDC / Kafka Connect outbox SMT / Dual-write (금지, negative reference) / Event sourcing / Spring @TransactionalEventListener (in-process only) / Netflix DBLog (극단 자체 CDC)
  • Owning branch-notes:
  • raw 10개: branch-note 외부 근거 섹션 참조
  • 비교 핵심: polling lag vs CDC 인프라 비용이 결정 축. ca-tmpl 가정 = lag 수 초 허용 + Kafka Connect 운영 인력 부재 + DB가 SSOT. 가정 깨지면 Debezium migration (Wix 사례). event sourcing은 "대안"이라기보다 도메인 모델 자체 교체. dual-write는 negative reference (outbox 도입 근거).

Topic 4 — API Error Envelope

  • ca-tmpl 결정: custom envelope ({success, data, error.{code, category, message, retryable, details}, meta}), ProblemDetail(RFC 7807) 명시적 forbidden
  • 대안 조사: Custom envelope (Stripe/GitHub/Toss 진영) / RFC 7807 ProblemDetail / Google rpc.Status (gRPC-derived) / JSON:API errors / GraphQL errors array
  • Owning branch-notes:
  • raw 8개: branch-note 외부 근거 섹션 참조
  • 비교 핵심: ca-tmpl의 success flag + retryable 1급은 어떤 표준에도 없음. Google rpc.Status만 retryable을 detail로 가짐. ProblemDetail은 실패 전용 평면이라 ca-tmpl의 success/error 대칭 요구와 구조적 충돌. → ca-tmpl이 ProblemDetail을 거부한 trade-off: 표준 lock-in 회피 + success/error 대칭 + 운영 메타 1급화.

Topic 5 — Idempotency Key Design

  • ca-tmpl 결정: triple scope (authenticatedPrincipal, idempotencyKey, useCaseName) + DB table + 24h TTL + 200ms in-flight wait → 409 IDEMPOTENT_IN_FLIGHT + fingerprint mismatch → 422 IDEMPOTENT_REQUEST_MISMATCH
  • 대안 조사: Stripe v1 pair (account, key) / Stripe v2 triple (account, API, key) / Square endpoint-scoped / PayPal (req-id, API call type) 45일 TTL / 토스 4-tuple (account, key, URL, method) 15일 TTL / AWS Powertools content-hash / GitHub no-API-level dedup / Brandur Postgres locked_at lock
  • Owning branch-notes:
  • raw 9개: branch-note 외부 근거 섹션 참조
  • 비교 핵심: ca-tmpl triple은 Stripe v1보다 보수적, Stripe v2/Square/Toss와 동급. TTL 24h가 모든 reference 중 가장 짧음(스토리지 비용·키 추측 공격면 최소). 200ms wait는 in-flight retry 친화적(Brandur lock의 변형). fingerprint 422는 IETF draft-07 권고 정합. "Stripe pair보다 무조건 안전"이라는 단정은 금지 — v1 한정 비교일 뿐.

Topic 6 — Multi-tenancy Isolation

  • ca-tmpl 결정: opt-in (APP_TENANT_ENABLED=true 시만 활성) + shared DB + tenant_id column + ULID 형식 + JWT claim 우선 + X-Tenant-Id header admin only
  • 대안 조사: shared DB + tenant_id (baseline, AWS Pool model) / subdomain-based resolution / JWT claim only / schema-per-tenant (Hibernate SCHEMA strategy, Stripe Citus) / database-per-tenant (AWS Silo model) / Hybrid (Azure Deployment Stamps, tier-based)
  • Owning branch-notes:
  • raw 9개: branch-note 외부 근거 섹션 참조
  • 비교 핵심: ca-tmpl의 opt-in + shared DB + tenant_id는 B2B 초기 단계 적합 (tenant 수 수십수백). migration trigger 3가지: (a) 규제(금융/의료) isolation 강제 → schema-per-tenant, (b) tenant 수 수백수천 + 단일 row 수 수억 → schema-per-tenant 또는 hybrid, (c) enterprise tier 등장 시 isolation 가격화 → db-per-tenant.

Group G-A — 관측 (Observability) — 4 branches, 11 raw

  • Owning branch-notes: raw/branch-notes/feature-log-management-contract, raw/branch-notes/feature-metrics-alerting-contract, raw/branch-notes/feature-distributed-tracing-contract, raw/branch-notes/feature-operational-runbook-contract
  • 대안 조사 (sub-topic별):
    • Log: ca-tmpl(structured JSON + Logback masking + prod 10% sampling) vs ECS schema / OpenTelemetry log signal / Log4j2 / Loki·Datadog SaaS
    • Metric: ca-tmpl(Micrometer dot.case + Prometheus + P1/P2/P3 + cardinality bounds) vs StatsD push / Datadog APM / OTel metrics / CloudWatch / SLO burn-rate
    • Tracing: ca-tmpl(W3C traceparent + Micrometer Tracing + prod 1%) vs B3 Zipkin legacy / Datadog APM / AWS X-Ray / Tail-based sampling / Adaptive sampling
    • Runbook: ca-tmpl(runbook:// scheme + repo path + link-check smoke) vs Confluence runbook / PagerDuty Runbook Automation / Auto-remediation
  • 비교 핵심: 자체 JSON schema + Logback masking은 minimal core + JVM stdout 친화. OTel log signal은 trace correlation 강점이나 2024 ecosystem maturity 낮음. SLO burn-rate alert는 traffic 무관 일관 severity이지만 정식 SLO 수립 후 단계. W3C tracecontext + Micrometer Tracing은 vendor-neutral, B3은 64-bit non-호환으로 forbidden. runbook:// git markdown은 drift 방지 + PR review로 SaaS runbook 대비 강점.

Group G-B — 보안 baseline — 3 branches, 12 raw

  • Owning branch-notes: raw/branch-notes/feature-security-operational-baseline, raw/branch-notes/feature-management-actuator-security-contract, raw/branch-notes/feature-secrets-config-source-contract
  • 대안 조사:
    • Security baseline: ca-tmpl(JWT Resource Server + AuthN/AuthZ matrix 12행 + JWKS 10min + clock skew 60s) vs Session+cookie / OAuth2 Authorization Code+PKCE / mTLS / API key+HMAC (AWS SigV4) / OPA policy engine
    • Actuator: ca-tmpl(management port 9001 + prod allowlist) vs Single port + path ACL / mTLS / Network ACL only / Service mesh (Istio)
    • Secrets: ca-tmpl(prod=secret manager OR mounted env + restart-only rotation + HMAC salt 90d) vs AWS Secrets Manager auto-rotation / HashiCorp Vault dynamic secrets / K8s Secret + external-secrets-operator / Doppler·1Password SDK / Plain env (rejected)
  • 비교 핵심: JWT Resource Server는 stateless 확장성 우위 vs session, revocation은 JWKS rotation으로 일부 회수. mTLS는 sender-constrained라 강하지만 PKI 운영 비용 큼. OPA는 외부 policy engine으로 정책-코드 분리 강점이나 AUTHZ 2종에는 in-process 충분. Vault dynamic은 short lease 보안 우위지만 ca-tmpl @RefreshScope 금지와 정면 충돌. AWS Secrets Manager auto-rotation이 dual-bind 60s 패턴과 정합.

Group G-C — Data layer — 3 branches, 11 raw

  • Owning branch-notes: raw/branch-notes/feature-persistence-failure-baseline, raw/branch-notes/feature-cache-consistency-contract, raw/branch-notes/feature-outbound-http-client-baseline
  • 대안 조사:
    • Persistence: ca-tmpl(SQLState 9-row matrix + OSIV off + Hikari alert + read replica lag threshold) vs Spring Data JPA default less-granular / R2DBC reactive / JOOQ SQL-first / 직접 JDBC + classifier / CockroachDB·Spanner·Aurora-specific
    • Cache: ca-tmpl(cache-aside + Caffeine local + Redisson RLock distributed + after-commit invalidation + 5s window) vs Write-through / Write-behind / Read-through / Hazelcast vs Redis / Stale-while-revalidate
    • Outbound HTTP: ca-tmpl(Spring RestClient + Resilience4j + timeout 2s/5s/10s + retry default disabled + CB) vs RestTemplate legacy / WebClient reactive / Feign·OpenFeign / OkHttp+Retrofit / Hystrix (deprecated)
  • 비교 핵심: SQLState matrix는 Spring DataAccessException hierarchy 위에 SQLState 입힌 형태로 임의 분류 아님. OSIV는 Hibernate 권위자(Vlad Mihalcea)도 anti-pattern 명시. cache-aside는 application owns invalidation으로 실패 가시성 강점. Resilience4j는 Spring 공식 maintenance 정책 정합(RestTemplate maintenance-only, Hystrix deprecated). WebClient는 다른 runtime model이라 MVC baseline에 강제 시 event-loop blocking risk. Stripe은 retry default-on이지만 idempotency-key 보장 전제.

Group G-D — Runtime / Lifecycle — 3 branches, 12 raw

  • Owning branch-notes: raw/branch-notes/feature-container-runtime-contract, raw/branch-notes/feature-runtime-health-lifecycle-contract, raw/branch-notes/feature-migration-startup-contract
  • 대안 조사:
    • Container: ca-tmpl(Temurin JRE slim + MaxRAMPercentage=75 + UTC/UTF-8 + graceful shutdown 20s+5s+35s) vs Distroless (Google) / Alpine + GraalVM / GraalVM native-image / Spring Boot Native / Multi-stage debug variant
    • Runtime health: ca-tmpl(liveness/readiness/startup 분리 + Required Optional Dependency Matrix + UTC + NTP drift >5s) vs Single /health legacy / Custom HealthIndicator / Spring Actuator Groups / Service mesh health (Istio·Consul)
    • Migration: ca-tmpl(Flyway + readiness gated + exit codes 78/70/71/72 + prod repair forbidden) vs Liquibase XML/YAML / Hibernate hbm2ddl (anti-pattern) / Init container in K8s / Separate migration job / Atlas·Tern (schema-as-code)
  • 비교 핵심: Temurin JRE slim은 운영 친숙도/디버깅 우선. Distroless는 보안 surface 축소하지만 in-container 디버깅 손실. GraalVM native-image는 cold start/메모리 우위지만 reflection 비용 + peak throughput 손실 (우아한형제들도 hybrid 채택). K8s 공식 + Spring Actuator Groups가 ca-tmpl 3-endpoint 분리와 정합. Flyway 공식이 prod repair/baseline_on_migrate/out_of_order 위험성을 명시 → ca-tmpl forbidden의 직접 근거. multi-instance에서는 K8s Job 또는 migration lock이 init container보다 race 회피에 우월.

Group G-E — DevOps / CI — 3 branches, 9 raw

  • Owning branch-notes: raw/branch-notes/feature-ci-quality-gates-contract, raw/branch-notes/feature-build-release-supply-chain-contract, raw/branch-notes/feature-developer-experience-contract
  • 대안 조사:
    • CI: ca-tmpl(Gate ownership matrix 20 rows + flaky quarantine 14d + OpenAPI snapshot diff + Trivy) vs Jenkins / GitLab CI vs GitHub Actions / CircleCI·Buildkite / Drone CI / Tekton (k8s-native)
    • Supply chain: ca-tmpl(Cosign keyless + SLSA + Gradle dependency-locking + SemVer+sha + reproducibility) vs GPG signing legacy / Notary v1 / in-toto attestations / JFrog Artifactory provenance / Sigstore for non-container
    • DX: ca-tmpl(./gradlew bootstrap + Temurin 21 LTS + Testcontainers integration + markdown-link-check) vs make bootstrap / docker compose up only / devcontainer (VSCode·Codespaces) / Nix flake / mise·asdf
  • 비교 핵심: GitHub Actions needs: + if: success()가 ca-tmpl contract gate 모델과 정확히 맞물림. Tekton/Jenkins는 k8s 인프라/plugin 의존도로 skeleton 단계에 과함. Cosign keyless signature 누락만 차단으로는 부족 — identity 매칭 정책(--certificate-identity)이 추가 필요(branch note 보강 후보). Flaky quarantine은 Spotify/Google/MS 인정 vs Fowler 반대 — ca-tmpl 14d sunset이 절충안. mise/asdf는 .tool-versions 표준, SDKMAN은 .sdkmanrc — branch note "또는" 표현은 drift 위험 내포.

Group G-F — API evolution & schema — 2 branches, 8 raw

  • Owning branch-notes: raw/branch-notes/feature-api-compatibility-deprecation-contract, raw/branch-notes/feature-schema-serialization-contract
  • 대안 조사:
    • Compatibility: ca-tmpl(90d public + 30d internal migration window + breaking change catalog 7행 + Sunset header) vs Stripe date-based versioning (no removal, freeze) / Twitter Tier-based (legacy/current/beta) / Microsoft REST API versioning policy / GitHub preview API headers / Spring HATEOAS (links over versions)
    • Schema: ca-tmpl(ISO-8601 offset UTC + BigDecimal scale 2 HALF_UP + unknown field strict inbound·tolerant outbound + null/empty/missing 분리) vs Jackson default lenient / Avro·Protobuf strict typing / JSON Schema validation / Smithy (AWS API modeling) / OpenAPI 3.1 spec
  • 비교 핵심: Stripe(freeze forever) vs ca-tmpl(90d/30d window) vs GitHub(24mo EOL + 410 Gone): 외부 컨슈머 규모와 운영 비용 trade-off. ca-tmpl internal-first면 90d 합리, EOL 응답 코드(410 Gone)가 catalog에 누락. Google AIP-180은 enum value 제거도 금지 → ca-tmpl narrow enum = breaking, new version 결정과 부분 정합. Sunset(RFC 8594) + Deprecation 헤더는 함께 보내야 정합. Protobuf reserved(field number/name 재사용 차단)가 JSON 환경에서 ca-tmpl이 가장 크게 보강할 부분. Avro full-compatibility는 schema registry 자동 검사 강력하지만 outbox/event 한정 도입 권장.

Group G-G — Skeleton governance — 4 branches, 11 raw

  • Owning branch-notes: raw/branch-notes/feature-contract-registry-governance, raw/branch-notes/feature-contract-verification-test-suite, raw/branch-notes/feature-test-taxonomy-fixture-contract, raw/branch-notes/feature-implementation-readiness-scorecard
  • 대안 조사:
    • Registry governance: ca-tmpl(markdown SSOT + YAML/generated constants + 7-column schema) vs Code-only enums / Protobuf·Smithy as registry / ArchUnit annotations as registry / Database-stored registry / @ConfigurationProperties as registry
    • Verification: ca-tmpl(11 release-blocking gates + JSON snapshot + Pact CDC out-of-scope) vs Pact CDC / Spring REST Docs / Spring Cloud Contract / Hoverfly·WireMock service virtualization / PostgreSQL diff
    • Test taxonomy: ca-tmpl(6 levels + Testcontainers from integration + src/testFixtures + 5min budget) vs Classic test pyramid / Test trophy (Kent Dodds) / Honeycomb (Spotify) / Fitness functions
    • Scorecard: ca-tmpl(binary pass/fail + 15 area + 1:1 branch evidence) vs OpenTelemetry Maturity Model / AWS Well-Architected Framework / CIS Benchmark scoring / SLSA build level scoring / CMMI maturity
  • 비교 핵심: ca-tmpl branch note 결정 라인이 사실상 mini-ADR로 동작 (Status=status_label, Context=목표/WHY, Decision=결정 사항, Consequences=테스트 계약) — 별도 ADR 파일 도입 불요. Pact 공식이 직접 "consumer-known subset만 검증"이라 명시 → ca-tmpl single-team 환경에서 snapshot 우위. Testcontainers 공식이 "real services, no H2" 입장 — ca-tmpl integration부터 강제 정합. binary pass/fail은 adoption gate에 적합, WAR/CIS 점진적 점수는 운영 중 지속 개선에 적합.

Group G-H — Sample / adoption — 2 branches, 8 raw

  • Owning branch-notes: raw/branch-notes/feature-sample-domain-contract-fixture, raw/branch-notes/feature-sample-removal-adoption-contract
  • 대안 조사:
    • Sample fixture: ca-tmpl(sample-portfolio 12 scenario matrix + 6-field minimum model + state machine + optimistic lock + idempotency key) vs Spring Petclinic / RealWorld (gothinkster) / Microservices sample (Spring guides) / Shopping cart (Stripe testmode) / No fixture
    • Removal/adoption: ca-tmpl(2-step removal + dual-mode CI matrix + 7-step adoption checklist) vs Yeoman·archetype auto-remove / Cookiecutter / degit (Svelte) / Spring Initializr / GitHub Template Repository / Manual fork
  • 비교 핵심: Petclinic은 "demo지 best-practice 아님" 본인 선언, RealWorld는 spec 풍부하지만 minimum 아니고 contract scenario 부재. ca-tmpl 결정이 skeleton contract 검증 도구라는 목적에 가장 적합. Initializr/Cookiecutter는 generator 시점 sample-off라 ca-tmpl dual-mode CI matrix와 충돌. GitHub Template Repository가 CI/Actions까지 함께 복제되어 friction 최저 — reference 1순위. Backstage는 조직 규모 임계점 이후 IDP 후보.

Group G-I — Config / adapter — 2 branches, 7 raw

  • Owning branch-notes: raw/branch-notes/feature-env-driven-runtime-configuration, raw/branch-notes/feature-integration-adapter-templates
  • 대안 조사:
    • Env config: ca-tmpl(APP_ prefix + Duration 30s 1택 + boolean true/false + no-runtime-reload + .env.example drift verify + APP_MULTI_INSTANCE_ENABLED claim parsing) vs Spring Cloud Config Server / k8s ConfigMap + Spring Cloud Kubernetes auto-reload / HashiCorp Consul KV / AWS Parameter Store·AppConfig / LaunchDarkly·Unleash
    • Adapter templates: ca-tmpl(optional module + @ConditionalOnProperty + ArchUnit 3-layer detection + AdapterDisabledException) vs Spring Boot AutoConfiguration without ConditionalOnProperty / Plugin architecture (OSGi) / Spring @Profile based / SPI ServiceLoader / Feature flag library (FF4J·Togglz)
  • 비교 핵심: 12-factor §III. Config가 ca-tmpl APP_ env-only + no-reload 결정의 이론 출처. Spring Cloud Config Server는 인프라 SPOF + bootstrap 의존, k8s reload는 partial-state 디버깅 어려움. LaunchDarkly/Unleash는 product-grade A/B/canary 요구 발생 시 진입점. ca-tmpl @ConditionalOnProperty는 Layer 1만 Spring 공식 cover, Layer 2(ArchUnit)/Layer 3(AdapterDisabledException)는 branch 자체 contract — ArchUnit source 별도 필요한 미흡 영역. SPI는 on/off 표현 불가 + DI 미통합 + default constructor 강제. Togglz/FF4J는 runtime branching 도구라 시맨틱 다름.

Group G-J — Privacy / file / domain modeling — 3 branches, 10 raw

  • Owning branch-notes: raw/branch-notes/feature-data-retention-privacy-contract, raw/branch-notes/feature-file-resource-handling-contract, raw/branch-notes/feature-domain-modeling-guardrails
  • 대안 조사:
    • Privacy: ca-tmpl(30/180/365d retention + HMAC-SHA-256 salt rotation 90d + DSR SLA 30d/14d + is_sample column) vs GDPR-compliant privacy-by-design libraries / AWS Macie PII detection / OneTrust·TrustArc SaaS / Cryptographic erasure (delete key vs delete data) / Tokenization vs pseudonymization
    • File: ca-tmpl(10MB/12MB/20MB 3-layer + content-type allowlist 6종 + temp orphan 1h cleanup + antivirus gateway default) vs Direct S3 presigned URL / tus protocol (resumable) / multipart/form-data only / ClamAV in-app vs gateway / AWS GuardDuty Malware·GCP SCC
    • Domain modeling: ca-tmpl(VO private constructor + aggregate root mutator protection + domain logger ban + safe reason enum + invariant in constructor + ORM 외부 매핑) vs Functional domain (Scala·F#) / Anemic vs Rich model / Pure DDD aggregates / Event sourcing / CQRS
  • 비교 핵심: GDPR Art.25 (Privacy by design) + NIST SP 800-88 (Cryptographic Erase)가 ca-tmpl retention/backup 결정의 표준 근거. HMAC + 90d salt rotation은 ENISA가 인정하나 brute-force 가능 input space(예: 한국 휴대폰 11자리)에서는 tokenization 우위. backup의 GDPR Art.17 erasure는 cryptographic erase가 NIST 정식 인정 → per-principal envelope key 구조 필요(ca-tmpl 미결정). ICAP/RFC 3507이 antivirus gateway 표준이지만 HTTPS E2E TLS 환경에서 적용 어려움. tus 채택 시 ca-tmpl "1h orphan cleanup"이 session 잘못 삭제 가능. Vaughn Vernon "Effective Aggregate Design" + Fowler "Anemic Domain Model"이 ca-tmpl 결정의 reference standard. ca-tmpl의 "ORM 외부 매핑"은 Vernon Option A, 우아한형제들 초기 글은 Option B(JPA direct annotation + protected ctor)지만 ca-tmpl forbidden import 규칙 위배라 거부. Greg Young 글에서 ca-tmpl은 CQRS read 분리/event sourcing 모두 미채택, 단순 "domain event = transport-free fact" 정의만 차용.

다음 단계 (Phase E)

모든 43 branch의 외부 근거 조사 완료 (총 16 topic, 153 raw 파일). 다음은 wiki/concepts/ 합성 단계:

위 16개 topic을 각각 wiki/concepts/{topic}.md canonical 문서로 합성 예정:

  • (T1-T6 기존 6개) clean-architecture-package-layout / transaction-boundary-abstraction / transactional-outbox-pattern / api-error-envelope-design / idempotency-key-design / multi-tenancy-isolation-patterns
  • (G-A) observability-log-metric-trace-runbook
  • (G-B) security-baseline-jwt-actuator-secrets
  • (G-C) data-layer-persistence-cache-outbound
  • (G-D) runtime-container-health-migration
  • (G-E) devops-ci-supply-chain-dx
  • (G-F) api-evolution-and-schema
  • (G-G) skeleton-governance-registry-verification-test-scorecard
  • (G-H) sample-fixture-and-adoption
  • (G-I) config-and-adapter-templates
  • (G-J) privacy-file-domain-modeling

각 concept 문서는 templates/concept-template.md 형식 (Summary / Standard / 한계 / Project Application / Interview Questions / Do Not Overclaim / Sources). raw 153개를 Sources로 인용. status draft로 시작.

검증 권장 (needs-confirmation)

각 topic 에이전트가 부분 추출만 가능했던 source — 후속 보강 필요:

  • layer-first-baeldung-clean-architecture-spring-boot.md (본문 직접 인용 미완)
  • hexagonal-cockburn-wikipedia-summary.md (원문 SSL 만료, Wikipedia 대체)
  • outbox-woowahan-techblog-pattern.md (인용 wording 보강)
  • outbox-netflix-domain-events-cdc.md (DBLog 정확한 인용)
  • multitenancy-stripe-citus-schema-per-tenant.md (Citus 한계치 수치)

후속 보강 결과 (2026-05-22 처리 완료)

8건의 후속 보강 후보 모두 처리 완료. 외부 source 추가 + branch-note 결정사항 추가 + concept/project 보강. 신규 raw 8 파일은 status needs-confirmation 또는 raw(high confidence)로 분류.

항목 처리 결과 신규 raw 파일
G-E Cosign identity 매칭 정책 결정 추가: cosign verify --certificate-identity=<expected> --certificate-oidc-issuer=<expected> 필수. signature 존재만 검증하면 fail. (status: high) raw/official-docs/cosign-keyless-identity-verification-policy
G-E SLSA v1.0 spec 필드명 결정 추가: provenance 생성 시 SLSA 공식 필드명(buildDefinition.{buildType, externalParameters, internalParameters, resolvedDependencies} + runDetails.{builder.id, metadata.invocationId, ...}) 사용. 약식 명명 forbidden. (status: high) raw/official-docs/slsa-v1-provenance-schema
G-F Sunset+Deprecation paired 결정 추가: API deprecation 응답은 Sunset + Deprecation 헤더 함께 전송. 단독 Sunset 금지. Link: <url>; rel="sunset" 권장. (status: high) raw/official-docs/sunset-deprecation-headers-paired-usage
G-F Protobuf reserved JSON 흉내 결정 보류: OpenAPI x-removed-fields extension OR markdown 자체 catalog. 코드 단계 도구 결정. (status: needs-confirmation) raw/official-docs/protobuf-reserved-vs-json-openapi-extension
G-G ArchUnit annotation-as-registry 결정 유지: markdown SSOT 유지, ArchUnit annotation은 verifier 한정 (registry 아님). 근거: framework-neutral, git diff review, 외부 도구 호환. (status: needs-confirmation, 공식 권고 부재) raw/official-docs/archunit-annotation-as-registry-evaluation
G-I ArchUnit Layer 2 정적 검사 범위 결정 명확화: Layer 2는 "annotation 존재 + naming pattern" fitness function까지만 정적 보장. runtime active 검사는 Layer 3 (AdapterDisabledException)에 위임. (status: needs-confirmation) raw/official-docs/archunit-conditional-on-property-3-layer-pattern
G-J per-principal envelope key 결정 추가: backup PII 포함 시 per-principal envelope key (또는 tenant-level CMK) 구조 적용. HMAC + salt rotation은 forward security only 명시. 구체 패턴은 Phase C2 보류. (status: needs-confirmation) raw/official-docs/gdpr-cryptographic-erasure-envelope-key-pattern
G-B 한국 보안 기술블로그 부분 완료: Actuator 영역 2건 (우아한형제들 + 토스페이먼츠) 확보. JWT/secret 직접 사례는 fetch 가능 source 부재 → follow-up 후보로 유지. (status: raw) raw/company-tech-blogs/security-woowahan-actuator-safe-usage, raw/company-tech-blogs/security-toss-actuator-healthcheck

총 신규 raw 파일: 9개 (G-B만 2개). 누적 외부 근거 raw: 162개 (Topic 1-6: 54 + G-A~J: 99 + 후속 보강: 9).

잔여 follow-up

  • G-B: 한국 기업 JWT/secret 직접 사례 (토스/카카오/네이버 등) — 검색 가능한 글 등장 시 추가.
  • G-F: Protobuf reserved 흉내 도구 선택 (x-removed-fields extension vs markdown catalog) — Phase C2 코드 단계 결정.
  • G-I: ArchUnit Layer 2 fitness function 도입 여부 — Phase C2 코드 단계 결정.
  • G-J: envelope key 구체 패턴 (per-principal CMK / per-principal DEK+master CMK / tenant-level CMK) — Phase C2 KMS 선택 단계 결정.

30. 시스템 아키텍처

본 절은 templates/project-template.md §3 표준에 맞춰 작성. ca-skeleton 은 운영 계약 문서 가 본체이며 아키텍처는 모듈 의존성 + 외부 의존성 2관점으로 표현.

작성 도구: draw.io (templates/diagram-standards.md v2 minimalist 표준). Mermaid 는 시퀀스용 (§30.1~§30.3).

30-1. 모듈 의존성 (Gradle 멀티모듈 + Clean Architecture)

!raw/diagrams/ca-skeleton/architecture-modules-2026-05-26.drawio

다이어그램이 답하는 질문: 5개 Gradle 모듈은 어느 방향으로만 서로 의존할 수 있고, 그 중심은 무엇인가?

핵심 메시지: domain (파란 박스) 이 CA 의 심장이며, 모든 의존 화살표가 결국 domain 으로 수렴한다. cmd 는 composition root 로서 모든 모듈을 조립하지만, 자기 자신은 어디에도 의존받지 않는다.

허용 방향 (다이어그램 화살표 8개):

  • cmd → presentation / service / infra / domain — composition root
  • presentation → service (UseCase 호출) + presentation → domain (도메인 모델/예외 직접 사용)
  • service → domain (UseCase 가 도메인 모델 조작)
  • infra → domain (Repository Port 구현, 도메인 모델 매핑)

HARD-STOP 금지 사항 (callout 참조):

  • domain → 어떤 다른 모듈 또는 Spring/JPA/HTTP/cloud SDK (순수 Java 만)
  • serviceinfra 또는 presentation (포트로만 통신)
  • presentationinfra (Repository / JPA Entity 직접 사용 금지)
  • infrapresentation 또는 controller DTO (요청 객체 누출 금지)

검증 수단:

  • ./gradlew verifyCleanArchitectureDependencies — Gradle project-dependency check
  • ./gradlew :cmd:test — ArchUnit CleanArchitectureTest 실행

30-2. 외부 의존성 & 신뢰 경계 (런타임 토폴로지)

!raw/diagrams/ca-skeleton/architecture-runtime-topology-2026-05-26.drawio

다이어그램이 답하는 질문: 앱이 기동하기 위해 반드시 있어야 하는 것은 무엇이고, APP_ADAPTER_*_ENABLED=false 로 끌 수 있는 것은 무엇인가?

핵심 메시지: Application 은 단 하나의 mandatory 외부 의존성 = PostgreSQL 만 가진다. Redis / Kafka / Email / Slack / Google 은 모두 optional — adapter 를 끄거나 외부 장애 시에도 앱 자체는 살아 있어야 한다.

의존성 분류 (다이어그램 색·선 ↔ 정책):

종류 시각화 예시 정책
Mandatory 파란 굵은 실선 Client→app(HTTP), app→PostgreSQL(JDBC) 없으면 기동 실패. cmd health check 에서 fail-fast
Optional internal 주황 점선 Redis cache, Kafka outbox publisher APP_ADAPTER_REDIS_ENABLED=false 로 끌 수 있음. 끌 경우 fallback path 활성
External Internet 회색 점선 Email API, Slack API, Google OIDC 외부 장애에도 앱 자체는 살아 있어야 함 (degrade 또는 retry-able)

운영 정책 (§11 Adapter Failure Contract):

  • Mandatory adapter (PostgreSQL) 장애 → app 자체가 /readyz 실패, traffic 차단
  • Optional internal adapter (Redis/Kafka) 장애 → 해당 기능만 degrade, app 자체는 healthy
  • External (Email/Slack/Google) 장애 → 호출 단위로 retry / circuit-breaker, app 자체는 healthy

금지: optional adapter 가 mandatory 처럼 동작하도록 hard-coded (e.g., service 가 RedisCachePort 를 null 검사 없이 의존) → §11 위반.

30.1 핵심 시퀀스 (Mermaid)

§3 ~ §7 (응답 envelope, validation, exception, error category) 의 데이터 흐름을 시퀀스로 표현. happy path + error path.

sequenceDiagram
    autonumber
    actor Client
    participant FE as Presentation (Controller)
    participant App as Application (UseCase)
    participant Dom as Domain
    participant Infra as Infrastructure (Adapter)
    participant DB as DB

    Client->>FE: HTTP request
    FE->>FE: Request DTO validation (§4 syntax layer)
    FE->>App: command/query (record)
    App->>Dom: domain invariant check (§4 invariant layer)
    App->>Infra: outbound port call (via TransactionPort)
    Infra->>DB: persistence
    alt success
        DB-->>Infra: result
        Infra-->>App: domain object
        App-->>FE: response value
        FE-->>Client: 200 OK {success: true, data: ..., meta: {request_id, trace_id}}
    else domain invariant 위반
        Dom-->>App: DomainInvariantException
        App-->>FE: bubble up
        FE-->>Client: 422 Unprocessable Entity {success: false, error: {category: VALIDATION, code: ...}}
    else infra/DB 장애
        Infra-->>App: PersistenceException (translated by §6 mapper)
        App-->>FE: bubble up
        FE-->>Client: 503 Service Unavailable {success: false, error: {category: TRANSIENT_DEPENDENCY, code: ...}}
    end

30.2 Transactional Outbox publish (§domain-event-outbox-contract)

SKIP LOCKED polling 패턴. DB 트랜잭션 + outbox 적재 + 비동기 broker 발행이 분리되어 원자성 확보.

sequenceDiagram
    autonumber
    actor Client
    participant App as service (UseCase)
    participant Infra as infra (Adapter)
    participant DB as PostgreSQL
    participant Poller as OutboxPoller<br/>(scheduled, multi-instance)
    participant Kafka as Kafka broker

    Client->>App: business command
    App->>Infra: save Aggregate + Outbox event<br/>(single TX)
    Infra->>DB: BEGIN; INSERT aggregate; INSERT outbox; COMMIT
    DB-->>Infra: OK
    Infra-->>App: success
    App-->>Client: 200 OK

    Note over Poller: 1초 주기 + SKIP LOCKED
    Poller->>DB: SELECT FROM outbox WHERE status='PENDING'<br/>FOR UPDATE SKIP LOCKED
    DB-->>Poller: events to publish
    loop 각 event
        Poller->>Kafka: publish(event)
        alt 성공
            Kafka-->>Poller: ack
            Poller->>DB: UPDATE outbox SET status='SENT'
        else 실패
            Kafka-->>Poller: error
            Poller->>DB: UPDATE outbox SET attempt_count+=1
            Note over Poller,DB: attempt_count >= max → status='DEAD'
        end
    end

30.3 Tenant Context Propagation (§tenant-context-policy)

멀티 테넌트 opt-in. JWT claim → ThreadLocal → 비동기 전파 → finally clear.

sequenceDiagram
    autonumber
    actor Client
    participant Filter as TenantContextFilter<br/>(presentation)
    participant TL as ThreadLocal<br/>(TenantContext)
    participant App as service (UseCase)
    participant TD as TaskDecorator
    participant Async as Async Executor<br/>(ThreadPoolTaskExecutor)
    participant DB as DB Repo

    Client->>Filter: HTTP request<br/>+ Authorization: Bearer JWT
    Filter->>Filter: JWT validate + extract tenant_id claim
    alt JWT 유효 + tenant_id 존재
        Filter->>TL: set(tenant_id)
        Filter->>App: forward
        App->>DB: query with WHERE tenant_id=current()
        DB-->>App: tenant-scoped data
        App-->>Filter: result

        Note over App,Async: 비동기 작업 시
        App->>TD: submit Runnable
        TD->>TD: capture caller tenant_id
        TD->>Async: wrap Runnable with try-finally
        Async->>TL: set(tenant_id) on worker thread
        Async->>App: business work
        Async->>TL: clear() ← MANDATORY (finally)
        Async-->>App: done

        Filter->>TL: clear() ← finally (worker thread reuse 보호)
    else JWT 무효
        Filter-->>Client: 401 Unauthorized
    else multi-tenant disabled + X-Tenant-Id header 유입
        Filter-->>Client: 400 TENANT_NOT_SUPPORTED
    end

핵심 함정 (§tenant-context-policy 의 결정 사항):

  • 비동기 작업 후 ThreadLocal.clear() 누락 시 스레드 풀 재사용으로 인한 테넌트 정보 누수 (Tenant Leakage) — finally 강제

(이 외 패턴 — JWKS refresh, idempotency replay, graceful shutdown — 은 각 feature-* sub-branch 의 시퀀스에서.)

31. 묶음

ca-skeleton (= ca-tmpl) 프로젝트에 묶이는 모든 raw 자료. ca-tmpl repo (/home/donghyeon/workspace/ca-tmpl/) 의 코드와 함께 본 LLM Wiki 의 자료들이 cluster 구성.

31.1 브랜치 (feature-* / develop-* / fix-* / chore-* / experiment-*)

generated reverse view는 child branch의 v2 contract migration 후 채운다. 아래 수기 목록은 그 전까지 legacy navigation으로 보존한다.

ca-skeleton 은 root branch 가 단일이 아니라 다수의 feature-* 가 직접 project 에 매달림. 모두 Tier-1 hub.

핵심 feature-* branch-notes (raw/branch-notes/):

(총 44개 — raw/branch-notes/feature-*.md glob 으로 확인 가능)

31.2 근거 자료

  • 개별 official-docs / company-tech-blogs 는 각 feature-* branch-note 의 Sources 표에서 cited.

31.3 오류 기록

31.4 면접 준비

31.5 블로그·채용공고 연계 글감

31.6 파생 wiki 문서

  • canonical 검증 사실:
    • ca-tmpl — 16 의사결정 project doc hub (named hub, sibling wiki/projects/ca-tmpl/ 폴더의 MOC)
    • 16 개별 project docs: wiki/projects/ca-tmpl/{topic}.md
  • 관련 일반 개념:
    • 16 wiki/concepts/{topic}.md (Core 6 + Cross-cutting 10) — llm-wiki 참조
  • 포트폴리오: (Phase D 후속)
  • 블로그 글: (Phase D 후속)

32. Phase 5 Additional Evidence Raws (2026-05-27)

Phase 5B 외부 근거 추가 보강. 25개 신규 raw 파일 (raw/official-docs/ 하위) 을 owning decision/branch-note 별로 매핑. 각 raw 는 frontmatter related_projects: [ca-skeleton] 보유. 본 섹션은 §29 (Phase 1~4 162개 누적) 이후 추가된 evidence index.

출처 신뢰도 (CLAUDE.md §5 정합): 본 섹션의 모든 raw 는 source_type: official-doc (RFC, IANA registry, vendor 공식 reference, OWASP cheat sheet, K8s 공식 문서 등). company-tech-blog 는 포함되지 않음.

사용 경계: 본 섹션은 raw evidence 의 cluster-level index 역할. 각 raw 의 Claim ID / Usage Boundary 는 raw 파일 자체의 ## Claims Extracted 섹션에서 확인. 본 project-note 는 raw 를 owning decision/branch 에 매핑할 뿐이며, raw 의 verbatim claim 을 그대로 best practice 로 단정하지 않음.

32.1 Architecture / Boundary (3 raw)

raw 채택 위치 (decision / branch) 사용 근거
raw/official-docs/arch-clean-architecture-uncle-bob feature-repository-access-permission-contract, feature-architecture-enforcement-rules, feature-skeleton-package-blueprint-contract Clean Architecture 의 Dependency Rule (외층 → 내층 only) 이 ca-skeleton 의 module dependency rule (§20) 의 1차 reference standard
raw/official-docs/arch-hexagonal-cockburn feature-application-port-usecase-contract, feature-repository-access-permission-contract, feature-architecture-enforcement-rules Cockburn 의 Ports & Adapters 가 inbound port (*UseCase) / outbound port (*Port) 분리 (§25 port naming default decision) 의 reference standard
raw/official-docs/cqrs-fowler-bliki raw/branch-notes/feature-repository-access-permission-contract (D10 capability matrix), feature-domain-modeling-guardrails Fowler 의 CQRS 분류가 command/query use case 분리 (§19 Use Case / Port Contract) 와 READ_REPOSITORY / WRITE_REPOSITORY capability 분리 (§10) 의 reference. 단, ca-skeleton 은 event sourcing 미채택.

32.2 Repository / Persistence / Transaction (3 raw)

raw 채택 위치 사용 근거
raw/official-docs/microservices-io-transactional-outbox raw/branch-notes/feature-repository-access-permission-contract (D7 outbox capability), feature-domain-event-outbox-contract microservices.io 의 Transactional Outbox pattern 정의가 ca-skeleton 의 outbox SKIP LOCKED polling 결정 (§14, §29 Topic 3) 의 reference (단, microservices.io 는 패턴 카탈로그이며 polling vs CDC 트레이드오프는 별도 source).
raw/official-docs/archunit-user-guide raw/branch-notes/feature-repository-access-permission-contract (D8 enforcement), feature-architecture-enforcement-rules ArchUnit 공식 user guide 가 @UseCaseRepositoryAccess annotation-based rule 의 enforcement 메커니즘 (§21 Capability Registry) 근거. annotation processor alternative, runtime AOP forbidden 정합.
raw/official-docs/spring-tx-management-reference raw/branch-notes/feature-repository-access-permission-contract (D4 transaction boundary), feature-transaction-concurrency-contract, feature-application-port-usecase-contract Spring 공식 Transaction Management reference 가 @Transactional propagation/isolation 의 표준 정의. ca-skeleton 은 @Transactional 직접 import 금지 + TransactionPort 추상화 (§25 transaction boundary default) 채택 — Spring 표준을 reference 로 두되 application layer 격리.

32.3 Outbound HTTP / Resilience (3 raw)

raw 채택 위치 사용 근거
raw/official-docs/resilience4j-micrometer-module raw/branch-notes/feature-outbound-http-client-baseline (D4 metric), feature-metrics-alerting-contract Resilience4j 공식 Micrometer 통합 모듈이 retry/circuit-breaker metric 이름·tag (§29 Group G-A metric) 의 표준 reference. ca-skeleton metric registry (§21 Metrics Registry) 의 retry/CB metric 정의 근거.
raw/official-docs/spring-restclient-builder-reference raw/branch-notes/feature-outbound-http-client-baseline (D5/D7 mechanism) Spring 6.1+ RestClient 공식 builder API reference. ca-skeleton 의 RestClient 기본값 (§11 Outbound HTTP, §29 Group G-C) 의 직접 source. RestTemplate maintenance-only 정책과 정합.
raw/official-docs/spring-smartlifecycle-reference raw/branch-notes/feature-outbound-http-client-baseline (D8 graceful shutdown), feature-runtime-health-lifecycle-contract Spring SmartLifecycle 인터페이스 reference. ca-skeleton 의 graceful shutdown 20s+5s+35s (§29 Group G-D Container) 와 outbound HTTP shutdown retry suppression (§28 Numeric conflicts) 의 phase 분리 메커니즘 근거.

32.4 API Contract / Schema / Versioning (4 raw)

raw 채택 위치 사용 근거
raw/official-docs/rfc9110-http-semantics raw/branch-notes/feature-outbound-http-client-baseline (D6 status code), raw/branch-notes/feature-api-contract-baseline (D8/D9 method/status) RFC 9110 (HTTP Semantics, 2022) 이 status code 의미·method 정의·conditional request 의 정식 reference. ca-skeleton 의 error envelope HTTP status 매핑 (§3, §6) 과 outbound HTTP 분류 (§11) 의 standard.
raw/official-docs/openapi-spec-3-1-0 raw/branch-notes/feature-api-contract-baseline (D10), feature-contract-verification-test-suite, feature-api-compatibility-deprecation-contract OpenAPI 3.1.0 공식 spec (JSON Schema 2020-12 정합). ca-skeleton 의 OpenAPI snapshot drift test (§25 OpenAPI drift default, §29 Group G-G) 의 standard reference.
raw/official-docs/google-aip-185-resource-versioning raw/branch-notes/feature-api-contract-baseline (D2/D6 versioning) Google AIP-185 (Resource Versioning) 가 URI path version (/v1) vs header version trade-off 의 reference. ca-skeleton 의 /v1 URI prefix default (§25 API versioning) 결정 근거 — Google AIP 는 외부 공식 reference 이지만 Google API 정책이라 ca-skeleton 이 100% 따라가지는 않음.
raw/official-docs/jsonapi-pagination-format raw/branch-notes/feature-api-contract-baseline (D7 pagination) JSON:API 공식 pagination format (page[number], page[size], links.{first,last,next,prev}). ca-skeleton 의 envelope meta.page (§21 Response Envelope) 의 reference 대안 1종 — ca-skeleton 은 자체 envelope 채택, JSON:API 는 비교 대안 (§29 Topic 4 API Error Envelope) 으로 보존.

32.5 Schema / Serialization (2 raw)

raw 채택 위치 사용 근거
raw/official-docs/rfc3339-datetime-utc raw/branch-notes/feature-runtime-health-lifecycle-contract (D12 timezone), feature-schema-serialization-contract RFC 3339 (Date and Time on the Internet) 이 ISO-8601 의 IETF profile. ca-skeleton 의 ISO-8601 offset UTC default (§16, §29 Group G-F Schema) 의 직접 reference.
raw/official-docs/iana-media-types-registry raw/branch-notes/feature-file-resource-handling-contract (D7 content-type allowlist), feature-schema-serialization-contract IANA Media Types Registry 가 Content-Type allowlist (§18 File / Resource Handling, §29 Group G-J File) 의 SSOT. ca-skeleton 의 6종 content-type allowlist 의 reference.

32.6 File / Resource Handling (5 raw)

raw 채택 위치 사용 근거
raw/official-docs/spring-boot-multipart-reference raw/branch-notes/feature-file-resource-handling-contract (D3/D4 mechanism) Spring Boot Multipart 공식 reference (spring.servlet.multipart.max-file-size 등). ca-skeleton 의 3-layer size limit (Spring 10MB / global 12MB / gateway 20MB, §29 Numeric conflicts) 중 Spring layer 의 직접 source.
raw/official-docs/nginx-client-max-body-size raw/branch-notes/feature-file-resource-handling-contract (D4 gateway layer) nginx client_max_body_size 공식 reference. ca-skeleton 3-layer size limit 의 gateway layer (20MB) 의 source.
raw/official-docs/owasp-file-upload-cheat-sheet raw/branch-notes/feature-file-resource-handling-contract (D5 security), feature-security-operational-baseline OWASP File Upload Cheat Sheet 가 file upload 보안 baseline (content-type validation, size limit, path validation, antivirus scanning) 의 SSOT. ca-skeleton 의 antivirus gateway default (§29 Missing Area Closures) 와 content-type allowlist 의 보안 reference.
raw/official-docs/owasp-path-traversal feature-file-resource-handling-contract OWASP Path Traversal cheat sheet 가 download/serve 경로 traversal 방지 (§18 File / Resource Handling - "path traversal 방지") 의 source.
raw/official-docs/jdk-files-createtempfile raw/branch-notes/feature-file-resource-handling-contract (D6 temp file) JDK Files.createTempFile Javadoc reference. ca-skeleton 의 temp file 1h orphan cleanup (§29 Group G-J File) 과 secure temp file creation 의 표준 API source.
raw/official-docs/spring-streaming-response-body raw/branch-notes/feature-file-resource-handling-contract (D8 download streaming) Spring StreamingResponseBody 공식 reference. ca-skeleton 의 download streaming failure 분류 (§18 File / Resource Handling - "download streaming failure") 의 mechanism source.

32.7 Runtime / Health / Lifecycle (2 raw)

raw 채택 위치 사용 근거
raw/official-docs/k8s-configure-probes-task-page raw/branch-notes/feature-runtime-health-lifecycle-contract (D5 probe config / D11 startup probe) K8s 공식 "Configure Liveness, Readiness and Startup Probes" task page. ca-skeleton 의 3-probe 분리 (§29 Group G-D Runtime health) 와 readiness/liveness/startup separation 의 SSOT.
raw/official-docs/k8s-pod-lifecycle-probes-concept raw/branch-notes/feature-runtime-health-lifecycle-contract (D7 probe semantics) K8s 공식 Pod Lifecycle concept page (probe lifecycle, restart policy 등). ca-skeleton 의 readiness gated migration (§28 Critical Defaults - migration runner) 와 graceful shutdown ↔ probe interaction 의 conceptual reference.

32.8 Operational Runbook / Alerting (3 raw)

raw 채택 위치 사용 근거
raw/official-docs/lychee-link-checker raw/branch-notes/feature-operational-runbook-contract (D4 link-check tool) lychee (Rust 기반 markdown link checker) 공식 doc. ca-skeleton 의 markdown-link-check 또는 lychee 를 통한 runbook link drift 방지 (§29 Self-Contradiction Closures - "runbook link required but unverifiable") 의 tool option.
raw/official-docs/prometheus-alertmanager-silences raw/branch-notes/feature-operational-runbook-contract (D6 alert silencing) Prometheus Alertmanager silences 공식 doc. ca-skeleton 의 alert dedup 5분 + P1 2분 noise 억제 (§28 Numeric conflicts) 의 silence/inhibition mechanism reference.
raw/official-docs/google-sre-workbook-on-call-monitoring raw/branch-notes/feature-operational-runbook-contract (D2 monitoring philosophy / D10 on-call) Google SRE Workbook "Monitoring" + "Being On-Call" chapters. ca-skeleton 의 P1/P2/P3 severity (§18 Metrics / Alerting) 와 runbook 7-section 표준 (§28 Phase D2 closures) 의 conceptual reference. company-tech-blog 아님 (Google 공식 book chapter, O'Reilly publication 형식이지만 Google SRE 가 저자).

33. 아키텍처 검토 체크리스트

  • 한 줄 요약 + 현재 상태 + 나의 역할 채워짐 (본문 도입부)
  • 측정 가능한 성공 기준 — §1 목표 + §28 Phase 매트릭스 ✓
  • 아키텍처 다이어그램 1개 이상 첨부 (§30-1 모듈 의존성, §30-2 런타임 토폴로지) ✓ (Mermaid; drawio 이관은 Phase C2 시 검토)
  • 다이어그램의 모든 컴포넌트가 라벨 + 역할 + 기술 스택 표기 ✓
  • 다이어그램의 모든 화살표가 프로토콜·데이터 종류 라벨링 ✓
  • 외부 시스템이 점선 또는 색으로 시각적 구분 ✓ (classDef external)
  • 범례(Legend) 다이어그램에 포함 ✓ (§30-2 끝 범례 블록)
  • 신뢰 경계 / 네트워크 경계 표시 ✓ (subgraph TB_*)
  • 시퀀스 다이어그램 ≥1 (Mermaid) — happy path + error path (§30.1 Request flow, §30.2 Outbox, §30.3 Tenant) — 총 3개 ✓
  • Cluster 섹션의 root/feature branch 목록 채워짐 (§31.1) ✓
  • 마지막 architecture review 날짜 frontmatter architecture_review: 에 기록 — 2026-05-26 ✓
  • Phase 5B evidence raws (25 raw, §32) cluster-level index 작성 ✓

35. Implementation Coverage Checklist

본 § 는 ca-skeleton 의 전체 영역 × 구현 진척 트래커. 신규 영역 발견 시 본 § 에 row 추가 → branch 신설 → 결정 박음 → 코드 작성 순서. 상태 변경 시 본 § + 해당 branch 의 status_label 동시 갱신.

상태 표기

아이콘 의미 등급 (CLAUDE.md §6)
[ ] 미시작 / scaffolding planned
[~] 결정 박힘, 코드 없음 documented-only
[*] 코드 일부 작성 actually-implemented (partial)
[x] 코드 완성 + 로컬 검증 locally-verified
[X] 운영 검증 prod-verified
(없음) branch 미존재 (신설 후보)

A. 외부 통신 / API 계약 영역

  • [~] HTTP 표면 baseline (24 결정 — envelope / status / pagination / URL naming / PATCH / conditional / cache / LRO / bulk) — feature-api-contract-baseline (D=24, sl=in-progress)
  • [~] Resource ID format (ULID 26-char Crockford base32) — feature-resource-identifier-contract (D=19, sl=in-progress, §구현 가이드 §1~§8 코드 skeleton ready)
  • [ ] Webhook outbound (signature / replay / retry / observability) — feature-webhook-outbound-contract (D=0, scaffolding)
  • [ ] Streaming response (SSE / WebSocket / long-poll / chunked — 1차 결정: 지원 여부) — feature-streaming-response-contract (D=0, scaffolding)
  • [~] API versioning + Sunset / Deprecation (/v1 URI prefix → 향후 /v2) — feature-api-compatibility-deprecation-contract (D=8, sl=in-progress)
  • [~] Outbound HTTP resilience (Resilience4j circuit breaker / retry / timeout) — feature-outbound-http-client-baseline (D=11, sl=in-progress)
  • [~] Error envelope + 코드 registry (error-codes.yaml SSOT) — feature-operational-error-observability-foundation (D=12, sl=in-progress)
  • [~] Idempotency-Key + Rate limit (HTTP header / TTL / fingerprint) — feature-rate-limit-idempotency-contract (D=10, sl=in-progress)
  • [~] Contract verification test suite (OpenAPI drift detection) — feature-contract-verification-test-suite (D=9, sl=in-progress)
  • [~] Schema / Serialization (Jackson naming / date-time / decimal) — feature-schema-serialization-contract (D=7, sl=in-progress)
  • (없음) Documentation generation / API docs publishing (OpenAPI → Swagger UI / Redoc / release artifact 묶기) — F 미래 후보 (사용자 항목 #8)

영속성 영역

  • [~] Persistence failure baseline (optimistic lock / conflict 분류) — feature-persistence-failure-baseline (D=8, sl=in-progress)
  • [x] Application port + use case contract (transaction 경계 + port 추상화) — feature-application-port-usecase-contract (D=14, sl=actually-implemented, AI=5, LV=2)
  • [~] Repository capability annotation (@UseCaseRepositoryAccess) — feature-repository-access-permission-contract (D=11, sl=in-progress)
  • [~] Transaction / Concurrency contract — feature-transaction-concurrency-contract (D=7, sl=in-progress)
  • [~] Migration runner readiness gate (Flyway startup) — feature-migration-startup-contract (D=8, sl=in-progress)
  • [~] Multi-tenancy isolation (tenant context + DB scope) — feature-tenant-context-policy (D=10, sl=in-progress)
  • [~] Data retention / Privacy / GDPR (DSR / PII / 감사 log) — feature-data-retention-privacy-contract (D=12, sl=in-progress)
  • [~] File / Resource handling (upload / download / S3) — feature-file-resource-handling-contract (D=12, sl=in-progress)
  • [~] Domain event + Transactional Outbox — feature-domain-event-outbox-contract (D=10, sl=in-progress)
  • [~] Cache consistency (Redis adapter + invalidation) — feature-cache-consistency-contract (D=9, sl=in-progress)
  • (없음) Persistence auditing (CreatedBy / UpdatedBy 도메인 오염 차단) — 신규 branch 권고: feature-persistence-auditing-contract
  • (없음) DB connection pool 운영 안정성 (HikariCP pool size / timeout / leak detection / slow query) — 신규 branch 권고 (priority #4): feature-database-connection-pool-contract
  • (없음) Backup / restore / DR (PITR / schema rollback policy / restore drill) — F 미래 후보 (사용자 항목 #6)

배포 영역

  • [~] Background job + Async boundary (scheduler / ShedLock) — feature-background-job-async-contract (D=12, sl=in-progress)
  • [~] Runtime health / Lifecycle (actuator / probe / readiness gate) — feature-runtime-health-lifecycle-contract (D=13, sl=in-progress)
  • [~] Management actuator security (port 분리 / 인증) — feature-management-actuator-security-contract (D=8, sl=in-progress)
  • [~] Metrics / Alerting (Micrometer + P1/P2/P3 severity) — feature-metrics-alerting-contract (D=10, sl=in-progress)
  • [~] Distributed tracing (W3C trace context + Micrometer Tracing) — feature-distributed-tracing-contract (D=12, sl=in-progress)
  • [~] Log management (MDC / scrubber / SLF4J 2.x / profile별 console encoder 포맷) — feature-log-management-contract (D=10, sl=in-progress)
  • [~] Container runtime (Temurin slim / JVM ergonomics / non-root) — feature-container-runtime-contract (D=5, sl=in-progress)
  • [~] Build / Release / Supply chain (Gradle / SBOM / Cosign) — feature-build-release-supply-chain-contract (D=13, sl=in-progress)
  • [~] Operational runbook (P1/P2/P3 runbook section 표준) — feature-operational-runbook-contract (D=10, sl=in-progress)
  • [~] Developer experience (bootstrap command / IDE / docker-compose) — feature-developer-experience-contract (D=10, sl=in-progress)
  • [~] Secrets / Config source (env / secret manager) — feature-secrets-config-source-contract (D=10, sl=in-progress)
  • [~] Env-driven runtime configuration (APP_* prefix / feature flag) — feature-env-driven-runtime-configuration (D=10, sl=in-progress)
  • [~] CI quality gates (test/lint/coverage thresholds) — feature-ci-quality-gates-contract (D=9, sl=in-progress)
  • (없음) Static analysis / code quality baseline (Checkstyle / Spotless / ErrorProne / SpotBugs / PMD / Sonar) — 신규 branch 권고 (priority #2): feature-static-analysis-quality-contract — ci-quality-gates 와 별개 (그 branch 는 threshold, 본 branch 는 tool 선택 + 룰셋)
  • [~] Dependency / vulnerability management (CVE scan(Trivy) / CVSS 차단 임계값 / KEV override / suppression governance / Renovate-Dependabot 보안 update / license scan / transitive audit) — raw/branch-notes/feature-dependency-vulnerability-management-contract (2026-06-15 scaffold + D1~D10, sl=in-progress, 전부 planned) — build-release-supply-chain 과 별개 (그 branch 는 artifact / SBOM / locking, 본 branch 는 vuln 정책 + 운영 중 upgrade). §25 SSOT Owner Map "Dependency vulnerability policy" row 참조
  • (없음) Performance / load baseline (k6 / Gatling / JMeter smoke load test / latency budget / throughput budget / N+1 query 감지) — F 미래 후보 (사용자 항목 #7)
  • (없음) Local dev data lifecycle (seed data / test data reset / docker-compose volume reset / local DB migration 재실행) — F 미래 후보 (사용자 항목 #9). DX 와 인접하나 별도 row

보안·거버넌스 영역

  • [*] Boundary validation + Mapping (B1~B9 — Jackson / PATCH / Bean Validation / Polymorphic / Virtual thread / ACL / Bulk / ArchUnit cross-cite) — feature-boundary-validation-mapping-contract (D=15, sl=in-progress, AI=15, LV=2)
  • [~] Business rule validation (domain invariant) — feature-business-rule-validation-contract (D=9, sl=in-progress)
  • [~] Security operational baseline (CORS / SecureRandom / header suppression / API key / session) — feature-security-operational-baseline (D=11, sl=in-progress)
  • [~] Domain modeling guardrails (aggregate boundary / value object) — feature-domain-modeling-guardrails (D=8, sl=in-progress)
  • [*] Domain feature slice + onboarding template — feature-domain-feature-onboarding-contract (D=7, sl=in-progress, AI=2, LV=2)
  • [x] Skeleton package blueprint (Gradle multi-module + Clean Architecture) — feature-skeleton-package-blueprint-contract (D=10, sl=locally-verified, AI=3, LV=8)
  • [x] Architecture enforcement rules (ArchUnit suite SSOT) — feature-architecture-enforcement-rules (D=12, sl=review, AI=11, LV=11)
  • [~] Integration adapter templates — feature-integration-adapter-templates (D=9, sl=in-progress)
  • [~] Sample domain fixture (sample-portfolio) — feature-sample-domain-contract-fixture (D=6, sl=in-progress)
  • [*] Sample removal / Project adoption — feature-sample-removal-adoption-contract (D=6, sl=in-progress, AI=2, LV=2)
  • [~] Contract registry governance (yaml SSOT) — feature-contract-registry-governance (D=7, sl=in-progress)
  • [*] Implementation readiness scorecard — feature-implementation-readiness-scorecard (D=6, sl=in-progress, AI=2, LV=2)
  • [~] Test taxonomy + fixture (unit/contract/architecture/integration) — feature-test-taxonomy-fixture-contract (D=8, sl=in-progress)
  • [~] Tenant context policy + multi-tenancy modelraw/branch-notes/feature-tenant-context-policy (in-progress). 활성화 트리거: raw/branch-notes/feature-resource-identifier-contract 의 D13 (ID 내 tenant 인코딩 거부 — 형식적 위치만 결정) + D17 의 5번째 ArchUnit rule (no_find_by_id_without_tenant) 이 본 branch 결정 후 활성화 대기 중. 현재 branch out-of-scope ("실제 SaaS tenant model 구현") 가 모델 확장이 필요할 때 갱신 필요 (TenantId VO / tenant 테이블 / FK / findByIdAndTenant repository contract / auth → tenant 해석). 단순 single-tenant skeleton 이면 지원 안함 결정으로 close 가능
  • (없음) Template instantiation contract (group / artifact / basePackage / root package rename / README 치환 / sample-off 적용 검증) — 신규 branch 권고 (priority #1): feature-template-instantiation-contract — developer-experience + sample-removal-adoption 와 인접하나 clone 후 검증 절차 가 독립 row 로 약함
  • (없음) AuthN / AuthZ product API baseline (JWT / OAuth2 resource server / RBAC / ABAC / permission matrix / endpoint authorization annotation) — 신규 branch 권고 (priority #5): feature-authentication-authorization-contractfeature-security-operational-baseline 와 별개 (그 branch 는 CORS / SecureRandom / header suppression 중심, 본 branch 는 product API 인증/인가)

E. 신규 branch 권고 (우선순위 9개)

사용자 18항 + 9 보강 분석 결과의 통합 우선순위. 박을 시점은 본 branch 가 현재 결정에 영향 을 주거나 코드 작성 중 막힐 때.

우선순위 branch (예정) 영역 박을 시점 비고
1 feature-template-instantiation-contract D 사용자 첫 template clone 시점 group/artifact/basePackage rename + sample-off 자동화
2 feature-static-analysis-quality-contract C 코드 작성 본격화 직전 Checkstyle/Spotless/ErrorProne/SpotBugs/PMD/Sonar tool 선택 + 룰셋
3 feature-dependency-vulnerability-management-contract C CI 셋업 시점 Dependabot/Renovate + CVE scan + license scan + 운영 upgrade 정책
4 feature-database-connection-pool-contract B persistence 코드 작성 시점 HikariCP pool size / timeout / leak detection / slow query
5 feature-authentication-authorization-contract D 도메인이 사용자 인증 요구하는 시점 JWT/OAuth2 RS + RBAC/ABAC + endpoint auth annotation
6 feature-application-query-bypass-contract B/D query endpoint 첫 작성 시점 CQRS Q 경로 — use case bypass 허용 여부 (architecture-blocking). 2026-06-05 scaffold + 구현 완료 (locally-verified): branch-note + D1 purity-guardrail ArchUnit rule(query_ports_do_not_leak_domain_jpa_or_web_types, generic type argument 검사) + sample-portfolio projection demo + D3/D4/D5 코드화. D2(separate read store) documented-only
7 feature-runtime-context-propagation-contract B/D virtual thread 활성화 + 도메인 context 전파 요구 시점 Java 21 Scoped Values — boundary B6 의 도메인 확장
8 feature-persistence-auditing-contract B entity audit 컬럼 (CreatedBy/UpdatedBy) 도입 시점 도메인 오염 차단 메커니즘 (AuditPort + adapter 가로채기)
9 feature-distributed-lock-contract B/C multi-instance prod 도입 시점 Redisson / DB advisory lock + 트랜잭션 commit 정합. 2026-06-12 branch-note 생성 (D1~D8 박힘 — JdbcLockRegistry default + xact advisory 보조 + ShedLock/session-advisory 배제, 코드 전부 planned)raw/branch-notes/feature-distributed-lock-contract

운영 요구 시 신설)

운영 단계에서 필수가 되지만 skeleton 1차 범위에서는 deferred. 도메인이 요구하거나 prod 운영 시점에 신설 의무.

  • (없음) Backup / restore / DR (PITR / schema rollback / restore drill) — 운영 앱 진입 시 필수 (사용자 항목 #6)
  • (없음) Performance / load baseline (k6 / Gatling / JMeter / latency budget / N+1 detection) — prod 트래픽 수반 시 필수 (사용자 항목 #7)
  • (없음) Documentation generation / API docs publishing (Swagger UI / Redoc / release artifact 묶기) — API 외부 공개 시 필수 (사용자 항목 #8)
  • (없음) Local dev data lifecycle (seed / reset / docker volume / migration 재실행) — DX 강화 시점 (사용자 항목 #9). DX 와 인접
  • (없음) Time / Clock 주입 (Clock port, Instant.now() 차단 ArchUnit rule) — domain 시간 의존 시점
  • (없음) Locale / i18n (error message 다국어, MessageSource 추상화) — 다국어 서비스 시점
  • (없음) Money / Currency / BigDecimal 정밀도 (금융 도메인 패턴) — 금융 도메인 시점
  • (없음) Search abstraction (Elasticsearch / PostgreSQL FTS port) — 검색 도입 시점
  • (없음) Email / SMS / Notification outbound (adapter 표면) — 알림 도입 시점
  • (없음) Saga / Process Manager (multi-step 분산 트랜잭션) — 복합 도메인 시점
  • (없음) Soft delete vs hard delete policy (data-retention 의 확장) — soft-delete 도입 시점

사용 절차

  1. 상태 확인: 코딩 시작 전 본 § grep 으로 해당 영역 branch 상태 파악.
  2. 결정 부족 시: 해당 branch 의 §결정 사항 / §Decision Evidence Map drain 우선.
  3. 코드 시작 후 갱신: [ ][~][*][x][X] 순서로 본 § + branch status_label 동시 갱신.
  4. 신규 영역 발견 시: §31.1 Cluster Branches list + §25 SSOT Owner Map + 본 § 에 row 추가 후 branch 신설 (§34 Stack Commitment 정합 의무).
  5. gap 식별: 정기적 (주 1회 권장) 본 § scan 으로 [ ] 가 많은 영역 / (없음) 항목 검토 → 코딩 우선순위 조정.
  6. 상태 grade 의 evidence 근거: [*]/[x]/[X] 마킹 시 branch 의 §완료 후 정리 / Closure 섹션에 해당 grade 의 실제 코드 reference (PR / commit / test 파일 경로) 명시 의무.

현재 우선순위 (진행 가능 순서)

현재 분포 요약 (46 ca-skeleton branches + 9 신규 권고 + 11 미래 후보):

  • [x] 3개 (locally-verified 이상): feature-skeleton-package-blueprint-contract, feature-architecture-enforcement-rules, feature-application-port-usecase-contract
  • [*] 4개 (partial implementation): feature-boundary-validation-mapping-contract, feature-domain-feature-onboarding-contract, feature-sample-removal-adoption-contract, feature-implementation-readiness-scorecard
  • [~] 37개 (결정 박힘, 코드 없음): 대부분 — D-row 평균 9~12개
  • [ ] 2개 (scaffolding only): feature-webhook-outbound-contract, feature-streaming-response-contract
  • (없음) 8개 (신규 branch 권고, E 영역): template-instantiation / static-analysis / dependency-vulnerability / database-connection-pool / authn-authz / runtime-context / persistence-auditing / distributed-lock — (query-bypass 는 2026-06-05 scaffold+구현 완료로 제외, [x] locally-verified 로 승급)
  • (없음) 11개 (미래 후보, F 영역): backup-restore / performance-load / docs-publishing / local-dev-data / clock-injection / i18n / money-decimal / search / notification / saga / soft-delete

작업 흐름 권고:

  1. [~][*] drain — 코드 작성 단계로 진입. 우선순위:
    • (1순위) feature-resource-identifier-contract — §구현 가이드 §1~§8 코드 skeleton ready, 즉시 코드 작성 가능
    • (2순위) feature-api-contract-baseline — D=24 결정 모두 박힘. ArchUnit rule 작성 + envelope serializer
    • (3순위) feature-operational-error-observability-foundation — error registry yaml SSOT (다수 branch 의 dependency)
    • (4순위) feature-security-operational-baseline — CORS / SecureRandom / API key — security baseline
  2. (없음) E 영역 신규 branch scaffolding코드 작성 전에 박아야 할 architecture-blocking 결정:
    • template-instantiation (priority 1) — project clone 시점에 즉시 필요
    • static-analysis-quality (priority 2) — CI 셋업 시점
    • dependency-vulnerability (priority 3) — CI 셋업 시점
    • database-connection-pool (priority 4) — persistence 코드 작성 시점
    • authn-authz (priority 5) — 도메인 사용자 인증 요구 시점
    • 나머지 3개 (runtime-context, persistence-auditing, distributed-lock) 는 코드 작성 중 부딪힐 때 scaffolding (query-bypass 는 2026-06-05 scaffold+구현 완료)
  3. [ ][~] 결정 drain — scaffolding 2개 (webhook / streaming) 의 1차 결정 박기. 도메인 요구 등장 전까지 미지원 default + ArchUnit 차단 권고.
  4. [*][x] 승급 — 4개 partial 의 planned 잔존 row drain. 특히 boundary branch 의 ArchUnit rule 추가 작성.
  5. [x][X] 승급 — 3개 locally-verified 의 prod-deploy 후 운영 검증 (실제 서비스 배포 후).
  6. F 영역 미래 후보 — 운영 / 도메인 요구 등장 시점에 신설. skeleton 1차 범위 .

Branch 작업 시점 의무:

  • 본 § 의 해당 row 상태 갱신
  • 해당 branch 의 status_label frontmatter 갱신
  • §완료 후 정리 / Closure 섹션에 evidence reference (PR / commit / test 경로) 추가
  • §31.1 Cluster Branches list 의 description 갱신 (필요시)
  • 신규 branch 신설 시 §31.1 + §25 SSOT Owner Map + 본 § row 동시 추가 (§34 Stack Commitment 정합 의무)

Branch 작성 가이드 — 학습된 실패 모드 (4가지)

2026-06-01 raw/branch-notes/feature-resource-identifier-contract 4개 의문점 (sealed permits 모듈 경계 / D5 본문 vs §1/§2 와이어링 / D13 tenant 모델 부재 / D17 + §6 위임 vs 작성) 의 root cause 분석에서 식별된 반복 발생 가능 실패 모드. branch 작성 / 리뷰 시 본 § 항목별 self-check 권고.

Failure mode 발생 영역 위반된 룰 Self-check 질문
F1. Cross-branch SSOT 미확인 branch 가 다른 branch 결정 영역 (예: 모듈 경계, ArchUnit suite 소유) 을 자기 §구현 가이드에 결정 CLAUDE.md §11 "본 branch 결정 범위 밖 cell 작성 금지" + §15.5 R3 OUT_OF_BRANCH_SCOPE 본 §구현 가이드 의 각 cell 이 sibling branch 의 결정 영역 (특히 feature-skeleton-package-blueprint-contract 의 모듈 경계, feature-boundary-validation-mapping-contract 의 ArchUnit suite, feature-tenant-context-policy 의 tenant 모델) 을 침범하지 않는가?
F2. 본문 결정 ↔ §구현 가이드 self-inconsistency D-row 결정과 §구현 가이드 코드가 서로 다른 패턴 채택 (예: D5 본문 = static factory, §1/§2 = port + DI). D-row 끼리도 self-inconsistency (예: D2 charset = Crockford base32, I/L/O/U 제외 → 그러나 D19 fixture 값 01HRGC7K2N4F6P8Q0R2S4T6U8VU 포함 → 자기 regex 통과 불가, 2026-06-01 self-catch) §15.5 R1~R3 의 암묵적 가정근거 → 결정 만 검사, 결정 → 구현 미검사, 결정 → 결정 도 미검사. wiki-workflow STOP self-check 12 도 동일 한계 각 D-row 결정의 기술 선택 이 §구현 가이드 코드 예시와 1:1 매칭되는가? (메커니즘 / 호출자 / 의존 방향 모두) 그리고 D-row 간 cross-reference 가 자기 자신의 charset/regex/format 통과하는가? (예: charset 결정의 alphabet 이 fixture 값을 actually 통과)
F3. 실제 코드 cross-check 부재 spec 이 현재 코드에 존재하지 않는 의존성 (예: tenant 컬럼, ArchUnit rule 의 검사 대상 패키지) 을 가정 명시적 룰 없음 — 코드 cross-check 게이트 부재 본 branch §구현 가이드 의 전제 사실 (테이블 / 컬럼 / 모듈 / 패키지) 이 /home/donghyeon/workspace/ca-tmpl 의 실제 코드에 존재하는가? 없으면 마이그레이션 대상 임을 본문에 명시했는가?
F4. 위임 / 작성 모호 branch 가 결정 SSOT 임을 명시했으나 §구현 가이드에 실제 작성 코드 잔존 (R3 부분 적용) §15.5 R3 의 부분 적용 §구현 가이드 의 코드 skeleton 이 reference (실제 호스팅 = sibling) 인지 실제 작성 (본 branch host) 인지 본문에 명시했는가? reference 라면 sibling cite 와 코드 위치 = sibling 한 줄 추가했는가?

위 4개 self-check 는 /lint 가 자동 catch 하지 못하는 정성적 영역 — branch 작성 / Sources 추가 / Decision 추가 / §구현 가이드 작성 시점에 명시적으로 검토.

장기적으로 /lint 검사 항목 (§15.5 예정 목록) 에 다음 4가지 추가 권고:

  1. F1 — ..domain.. / ..adapter.. 등 package glob 이 sibling branch SSOT 모듈 경계 위반 여부 정적 grep
  2. F2 — ## 결정 사항 의 각 D-row 본문이 ## 구현 가이드 의 §N 코드에서 referenced 됐는지 (Trace: D<N> 헤더 grep)
  3. F3 — ## 구현 가이드 의 코드 예시에 등장하는 클래스명 / 테이블명 / 패키지명이 실제 코드에 grep hit
  4. F4 — ## 구현 가이드 의 코드 skeleton 첫 줄에 REFERENCE ONLY 또는 actual location: 라벨 grep — 미명시 시 본 branch 호스팅으로 간주

34. Stack Commitment

Legacy detail/reference. stack 선택의 stable owner는 ## 6.1 Project Decision Registry / 안정 결정 레지스트리STACK-* rows다. 아래 matrix는 버전·trade-off 설명을 보존한다.

ca-skeleton 은 단일 stack 커밋 을 채택합니다. 다중 DB / 다중 언어 / 다중 빌드 도구 가정은 모든 branch 의 결정 부담을 theoretical UNSUPPORTED_IMPL_DECISION 으로 부풀려 minimalist 정신과 충돌합니다. 본 § 가 stack SSOT — 모든 branch 는 본 § 를 상속 하며 stack 관련 결정을 자기 branch 에서 재선언하지 않습니다.

Stack Matrix

Layer 선택 버전 비고
Language Java 21 LTS java.util.UUID v7 native 미지원 — ULID 선택 근거 (resource-identifier branch D1)
Framework Spring Boot 3.5.14 starter web / data-jpa / validation 사용
ORM Hibernate ORM 6.5.x (Spring Boot transitive) @JdbcTypeCode(SqlTypes.UUID) native UUID
JSON Jackson 2.18.x (Spring Boot transitive) custom serializer for value objects
DB PostgreSQL 16 uuid native column type (16-byte binary). MySQL / Oracle / SQL Server out of scope
Migration Flyway (Spring Boot transitive) startup runner, readiness gate (§25 default)
Build tool Gradle Groovy DSL multi-module + apply false 패턴. io.spring.dependency-management 1.1.6
Test framework JUnit 5 Spring Boot starter 기본
Architecture test archunit-junit5 1.3.0 D17 ArchUnit rule suite (resource-identifier branch + boundary branch)
Random source java.security.SecureRandom Java 21 ULID generator + idempotency key + token generation 의 의무 random source

Cross-Branch 상속 패턴

각 branch 의 §결정 사항 / §Decision Evidence Map / §구현 가이드 가 stack 관련 결정 시 본 § 를 reference 만 하고 재선언하지 않음. 예시:

✗ 잘못된 패턴 (재선언):
  D10: DB primary key = BINARY(16) (MySQL InnoDB) + uuid native (PostgreSQL)
       → 다중 DB 가정 = theoretical UNSUPPORTED_IMPL_DECISION 발생

✓ 올바른 패턴 (상속):
  D10: DB primary key = PostgreSQL 16 uuid native (project §34 Stack Commitment)
       → 단일 stack, 결정 명확, 미래 stack 변경 시 §34 한 곳만 갱신

Stack 변경 절차

본 § 의 stack 변경은 모든 branch 에 cascade 됩니다. 변경 시:

  1. 본 § Stack Matrix 갱신 (변경 row + 변경 사유 한 줄)
  2. 영향 받는 sibling branch 식별 — grep -rn "project §34" raw/branch-notes/feature-*.md
  3. 각 sibling branch 의 §Decision Evidence Map 의 project-ssot (§34) reference 영향 평가
  4. 영향 큰 결정 (D1 ULID 같은 foundational) 은 branch 의 §결정 사항 재평가 + UNSUPPORTED_IMPL_DECISION 재평가

Out of Stack (명시적 거부)

본 stack commit 은 다음 대안 들을 명시적으로 거부:

  • DB: MySQL / Oracle / MariaDB / SQL Server — PostgreSQL 16 단일
  • Language: Kotlin / Scala / Groovy (응용 코드) — Java 21 단일 (Gradle Groovy DSL 은 빌드 도구 한정)
  • Framework: Micronaut / Quarkus / Helidon — Spring Boot 3.5.14 단일
  • Build tool: Maven / Bazel — Gradle Groovy DSL 단일
  • Test framework: TestNG / Spock — JUnit 5 단일

도메인이 위 alternative 를 요구할 경우 본 § 를 갱신 (cascade) 또는 별도 project-fork.