Files
llm-wiki/raw/official-docs/archunit-annotation-as-registry-evaluation.md

13 KiB

title, source_type, url, archive_url, status, confidence, related_branches, related_projects, tags, created, last_reviewed
title source_type url archive_url status confidence related_branches related_projects tags created last_reviewed
ArchUnit Annotation-as-Registry Pattern Evaluation official-doc https://www.archunit.org/userguide/html/000_Index.html needs-confirmation medium
feature-contract-registry-governance
ca-tmpl
ca-governance
archunit
registry
annotation
fitness-functions
2026-05-22 2026-05-27

ArchUnit Annotation-as-Registry Pattern Evaluation

Layer: raw/official-docs/ — ArchUnit User Guide 발췌 + ca-tmpl Group G-G(feature-contract-registry-governance)의 markdown SSOT 채택에 대한 후속 대안 평가 의 외부 근거.

평가 결과: ArchUnit annotation 기반 registry는 검토되었으나 채택되지 않음. markdown SSOT 유지. 본 문서는 그 결정의 근거를 보존한다.

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-contract-registry-governance Group G-G 결정 — "ArchUnit annotation-as-registry" 대안 평가 후 markdown SSOT 유지 결정의 근거 (annotation 의 공식 능력 범위 + registry SSOT 로 권고되지 않는다는 absence-of-evidence)

컨텍스트 / 왜 저장했는지

ca-tmpl feature-contract-registry-governance (Group G-G)는 markdown SSOT + YAML generated constants를 contract registry 저장 형식으로 채택했다. 이때 검토되었어야 하나 상세 평가가 누락된 대안이 있다.

ArchUnit이 제공하는 @ArchTest, @AnalyzeClasses, custom @interface 패턴을 그 자체로 registry로 쓰는 방식.

본 문서는 (a) ArchUnit annotation 기능이 무엇인지 인용으로 보존하고, (b) markdown SSOT vs annotation-as-registry 비교 표를 남겨, ca-tmpl 결정을 사후에 검증 가능하도록 한다.

출처 / Source

핵심 인용 / Key quotes (verbatim)

[§JUnit support — @ArchTest / @AnalyzeClasses] "declare ArchUnit's ArchUnitRunner (only JUnit 4), declare the classes to import via @AnalyzeClasses and add the respective rules as fields" + "The JUnit test support will automatically import (or reuse) the specified classes and evaluate any rule annotated with @ArchTest against those classes."

[§Custom @interface meta-annotation] "@AnalyzeClasses can also be used as a meta-annotation to avoid repeating the same configuration" + "This annotation can then be used on test classes without repeating the specific configuration of @AnalyzeClasses"

[§LayeredArchitecture rule] "layeredArchitecture()...layer("Controller").definedBy("..controller..")...whereLayer("Controller").mayNotBeAccessedByAnyLayer()"

[§Writing Custom Rules — DescribedPredicate + ArchCondition] "most architectural rules take the form: classes that ${PREDICATE} should ${CONDITION}" (implementation requires "exposing the concepts of DescribedPredicate and ArchCondition")

[§Building Evolutionary Architectures (Ford et al.)] "Architectural fitness functions — any mechanism that provides an objective integrity assessment of some architectural characteristic(s)."

