Files
llm-wiki/raw/blog-topics/operational-error-envelope-meta-category-migration-2026-06-01.md

6.0 KiB

title, source_type, status, related_branches, related_projects, tags, created, status_label, target_audience, inspiration_url, archive_url
title source_type status related_branches related_projects tags created status_label target_audience inspiration_url archive_url
blog-topic / operational-error-envelope-meta-category-migration-2026-06-01 blog-topic raw
feature-operational-error-observability-foundation
ca-tmpl
blog-topic
ca-tmpl
error-handling
observability
api-design
mdc
logging
testing
spring-boot
2026-06-01 ready-for-canonical backend-engineer

blog-topic: operational-error-envelope-meta-category-migration-2026-06-01

Layer: raw/blog-topics/ — 채용공고가 아닌 작업·학습·트러블슈팅에서 나온 블로그 글감 원석. canonical 정제 전 raw 후보이며, wiki/blog/ 직접 생성 근거가 아니다.

Parent / 부모

트리거 / Trigger

이미 동작하는 응답 envelope({success,data,error,traceId})을, 관측성 계약이 요구하는 richer shape({success,data,error.{code,category,...},meta.{requestId,traceId,correlationId}})으로 기존 계약을 깨지 않고 끌어올리는 마이그레이션을 직접 했다. 그 과정에서 (a) 인터페이스 추상 메서드 추가의 blast radius, (b) 동일 식별자의 계층별 case 매핑, (c) inbound 헤더 log injection 방어, (d) Spring Boot 슬라이스 테스트의 컨텍스트 오염 트러블슈팅까지 한 묶음으로 나왔다.

글감 후보 / Candidate angles

  1. "운영 에러 분류를 SSOT enum 으로 고정하기" — 13개 임시 목록 → 10-category enum 으로 수렴. category(식별)와 retryable(런타임 신호)을 분리한 이유(per-code retryable, INTERNAL_ERROR 처럼 category default 와 다른 코드 허용).
  2. "이미 직렬화되는 응답 계약에 필드를 안전하게 추가하는 법" — record 컴포넌트 추가가 모든 호출부를 깨뜨리는 게 오히려 안전장치. 컴파일러가 숨은 consumer(PortfolioErrorCode, BulkEnvelopeTest)를 전부 노출 → 한 패스 마이그레이션. ProblemDetail 거부 결정(D5/D6)을 불변으로 둔 additive 확장.
  3. "같은 ID 가 로그·JSON·헤더에서 다르게 쓰이는 건 버그가 아니다"request_id(snake) ↔ meta.requestId(camel) ↔ X-Request-Id(kebab)/traceparent(W3C lowercase). registry 로 3열 1:1 매핑을 고정하고 변환 지점을 한 군데(ResponseMetaFactory)로 모으는 패턴.
  4. "구조화 로깅에서의 log injection(CWE-117) 방어" — 평문 로깅과 달리 JSON 로깅에서의 진짜 위협은 CR/LF 줄 위조. reject/encode 가 아니라 strip + length cap 을 고른 trade-off.
  5. (트러블슈팅) "@WebMvcTest 의 nested @SpringBootConfiguration 이 같은 패키지 다른 테스트를 조용히 깨뜨린 사건" — git stash / 파일 mv 비파괴 격리로 원인 좁히기 → adapter 모듈 standalone MockMvc 로 재설계. (→ raw/errors/webmvctest-nested-springbootconfiguration-context-pollution-2026-06-01)

핵심 메시지 / Thesis (raw)

운영 에러/관측성 "기반 계약"은 화려한 기능이 아니라 모든 어댑터가 같은 실패 언어를 쓰게 만드는 어휘 고정이다. 그 어휘를 (1) enum SSOT, (2) registry 매핑, (3) 단일 변환 지점, (4) 컴파일러로 강제되는 additive 확장으로 박아두면, 이후 모든 기능 branch 가 그 위에서 일관되게 쌓인다.

글감 / Topic seed

  • 한 문장 요지: 기존 envelope을 깨지 않고 error.categorymeta를 추가해 운영 에러 어휘와 관측성 식별자를 한 응답 계약으로 묶는다.
  • 예상 제목 후보:
    • API error envelope에 meta와 category를 추가한 이유
    • 운영 에러 어휘를 enum과 response meta로 고정하기

핵심 주장 후보 / Claim candidates

  • 사실 후보:
    • operational error foundation branch가 category enum, response meta, MDC key, header sanitization을 다룬다.
    • additive record component 추가는 호출부 compile error로 migration blast radius를 드러낸다.
  • 의견/해석 후보:
    • 운영 에러 기반 계약은 모든 adapter가 같은 실패 언어를 쓰게 만드는 어휘 고정 작업이다.

Outline seed

  1. 기존 envelope에 metacategory를 추가해야 했던 이유를 설명한다.
  2. enum SSOT, registry mapping, response meta factory의 역할을 나눈다.
  3. header sanitization과 log injection 방어를 관측성 계약의 일부로 다룬다.

Canonical 전환 후보 / Canonical extraction candidates

  • wiki/projects/ca-tmpl/api-error-envelope-design.md 후보:
    • verified envelope meta/category migration 글감.
  • 필요한 추가 검증:
    • blogify 전 운영 검증이 아니라 local verification 범위임을 유지한다.

Sources / 근거 후보

미해결 / Unknown

  • 아직 확인해야 할 사실: 운영 배포/측정 근거는 없다.
  • 과장하면 안 되는 부분: verified canonical이더라도 prod verification으로 확대하지 않는다.

관련

Decision / 처리 결정

  • 액션: promote-to-canonical
  • 이유: wiki/projects/ca-tmpl/api-error-envelope-design.md 에 meta/category migration과 operational error vocabulary 글감으로 반영했다.
  • 다음 단계: source canonical이 verified 상태이므로 이후 blogify 대상으로 삼을 수 있다. 단 운영 검증으로 확대하지 않는다.