--- kind: CASE slug: messaging-policy-f04 title: DLQ 메타데이터의 두 시각이 항상 같다 topic: transport-and-provider-semantics project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: case:messaging-policy-f04 evidenceCapturedOn: 2026-09-01 assets: - key: messaging-policy-f04 file: ../../../final/evidence/rendered/messaging-policy-f04.svg evidence: - ../../../final/evidence/raw/messaging-policy-f04.txt source: - 원본 분석 절은 final/document.md#a19-messaging-policy#L808 이다. module: messaging-policy priority: P3 --- # DLQ 메타데이터의 두 시각이 항상 같다 DeadLetterMetadata가 firstFailureAt과 lastFailureAt을 별도 필드로 선언하는데, 유일한 생산 지점인 DeadLetterOrchestrator:89-97이 둘 다 delivery.metadata().receivedAt()으로 채운다. 두 헤더(msg.first-failure-at, msg.last-failure-at)가 DLQ 메시지에 붙는데 항상 같은 값이다. ## 관계 - **구성 오류는 한 예외 타입과 안정 코드로 보고한다** 같은 분석 리프에서 끌어낸 규칙이다. - **저장소 밖 문서를 절 번호로 인용하지 않는다** 같은 분석 리프에서 끌어낸 규칙이다. - **부팅 경로의 알고리즘 복잡도는 문서화한다** 같은 분석 리프에서 끌어낸 규칙이다. ## 문제 DeadLetterMetadata가 firstFailureAt과 lastFailureAt을 별도 필드로 선언하는데, 유일한 생산 지점인 DeadLetterOrchestrator:89-97이 둘 다 delivery.metadata().receivedAt()으로 채운다. 두 헤더(msg.first-failure-at, msg.last-failure-at)가 DLQ 메시지에 붙는데 항상 같은 값이다. ## 결론 운영자가 "이 메시지가 얼마나 오래 실패해 왔는가"를 헤더에서 알 수 없다. ReservedHeaders가 두 이름을 따로 정의한 목적이 실현되지 않는다. ## 검증 환경 OpenJDK : 21.0.12 java -version 으로 확인 Gradle : 9.0.0 src/gradle/wrapper/gradle-wrapper.properties 의 distributionUrl 로 확인 확인 방식 : DeadLetterMetadata 참조 5건 검색과 유일한 생산 지점이 두 필드에 넣는 값 확인 소스 수정 : x ## 재현 조건 원문은 final/document.md#a19-messaging-policy#L808 에 있다. ## 본문 `DeadLetterMetadata`가 `firstFailureAt`과 `lastFailureAt`을 별도 필드로 선언하는데, 유일한 생산 지점인 `DeadLetterOrchestrator:89-97`이 둘 다 `delivery.metadata().receivedAt()`으로 채운다. ## DeadLetterMetadata 참조 위치 :::evidence key="messaging-policy-f04" alt="코드베이스에서 DeadLetterMetadata 를 검색한 출력 5줄. 이 기록이 세는 참조가 그 출력에 그대로 보인다." caption="DeadLetterMetadata 코드베이스 검색 — 5줄 · exit 0" zoom="true" ::: ## 두 헤더가 항상 같은 값이다 `msg.first-failure-at`, `msg.last-failure-at` 가 DLQ 메시지에 붙는다. 운영자가 "이 메시지가 얼마나 오래 실패해 왔는가"를 헤더에서 알 수 없다 — `ReservedHeaders`가 두 이름을 따로 정의한 목적이 실현되지 않는다. ## 확인하지 못한 것 DLQ 메시지의 두 헤더가 실제 배포에서 같은 값을 갖는 것을 관측하지 않았다. 생산 지점 한 곳의 코드로 판정했다.