Claims Extracted / 추출된 주장

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
AAR-C1 @ArchTest 는 ArchUnit JUnit runner 가 평가할 ArchRule field 를 마킹하는 annotation; @AnalyzeClasses 는 import 대상 classes 를 선언하는 annotation. 둘은 runner 입력 (framework annotation) 역할 [§JUnit support — @ArchTest / @AnalyzeClasses] "declare the classes to import via @AnalyzeClasses and add the respective rules as fields... evaluate any rule annotated with @ArchTest against those classes." official-vendor-doc ArchUnit JUnit 통합 환경 @ArchTest/@AnalyzeClasses 가 도메인 contract registry (error code, env key 등) 를 표현하는 용도라는 뜻은 아님 — runner 입력 전용
AAR-C2 ArchUnit 공식이 안내하는 custom @interface 패턴의 명시 목적은 @AnalyzeClasses 설정 중복 제거용 meta-annotation [§Custom @interface meta-annotation] "@AnalyzeClasses can also be used as a meta-annotation to avoid repeating the same configuration" official-vendor-doc ArchUnit User Guide 가 안내하는 meta-annotation 패턴 도메인 contract 를 custom annotation 으로 registry 화 하는 것이 공식 권장 패턴이라는 뜻은 아님 (User Guide 에 명시 부재 — absence of evidence)
AAR-C3 ArchUnit 의 LayeredArchitecture rule 은 DSL string + ArchRule 형태로 layer 를 정의하고 접근 제약을 표현 (.layer().definedBy("..controller..").whereLayer().mayNotBeAccessedByAnyLayer()) [§LayeredArchitecture rule] "layeredArchitecture()...layer("Controller").definedBy("..controller..")...whereLayer("Controller").mayNotBeAccessedByAnyLayer()" official-vendor-doc layer 기반 아키텍처 강제 custom annotation 으로 layer 를 "등록" 하는 패턴이 공식 예제에 포함된다는 뜻은 아님
AAR-C4 ArchUnit 의 custom rule 작성 패턴은 DescribedPredicate + ArchCondition 조합으로 "classes that ${PREDICATE} should ${CONDITION}" 형식 [§Writing Custom Rules — DescribedPredicate + ArchCondition] "most architectural rules take the form: classes that ${PREDICATE} should ${CONDITION}" official-vendor-doc custom ArchRule 작성 이 패턴이 SSOT registry 역할을 한다는 뜻은 아님 — 검증 (verifier) 형식
AAR-C5 Building Evolutionary Architectures 의 fitness function 정의는 "아키텍처 특성에 대한 객관적 무결성 평가를 제공하는 모든 mechanism" — ArchUnit 은 이 정의의 mechanism (verifier) 에 해당 [§Building Evolutionary Architectures (Ford et al.)] "any mechanism that provides an objective integrity assessment of some architectural characteristic(s)." engineering-blog (서적 출처) fitness function 개념 일반 fitness function 이 SSOT 역할까지 포함한다는 정의가 있다는 뜻은 아님 — verifier 정의에 한정

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것:
    • AAR-C1: @ArchTest/@AnalyzeClasses 의 runner-입력 역할
    • AAR-C2: ArchUnit User Guide 가 명시적으로 안내한 custom @interface 유일 use case (= @AnalyzeClasses meta-annotation)
    • AAR-C3: LayeredArchitecture 의 DSL string 기반 layer 정의 패턴
    • AAR-C4: custom rule 작성의 표준 형식 (PREDICATE + CONDITION)
    • AAR-C5: fitness function 의 정의 = mechanism/verifier
  • 이 자료가 증명하지 않는 것:
    • ArchUnit annotation 을 도메인 contract registry SSOT 로 권장한다는 명제 (User Guide 에 명시 부재)
    • markdown SSOT vs annotation 의 우월성 비교 (본 자료는 ArchUnit 능력 정의만 — 비교 표는 ca-tmpl 자체 분석)
    • polyglot stack (Python, frontend) 에서 ArchUnit annotation 이 작동한다는 명제 (JVM 한정)
    • "annotation 없는 사용을 javac/ArchUnit 이 silently pass" 라는 명제 (별도 검증 메커니즘 부재 — 본 자료는 그 사실을 직접 말하지 않음)
  • 내 프로젝트(ca-tmpl) 에 적용하려면 추가 확인이 필요한 것:
    • markdown SSOT 의 drift 검증 스크립트 실제 구현 여부 (ca-tmpl 한계로 문서화됨)
    • polyglot 환경 도래 시 IDL registry (Protobuf/Smithy) 로의 마이그레이션 결정 (raw/official-docs/schema-protobuf-vs-json-evolution 참고)
    • Building Evolutionary Architectures 책 원문에서 annotation-as-SSOT 권고/반대 구절 직접 확인 (현재 needs-confirmation)

markdown SSOT vs annotation-as-registry 비교 표 (내 프로젝트 해석 — 미검증)

본 표는 자료 직접 인용 아님. ca-tmpl 자체 평가.

