Files
llm-wiki/raw/errors/archunit-no-uuid-random-trace-id-false-positive-2026-06-01.md
T

4.3 KiB

title, source_type, status, related_branches, related_projects, tags, created, status_label
title source_type status related_branches related_projects tags created status_label
error / archunit-no-uuid-random-trace-id-false-positive-2026-06-01 error-note raw
feature-resource-identifier-contract
ca-skeleton
error
ca-skeleton
architecture
archunit
identifier
trace-id
scoping
2026-06-01 resolved

error: archunit-no-uuid-random-trace-id-false-positive-2026-06-01

Layer: raw/errors/ — 작업 중 마주친 단일 실패·트러블슈팅 기록. 원본은 raw에 영구 보관한다.

Parent / 부모

증상 / Symptom

  • 에러 메시지 (원문 그대로):
    Rule 'D5/D17 no_uuid_random_in_controller: ...' was violated (1 times):
    Method <dev.caskeleton.adapter.web.filter.RequestLoggingFilter.doFilterInternal(...)>
    calls method <java.util.UUID.randomUUID()> in (RequestLoggingFilter.java:43)
    
  • 발생 컨텍스트: cd src && ./gradlew :app-bootstrap:test 실행 중 CleanArchitectureTest.no_uuid_random_in_controller 실패.
  • 발생 시점: 2026-06-01 (D17 rule을 boundary suite에 추가한 직후 1차 실행)
  • 재현 가능 여부: always — rule 대상 package를 ..adapter.web..(광범위)로 두면 기존 RequestLoggingFilter가 항상 걸림.

재현 절차 / Reproduction

  1. no_uuid_random_in_controllernoClasses().that().resideInAnyPackage("..adapter.web..", "..application..")로 작성.
  2. cd src && ./gradlew :app-bootstrap:test --tests '*CleanArchitectureTest' 실행.
  3. 기대 결과: resource id 생성만 차단.
  4. 실제 결과: RequestLoggingFilterX-Request-Id 생성(UUID.randomUUID())까지 위반으로 잡힘.

근본 원인 / Root cause

  • 직접 원인: rule의 selector가 ..adapter.web.. 전체였는데, web filter는 controller가 아니며 correlation/trace id를 생성한다.
  • 근본 원인: spec D17 결정 텍스트는 "controller / service / use case layer"로 한정했으나, §6 reference 코드는 광범위한 ..adapter.web..를 썼다. 둘 사이의 미세 불일치가 구현 시 노출. 또한 trace/correlation id는 D18에서 본 branch 범위 밖(distributed-tracing-contract)으로 명시돼 있어, resource-id rule이 잡으면 안 되는 대상이었다.
  • 트리거 조건: 기존 production filter가 합법적으로 UUID.randomUUID()를 trace id 용도로 사용 중.

해결 / Resolution

  • 적용한 조치: selector를 D17 결정 텍스트에 맞춰 ..adapter.web..controller.. + ..application..로 좁혔다. trace/correlation id 생성(web filter)은 의도적으로 scope 밖임을 rule .as(...) 설명에 명시.
  • 검증 방법:
    • cd src && ./gradlew :app-bootstrap:test verifyCleanArchitectureDependencies 성공.
    • cd src && ./gradlew check 전체 성공.
  • 잔여 위험 / 후속 작업: filter/interceptor가 resource id를 생성하는 안티패턴은 이 rule로는 안 잡힌다(범위 밖). 필요 시 distributed-tracing-contract 또는 별도 rule로 분리.

회고 / Lessons

  • 빨리 감지하는 신호: 새 ArchUnit rule이 기존 합법 코드를 잡으면, rule이 틀렸을 가능성을 먼저 의심하고 위반 대상의 의도(여기선 trace id vs resource id)를 확인.
  • 예방 체크리스트: rule selector는 spec의 "결정 텍스트"(좁은 의도)와 "reference 코드"(넓은 예시)가 다를 때 결정 텍스트를 따른다. id 생성 규칙은 어떤 id인지(resource / trace / session / idempotency) 항상 구분한다.
  • 일반화된 교훈: 식별자 거버넌스 규칙은 "ID 종류"별로 책임 branch가 다르다 — 한 rule이 모든 UUID.randomUUID()를 잡으면 cross-domain false positive가 난다.