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

138 lines
13 KiB
Markdown

---
title: ArchUnit Annotation-as-Registry Pattern Evaluation
source_type: official-doc
url: https://www.archunit.org/userguide/html/000_Index.html
archive_url:
status: needs-confirmation
confidence: medium
related_branches: [feature-contract-registry-governance]
related_projects: [ca-tmpl]
tags: [ca-governance, archunit, registry, annotation, fitness-functions]
created: 2026-05-22
last_reviewed: 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
- 원본 URL (ArchUnit User Guide): https://www.archunit.org/userguide/html/000_Index.html
- 보조 URL: https://github.com/TNG/ArchUnit-Examples
- 보조 참조: *Building Evolutionary Architectures* (Ford, Parsons, Kua) — fitness functions 개념
- 보조 URL: https://www.baeldung.com/java-archunit-intro
- 아카이브 URL: (미수집)
- 저자 / 조직: ArchUnit 프로젝트 (TNG Technology Consulting)
- 발행 상태: ArchUnit User Guide v1.4.x 기준 지속 갱신 (2026-04 기준 최신)
- 마지막 확인일: 2026-05-27
## 핵심 인용 / 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를 권고하는 구절은 본 문서에서 확인되지 않음. 책 원문 재확인 필요.
## Related / 관련
- 같은 주제 다른 official-doc:
- [[raw/official-docs/governance-archunit-official]] (ArchUnit 공식 소개)
- [[raw/official-docs/archunit-conditional-on-property-3-layer-pattern]] (Layer 2 정적 검사 가능 범위)
- 인용하는 branch:
- [[raw/branch-notes/feature-contract-registry-governance]] (Group G-G 본체)
- canonical contract 섹션:
- [[raw/project-notes/ca-skeleton-operational-contract]] — §21 Contract Registry, §29 Group G-G
- 관련 wiki:
- [[wiki/concepts/skeleton-governance-registry-verification-test-scorecard]] (작성 시)
- [[wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard]] (작성 시)