항목 markdown SSOT + YAML generated (ca-tmpl 채택) ArchUnit annotation-as-registry (대안)
저장 위치 branch-note + docs/registries/*.yml src/.../annotations/*.java (@interface 또는 marker class)
사람이 읽기 markdown table — 외부 리뷰어·비개발자도 가능 Java 소스 — IDE/컴파일러 필요
framework 종속 없음 (Spring/JPA/JUnit과 분리) Java + ArchUnit lock-in
다언어 재사용 YAML 파생을 어느 언어든 로딩 가능 JVM 한정. polyglot stack에는 부적합
git diff review 표 row 단위 변경 명확 annotation attribute diff는 가독성 떨어짐
외부 도구 호환 Obsidian dataview, IDE markdown 미리보기, GitHub render ArchUnit + javac만
"왜" 컨텍스트 보존 branch-note의 결정/근거/대안 라인이 함께 위치 annotation attribute는 짧은 string에 한정
누락 검출 drift 검증 스크립트 자체 작성 필요 (한계) annotation 없는 코드는 silently pass — 더 위험
변경 절차 row 추가 → contract test → .env.example 갱신 (명문화됨) annotation 추가 → 새 rule field 정의. 절차가 분산
fitness function 적합도 registry는 SSOT, fitness function은 별도 verifier annotation = SSOT + verifier 혼합. 역할 경계 흐려짐
단일 팀 적용 비용 markdown 작성 비용만 annotation 설계 + ArchUnit rule 작성 + maintenance
breaking change 정책 row의 compatibility_impact 열로 명시 annotation attribute 변경 시 모든 사용처 수정

메모 / Notes (내 프로젝트 해석) — 평가 결론

ca-tmpl은 markdown SSOT를 유지한다. 근거:

  1. framework-neutral. registry는 Spring/JPA/JUnit과 분리되어야 한다. error code/env key/header/log field는 polyglot stack(예: Python sidecar, frontend)에도 동일하게 적용될 수 있어야 하며, Java annotation은 이를 막는다.
  2. 외부 도구 호환. Obsidian dataview, IDE markdown 미리보기, GitHub web view, LLM Wiki /query가 모두 markdown을 1급으로 다룬다. annotation은 javac/ArchUnit/IDE plugin이 필요하다.
  3. git diff review가 가능하다. PR review에서 비개발자(예: PM, 운영) 또는 외부 컨설턴트가 row 변경을 읽을 수 있다. annotation diff는 Java 문법 지식이 필요하다.
  4. "왜" 컨텍스트가 branch-note와 같이 위치. branch-note ≈ mini-ADR 패턴이 깨지지 않는다.
  5. annotation은 verifier로만 사용. ArchUnit은 registry가 아닌 fitness function 실행 mechanism으로만 ca-tmpl에 들어간다 (이미 §12 verification suite에 반영).

단, 다음 사실을 명시한다.

  • ca-tmpl의 markdown SSOT는 drift 검증 스크립트가 미작성이다 (concept 문서 한계 섹션과 동일). annotation 방식은 javac/ArchUnit이 "어노테이션 없는 사용"을 잡을 수 있다는 강점이 있으나, 어노테이션 자체의 누락 검출이 별도로 필요하다는 점은 양쪽 모두 동일.
  • 본 평가는 ca-tmpl의 단일 팀 / 단일 release train / JVM 단일 stack 컨텍스트에 한정. 멀티 팀·polyglot 환경에서는 IDL registry(Protobuf/Smithy)가 우위일 수 있으며, 이는 raw/official-docs/schema-protobuf-vs-json-evolution 참고.

추가 검증 필요 (needs-confirmation 사유)

  • ArchUnit User Guide에서 "annotation을 도메인 contract registry로 권고"하는 공식 문구는 발견되지 않음. 본 문서는 ArchUnit이 그 목적으로 설계되지 않았다는 해석이며, 공식적으로 명시되지 않은 부재(absence)에 근거함.
  • TNG/ArchUnit-Examples 저장소는 @ArchTest/@AnalyzeClasses 사용 예제만 포함, custom @interface registry 예제는 없음 (확인 완료).
  • Building Evolutionary Architectures 인용은 fitness function 정의 부분만 확인. annotation-as-SSOT를 권고하는 구절은 본 문서에서 확인되지 않음. 책 원문 재확인 필요.