# 가족 지침이 이 계약의 주인으로 지목한 것
  src/messaging/CLAUDE.md:36 - 반대로 **노출하지 않는 것은 `implementation`으로 낮춘다.** starter가 노출하지 않는 하위 모듈을
  src/messaging/CLAUDE.md:37   `implementation`으로 내린 것이, JSON codec이 `ObjectMapper`를 private으로만 쓰고 Jackson을
  src/messaging/CLAUDE.md:38   `implementation`으로 둔 것이 그 예다.
  src/messaging/CLAUDE.md:39 - 이 규칙은 문서가 아니라 `MessagingPublicSurfaceContractTest`가 붙들고 있다. leaf의 production
  src/messaging/CLAUDE.md:40   source에서 public/protected 시그니처에 등장하는 vendor 라이브러리를 뽑아 그 leaf의
  src/messaging/CLAUDE.md:41   `build.gradle`이 `api`로 선언했는지 대조하고, starter의 `api` closure에 broker client 두 개가
  src/messaging/CLAUDE.md:42   들어오지 않는 것도 함께 본다. Spring Framework/Boot는 대상이 아니다 — 조립 경계 안에서만
  src/messaging/CLAUDE.md:43   등장하고 adopter가 이름 부를 일이 없다.
  src/messaging/CLAUDE.md:44 - 새 public 타입은 그 모듈의 계약이다. 삭제·시그니처 변경은 breaking change로 취급한다.

# 그 시험 클래스가 놓인 트리
  src/app-bootstrap/src/test/java/dev/caskeleton/bootstrap/contract/messaging/MessagingPublicSurfaceContractTest.java
    src/messaging 아래 동명 파일 : 0 개
    가족 test 트리 : 24 개 · 이 파일의 트리 : src/app-bootstrap/src/test
    이 파일의 @Test 3 · @Tag 0 · @Disabled 0
    :73  void vendorTypesInPublicSignaturesAreDeclaredApi() {
    :94  void theScanIsNotVacuous() {
    :114  void neitherBrokerSdkReachesAnAdoptersCompileClasspath() {

# 가족 경로에서 도는 워크플로의 트리거 전부와 실행 명령
  messaging-certification.yml:15 on:
  messaging-certification.yml:16   pull_request:
  messaging-certification.yml:17     paths:
  messaging-certification.yml:18       - "src/messaging/**"
  messaging-certification.yml:19       - ".github/workflows/messaging-certification.yml"
  messaging-certification.yml:20   schedule:
  messaging-certification.yml:21     - cron: "41 4 * * 3"
  messaging-certification.yml:22   workflow_dispatch:
  messaging-certification.yml:52  run: ./gradlew :messaging:messaging-kafka:verifyMessagingCertificationEvidence --no-daemon --stacktrace

# 경로 필터가 없는 워크플로
  ci-quality-gates.yml:1 name: ci-quality-gates
  ci-quality-gates.yml:2 
  ci-quality-gates.yml:3 on:
  ci-quality-gates.yml:4   pull_request:
  ci-quality-gates.yml:5   push:
  ci-quality-gates.yml:6     branches: ["main"]
  ci-quality-gates.yml:7   workflow_dispatch:
  ci-quality-gates.yml:8 
  ci-quality-gates.yml:9 permissions:
    on 블록(1-9)의 paths 필터 : 0 건
  ci-quality-gates.yml:19 jobs:
  ci-quality-gates.yml:20   quality-gates:
  ci-quality-gates.yml:21     runs-on: ubuntu-latest
  ci-quality-gates.yml:22     steps:
  ci-quality-gates.yml:48       - name: Check quality, public paths, and dependency locks
  ci-quality-gates.yml:49         working-directory: src
  ci-quality-gates.yml:50         run: ./gradlew check verifyPublicPathSnapshot verifyDependencyLocks --warning-mode=fail --no-daemon --stacktrace
  ci-quality-gates.yml:51       # Named as its own step because nothing else runs it: `check` does not depend on
  ci-quality-gates.yml:52       # graphqlStableTest, so the lane's required-class guard — the check that its module-boundary
  ci-quality-gates.yml:53       # suite has not silently stopped being discovered — protected nothing in CI. A separate step
  ci-quality-gates.yml:54       # keeps the aggregate invocation below byte-identical, which ConditionalTransportQualification
  ci-quality-gates.yml:55       # ContractTest asserts on, and the two tasks do not overlap.

# check 가 정말 이 프로젝트의 test 를 포함하는가
  $ ./gradlew :app-bootstrap:check --dry-run
    :app-bootstrap:test SKIPPED
    :app-bootstrap:functionalTest SKIPPED
    :app-bootstrap:check SKIPPED
  루트 test 규약이 거는 유일한 필터 :
    src/build.gradle:549     tasks.named('test') {
    src/build.gradle:550         useJUnitPlatform {
    src/build.gradle:551             excludeTags 'quarantine'
    src/build.gradle:552         }
    src/build.gradle:553     }

# 이름으로 골라 실제로 돌리면
  $ ./gradlew :app-bootstrap:test --tests '...MessagingPublicSurfaceContractTest'
    BUILD SUCCESSFUL
    결과 디렉터리 test/ · MessagingPublicSurfaceContractTest tests=3 failures=0 skipped=0

# 가족 태스크로 같은 이름을 고르면
  $ ./gradlew :messaging:messaging-kafka:test --tests '...MessagingPublicSurfaceContractTest'
    > No tests found for given includes: [dev.caskeleton.bootstrap.contract.messaging.MessagingPublicSurfaceContractTest](--tests filter)
    BUILD FAILED
