--- kind: CASE slug: a07-f004-claude title: 문서가 선언됐다는 둘은 없고, 선언된 하나는 그 문장에 없다 topic: identity-and-identifier project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: case:a07-f004-claude evidenceCapturedOn: 2026-09-02 assets: - key: a07-f004-claude file: ../../../final/evidence/rendered/a07-f004-claude.svg evidence: - ../../../final/evidence/raw/a07-f004-claude.txt source: - 원본 분석 절은 final/document.md#a07#L131 이다. 등급은 P3 이다. 선언 블록이 두 줄이라는 사실, 도메인 코어와 외부 라이브러리가 선언돼 있지 않다는 판정, 애플리케이션 코어가 언급되지 않았다는 지적, 그리고 실제 선언이 허용 목록의 부분집합이라는 결론이 그 절에 있다. - 그 절은 문서 인용에서 `:application-core` 를 `:application-code` 로 적었다. 원문은 `core` 다. - 앞 문장의 공유 계약이 강제되는 허용 목록에 없다는 것은 이 기록이 새로 확인했다. 그 라이브러리가 이 리프의 클래스패스에 없다는 판정은 그 절에 있고, 여기서는 잠금 파일의 빈 구성 표기로 그것을 다시 확인했다. --- # 문서가 선언됐다는 둘은 없고, 선언된 하나는 그 문장에 없다 리프 지침 문서의 의존성 문단은 두 문장이다. 앞 문장이 든 허용 목록 셋 중 하나는 강제되는 레지스트리에 없다. 뒤 문장이 선언돼 있다고 적은 둘은 어느 쪽도 없고, 실제 선언 하나는 그 문장에 없다. ## 관계 - **사라진 가드가 문서에만 남았고 그 부재는 이미 승인된 결정이다** 같은 문서의 다른 오류다. - **README의 세 가지 사실 오류** 같은 리프의 문서 오류다. - **허용 의존 목록은 상한이므로 미사용을 잡지 않는다** 실제 선언이 그 상한의 부분집합인 이유다. ## 문제 지침 문서에서 허용을 적은 절은 두 문장이다. 앞 문장은 이 리프가 의존할 수 있는 것을 셋으로 적고, 뒤 문장은 지금 빌드 파일에 실제로 선언돼 있다는 것을 적는다. 뒤 문장이 드는 둘 중 하나는 앞 목록의 항목이고 다른 하나는 그 목록에 없는 외부 라이브러리다. ## 결론 빌드 파일의 선언 블록은 두 줄이다. 애플리케이션 코어 프로젝트와 Spock 시험 라이브러리다. 뒤 문장이 든 둘은 어느 쪽도 거기 없다. 도메인 코어는 표기를 가리지 않고 세어도 빌드 파일에 0 건이다. 외부 UUID 생성 라이브러리는 이 리프의 잠금 파일에 없고, 그 잠금 파일은 컴파일과 런타임 클래스패스가 비어 있다고 적는다. 이 저장소는 모든 구성을 엄격 모드로 잠그므로, 그 라이브러리가 시험 경로에만 없는 것이 아니라 프로덕션 경로 자체에 없다. 실제로 그것을 선언하는 곳은 예제 애플리케이션 한 줄이다. 실제로 선언된 애플리케이션 코어는 그 문장에 나오지 않는다. only 라고 쓴 이상 하나를 빠뜨린 것도 위반이다. 앞 문장은 셋 중 둘이 맞고 하나가 어긋난다. 강제되는 목록은 모듈 레지스트리에 있고 거기 적힌 것은 도메인 코어와 애플리케이션 코어다. 문서가 든 셋 중 공유 계약은 그 목록에 없다. 목록의 성격은 서술이 아니라 게이트다. 루트 빌드 파일이 레지스트리에서 허용 간선 표를 파생하고, 허용 밖 간선을 만나면 빌드를 실패시키며, 모든 리프의 검사가 그 태스크에 의존한다. 공유 계약을 실제로 선언하면 빌드가 멈춘다. 빌드 자체는 정합하다. 실제 선언이 허용 목록의 부분집합이다. 어긋난 범위는 문단 하나이고, 그 안의 진술 넷이 사실과 다르다. 판정은 P3 다. ## 검증 환경 Gradle : 9.0.0 확인 방식 : 지침 문서와 빌드 파일·잠금 파일·모듈 레지스트리 대조 소스 수정 : x ## 재현 조건 1. 리프 지침 문서의 허용 절 두 문장을 읽는다. 2. 빌드 파일의 선언 블록을 연다. 3. 도메인 코어를 표기를 가리지 않고 빌드 파일에서 센다. 4. 외부 라이브러리를 리프 잠금 파일에서 세고, 그 잠금 파일이 덮는 구성과 비어 있는 구성을 읽는다. 5. 잠금 모드 설정을 확인한다. 6. 그 라이브러리를 실제로 선언하는 곳을 찾는다. 7. 모듈 레지스트리에서 이 리프의 허용 목록을 읽고 앞 문장의 셋과 대조한다. 8. 그 목록이 어떻게 강제되는지 사슬을 따라간다. ## 본문 지침 문서의 허용 절은 두 문장이다. ## 허용 절과 선언 블록 :::evidence key="a07-f004-claude" alt="리프 지침 문서의 허용 절과 빌드 파일의 선언 블록. 도메인 코어를 빌드 파일에서, 외부 UUID 생성 라이브러리를 리프 잠금 파일에서 각각 센 결과와 그 잠금 파일이 덮는 구성 목록, 비어 있는 구성, 잠금 모드 설정. 그 라이브러리를 실제로 선언하는 곳. 그리고 모듈 레지스트리의 허용 목록과 문서가 든 셋의 차이, 그 목록을 강제하는 코드 사슬을 출력한 터미널 기록." caption="문서는 도메인 코어와 uuid-creator 가 선언됐다고 적음 · 선언 블록은 애플리케이션 코어와 Spock 두 줄 · 빌드 파일의 도메인 코어 언급 0, 잠금 파일의 uuid-creator 0이고 컴파일·런타임 클래스패스는 비어 있음 · 레지스트리 허용 목록에 공유 계약 없음 · 허용 밖 간선은 빌드를 실패시킴 — 39줄 · exit 0" zoom="true" ::: ```text - `:application-core`, `:domain-core`, `:shared-contract` (Gradle matrix). Currently only `:domain-core` + `com.github.f4b6a3:uuid-creator` are declared in [build.gradle](build.gradle). ``` 선언 블록은 두 줄이다. ```groovy dependencies { implementation project(':application-core') testImplementation 'org.spockframework:spock-core:2.4-groovy-5.0' } ``` ## 뒤 문장의 두 이름 ```text # 빌드 파일의 domain-core 언급(모든 표기) : 0 # 잠금 파일 줄 수 / uuid-creator·f4b6a3 : 154 / 0 # 프로덕션 클래스패스의 잠금 상태 : empty=compileClasspath,runtimeClasspath 336: lockAllConfigurations() 337: lockMode = LockMode.STRICT ``` 도메인 코어는 어떤 표기로도 빌드 파일에 없다. 외부 라이브러리 쪽은 잠금 파일이 더 강하게 말한다 — 이 저장소는 모든 구성을 엄격 모드로 잠그고, 이 리프의 컴파일·런타임 클래스패스는 잠긴 채 비어 있다. 시험 경로에만 없는 것이 아니라 프로덕션 경로 자체에 아무것도 없다. 그 라이브러리를 선언하는 곳은 따로 있다. ```text sample-portfolio/build.gradle:52: implementation 'com.github.f4b6a3:uuid-creator:6.1.1' ``` 선언 블록의 유일한 프로젝트 의존은 그 문장에 나오지 않는다. 문장이 `only` 라고 적어 선언 전체를 배타적으로 주장했으므로, 빠뜨린 것도 어긋남이다. ## 앞 문장의 세 이름 ```text # 레지스트리 allowed_dependencies : ['domain-core', 'application-core'] # 문서가 든 셋 중 목록에 없는 것 : ['shared-contract'] ``` 레지스트리가 이 리프에 허용한 것은 둘이다. 셋째 항목은 여기 없다. 이 목록은 서술이 아니라 게이트다. ```groovy 1419: Map> allowedProjectDependencies = registry.modules.collectEntries { module -> ... Set forbidden = actual - allowed if (!forbidden.isEmpty()) { throw new GradleException( ... 577: dependsOn rootProject.tasks.named('verifyCleanArchitectureDependencies') ``` 루트 빌드 파일이 레지스트리에서 허용 간선 표를 파생하고, 허용 밖 간선을 만나면 빌드를 실패시킨다. 모든 리프의 검사가 그 태스크에 의존하므로 이 리프도 지난다. 문서가 매트릭스라고 적은 셋째 항목을 실제로 선언하면 빌드가 멈춘다. ## 실제 선언과 허용 목록 실제 선언은 허용 목록 안에 있다. 간선 쪽에서 고칠 것은 없다. 어긋난 것은 문단 하나이고, 그 문단이 담은 진술 넷이 사실과 다르다. ## 확인하지 못한 것 문서가 든 두 이름이 과거 어느 시점에 실제로 선언되어 있었는지 확인하지 않았다.