# 주제: Stable/Advanced 경계를 지킨다고 선언된 세 주체 중 어느 것도
#       카탈로그를 레지스트리와 대조하지 않는다
# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
# severity: P2

# ---- 선언 ----
# GrpcStableModuleCatalog.java:6-17 (클래스 javadoc)
#   "The Stable plan fixes its module list as a Global Constraint so that "this capability is
#    Stable" is a fact with one owner instead of a property of whatever happens to be on a classpath.
#    This repository's module registry (src/config/architecture/modules.json) is the SSOT for
#    which Gradle projects exist; this catalog is the SSOT for which of them the Stable contract
#    covers, and **GrpcStableModuleCatalogTest holds the two together.**"
#
# GrpcStableBuildInvariant.java:5-11
#   "These are asserted from Java as well as from Gradle on purpose. The registry gate
#    (verifyCleanArchitectureDependencies) is the one that fails a build, and it is the authority;
#    this class is what a runtime component calls when it is handed a dependency set it did not
#    compile against."

# ---- 측정 1: 테스트는 modules.json 을 읽지 않는다 ----
# GrpcStableModuleCatalogTest.java 전문 60줄, 5개 테스트:
#   stableModuleSetIsExactAndAdvancedIsExcluded  -> 하드코딩 4개 이름 contains + advanced 제외
#   stableAndAdvancedAreDisjoint                 -> 두 상수 집합의 교집합 없음
#   stableModuleMayNotDependOnAdvanced           -> requireNoAdvancedDependency 가 던짐
#   stableOnlyDependenciesPass                   -> 안 던짐
#   advancedModuleIsNotGovernedByTheStableRule   -> advanced 는 규칙 밖
#
# import 목록: java.util.Set, org.junit..., assertj 뿐.
# **파일·경로·JSON 을 읽는 코드가 없다.**
# => "holds the two together" 는 성립하지 않는다.
#    modules.json 에 grpc 리프가 추가·제거·개명되어도 이 카탈로그는 알지 못한다.
#    두 상수 집합(STABLE 12 + ADVANCED 6 = 18)이 현재 레지스트리와 일치하는 것은
#    누군가 손으로 맞춰 두었기 때문이다.

# ---- 측정 2: Gradle 게이트는 Stable/Advanced 를 모른다 ----
# build-logic/src/main/groovy/ca.architecture-registry.settings.gradle:19-23 이
# 저장소의 레지스트리 게이트 3종을 열거한다:
#   verifyCleanArchitectureDependencies — "fails when a declared project has no entry or an entry
#                                          no project" (+ 선언 edge ⊇ 해소 edge)
#   verifyRuntimeModuleMembership      — "compares the resolved runtime closure against the
#                                          declared memberships"
#   verifyDocumentedLeafCount          — "fails any document that states a count the registry
#                                          disagrees with"
# ModuleRegistry.groovy:27-31 의 필드 집합:
#   ['id','gradle_path','source_path','allowed_dependencies','runtime_memberships']
# => 레지스트리 스키마에 Stable/Advanced 개념이 없다. 세 게이트 중 어느 것도 그 분할을 모른다.
#    javadoc 이 "the authority" 라고 부른 게이트는 **선언 edge 적합성**을 강제하지
#    Stable≠Advanced 를 강제하지 않는다.
#    현재 그 분할이 성립하는 것은 allowed_dependencies 를 쓴 사람이 지켰기 때문이다
#    (EVD-325 표: Stable 리프 12개 중 advanced 를 의존하는 것이 없다).

# ---- 측정 3: 런타임 검사는 실제로 배선되어 있다 ----
# command: git grep -n "requireNoAdvancedDependency" -- src
#   GrpcStableBuildInvariant.java:113                       (정의)
#   GrpcAdvancedModuleGuard.java:76                         (grpc-advanced-bootstrap, 프로덕션)
#   GrpcPlatformStartupValidator.java:176                   (grpc-spring-boot-starter, 프로덕션)
#   GrpcStableModuleCatalogTest.java:39,50,57               (테스트)
# => 이 셋 중 유일하게 실제로 도는 검사다. 다만 **호출자가 넘긴 의존 집합**을 볼 뿐이고,
#    그 집합이 레지스트리와 일치하는지는 검사하지 않는다.

# ---- 판정 ----
# 세 주체가 각각 다른 것을 검사한다:
#   테스트          : 두 하드코딩 상수 집합이 서로소인가 (항상 참, 손으로 그렇게 썼으므로)
#   Gradle 게이트   : 선언 edge 와 해소 edge 가 맞는가 (Stable/Advanced 무관)
#   런타임 불변식   : 넘겨받은 집합에 advanced 가 섞였는가 (호출자가 정직할 때만 유효)
# **카탈로그와 레지스트리를 대조하는 주체가 없다.**
# 이것은 messaging-testkit 의 BrokerFailureMatrix javadoc 과 같은 형태다 —
# "That rule is enforced by a test rather than documented" 인데 그 테스트가 규칙을 강제하지 않는다.

# ================= 정정 (grpc-spring-boot-starter 분석 중 발견) =================
# 위 "측정 2" 의 판정이 과했다. Stable 리프가 advanced 를 의존하는 것은 **실제로 막힌다**.
#
# (a) modules.json 의 grpc-spring-boot-starter allowed_dependencies 가 advanced id 를 하나도
#     담지 않는다(EVD-325 표). build.gradle 에 advanced project 의존을 추가하면 해소 edge 가
#     선언 집합에 없게 되어 verifyCleanArchitectureDependencies 가 실패한다.
#     => 게이트는 분할을 "모르지만", 레지스트리 내용을 통해 결과적으로 강제한다.
#
# (b) GrpcPlatformStartupValidatorTest:245-257 이 **실제 build.gradle 파일을 읽는다**:
#       @DisplayName("the auto-configuration is registered and reaches no Advanced module")
#       // matching on the prose would fail on the sentence stating the rule, so:
#       assertThat(read(Path.of("build.gradle"))).doesNotContain("project(':grpc-advanced");
#     => 좁지만 실제 저장소 내용을 검사하는 테스트가 있다.
#
# (c) GrpcPlatformStartupValidatorTest:215-222 이 requireNoAdvancedDependency 를 기동 시나리오로
#     단언한다.
#
# grpc-spring-boot-starter/build.gradle:4-7 의 주장 —
#   "That is not a comment — the registry's allowed_dependencies for this leaf omits every advanced
#    id, verifyCleanArchitectureDependencies enforces it, and GrpcPlatformStartupValidatorTest
#    asserts the same rule from the Java side."
# — 세 주장이 전부 확인된다.
#
# 남는 정확한 결함은 하나로 좁혀진다:
#   **GrpcStableModuleCatalog 의 STABLE/ADVANCED 이름 목록(12+6)이 modules.json 과 대조되지 않는다.**
#   리프가 추가·개명·제거되어도 카탈로그는 알지 못한다. GrpcStableModuleCatalogTest 는 JSON 을 읽지 않는다.
#   이것은 "Stable 이 advanced 를 의존하는가" 와는 다른 질문이며, 그 질문만 답이 없다.
# ==============================================================================

# ---- 부수 확인: grpc 18개의 빈 멤버십은 검증된 상태다 ----
# verifyRuntimeModuleMembership 이 "resolved runtime closure against the declared memberships" 를
# 비교하므로, 18개 리프의 runtime_memberships:[] 는 레지스트리 실수가 아니라
# **게이트가 확인한 사실**이다. EVD-325 의 판정을 강화한다.
