2 lines
78 KiB
JSON
2 lines
78 KiB
JSON
{"audit_request":{"assertions":[{"assertion_id":"A-BCP-01","condition":"unconditional","line_end":41,"line_start":41,"modality":"observed","object":"contract_packet: 1","predicate":"has_schema","quote":"- **패킷 스키마**: `contract_packet: 1`","scope":"branch contract packet","source_surface":"SURF-FE97E118291894922127","subject":"branch contract packet"},{"assertion_id":"A-BCP-02","condition":"완료 조건 (completion condition)","line_end":42,"line_start":42,"modality":"must","object":"Gradle module graph가 declared layout과 일치한다","predicate":"requires","quote":"- **완료 조건**: Gradle module graph가 declared layout과 일치한다","scope":"branch contract packet","source_surface":"SURF-FE97E118291894922127","subject":"Work Item 완료 조건"},{"assertion_id":"A-BCP-03","condition":"at packet creation","line_end":40,"line_start":40,"modality":"observed","object":"생성 시 프로젝트 개정 = 1","predicate":"other","quote":"- **생성 시 프로젝트 개정**: `1`","scope":"branch contract packet","source_surface":"SURF-FE97E118291894922127","subject":"branch contract packet"},{"assertion_id":"A-BCP-04","condition":"inherited project decision DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1","line_end":49,"line_start":49,"modality":"must","object":"domain-core·application-core·adapter-*·shared-contract·app-bootstrap·sample-portfolio 책임 분리","predicate":"other","quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1` | Gradle multi-module에서 domain-core·application-core·adapter-*·shared-contract·app-bootstrap·sample-portfolio 책임을 분리한다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |","scope":"module layout","source_surface":"SURF-FE97E118291894922127","subject":"Gradle multi-module module layout"},{"assertion_id":"A-BCP-05","condition":"inherited project decision DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1","line_end":50,"line_start":50,"modality":"observed","object":"Gradle Groovy DSL","predicate":"uses","quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1` | build tool은 Gradle Groovy DSL이다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |","scope":"build tooling","source_surface":"SURF-FE97E118291894922127","subject":"build tool"},{"assertion_id":"A-BCP-06","condition":"unconditional","line_end":55,"line_start":55,"modality":"must","object":"branch-local 결정 (packet에서 복제하지 않음)","predicate":"owns","quote":"> 기존 branch-local 결정은 아래 `## Decision Evidence Map / 결정-근거 매핑`의 D-row가 소유하며 이 packet에서 복제하지 않는다.","scope":"branch-local decisions","source_surface":"SURF-FE97E118291894922127","subject":"Decision Evidence Map D-row (D1~D8)"},{"assertion_id":"A-CTV-00","condition":"unconditional","line_end":300,"line_start":300,"modality":"observed","object":"내 프로젝트의 실 동작을 자동으로 보장하지 않음","predicate":"other","quote":"> 공식 문서나 사례는 근거지만, 내 프로젝트의 실 동작을 자동으로 보장하지 않음.","scope":"claims-to-verify","source_surface":"SURF-98DB94EA489C82CFC10E","subject":"공식 문서/사례 근거"},{"assertion_id":"A-CTV-01","condition":"locally-verified via ./gradlew verifyCleanArchitectureDependencies","line_end":304,"line_start":304,"modality":"must","object":"application/domain의 adapter 의존 (build graph 수준 차단)","predicate":"forbids","quote":"| Gradle multi-module이 application/domain과 adapter 의존을 build graph 수준에서 차단한다 | 우아한형제들/카카오뱅크 사례는 구조 사례이며 ca-tmpl build.gradle이 아직 없음 | `./gradlew verifyCleanArchitectureDependencies`. `application-core`가 `adapter-*`에 의존하면 실패 | `locally-verified` |","scope":"build graph dependency","source_surface":"SURF-98DB94EA489C82CFC10E","subject":"Gradle multi-module"},{"assertion_id":"A-CTV-02","condition":"locally-verified via ArchUnit; framework-neutral POJO 유지","line_end":305,"line_start":305,"modality":"must_not","object":"Spring/JPA annotation import (org.springframework.., jakarta.persistence.., javax.persistence..)","predicate":"forbids","quote":"| `domain-core`가 framework-neutral POJO로 유지된다 | domain module에 Spring/JPA annotation이 들어오는 순간 Clean Architecture 경계가 약해짐 | ArchUnit: `domain-core`에서 `org.springframework..`, `jakarta.persistence..`, `javax.persistence..` import 금지 | `locally-verified` |","scope":"domain-core module","source_surface":"SURF-98DB94EA489C82CFC10E","subject":"domain-core"},{"assertion_id":"A-CTV-03","condition":"locally-verified via ArchUnit + Gradle (adapter-* dependency 금지)","line_end":306,"line_start":306,"modality":"must","object":"port interface만 (outbound 구현체 아님)","predicate":"uses","quote":"| `application-core`가 outbound 구현체가 아닌 port interface만 사용한다 | multi-module이어도 project dependency를 잘못 열면 adapter 구현체 직접 호출이 가능 | ArchUnit + Gradle: `application-core` -> `adapter-*` dependency 금지. 현재 production `application-core`는 anchor 중심이며, reference repository port는 `sample-portfolio/domain/repository`에 격리됨 | `locally-verified` |","scope":"application-core module","source_surface":"SURF-98DB94EA489C82CFC10E","subject":"application-core"},{"assertion_id":"A-CTV-04","condition":"locally-verified-empty-anchor via ArchUnit package rule","line_end":307,"line_start":307,"modality":"must_not","object":"business common 오염 (response/error/header/logging/tracing/metrics/registry/annotation만 허용)","predicate":"forbids","quote":"| `shared-contract`가 business common으로 오염되지 않는다 | shared module은 커지기 쉬워 domain concept가 흘러들 위험이 있음 | ArchUnit package rule: `shared`에는 response/error/header/logging/tracing/metrics/registry/annotation만 허용. 현재는 package anchor만 존재 | `locally-verified-empty-anchor` |","scope":"shared-contract module","source_surface":"SURF-98DB94EA489C82CFC10E","subject":"shared-contract"},{"assertion_id":"A-CTV-05","condition":"locally-verified via Gradle dependency rule + ArchUnit","line_end":308,"line_start":308,"modality":"must_not","object":"production module로 역수입 (production modules must not depend on sample-portfolio)","predicate":"forbids","quote":"| `sample-portfolio`이 production module로 역수입되지 않는다 | sample은 fixture이지만 편의상 production에서 import할 위험이 있음 | Gradle dependency rule + ArchUnit: production modules must not depend on `sample-portfolio` | `locally-verified` |","scope":"sample-portfolio module","source_surface":"SURF-98DB94EA489C82CFC10E","subject":"sample-portfolio"},{"assertion_id":"A-CTV-06","condition":"locally-verified-minimum-boundary; named interface/public API 검증은 아직 약함","line_end":309,"line_start":309,"modality":"observed","object":"최소 module boundary (Spring Modulith 없이)","predicate":"validates","quote":"| Spring Modulith를 도입하지 않아도 최소 module boundary 검증이 가능하다 | Modulith verifier를 쓰지 않으면 public API/named interface 검증이 약할 수 있음 | 1차는 Gradle dependency + ArchUnit으로 검증. named interface/public API 검증은 Spring Modulith 없이 아직 약함 | `locally-verified-minimum-boundary` |","scope":"module boundary verification","source_surface":"SURF-98DB94EA489C82CFC10E","subject":"Gradle dependency + ArchUnit"},{"assertion_id":"A-DEC-00","condition":"unconditional","line_end":283,"line_start":283,"modality":"observed","object":"본 표의 row (Decision ID D1~D8 안정 유지)","predicate":"maps_to","quote":"> 각 결정이 어떤 raw source claim 으로 뒷받침되는지 명시. `Decision ID` 는 본 branch-note 안에서 안정적으로 유지 (D1~D8). module tree 와 package 책임도 본 표의 row 로 매핑.","scope":"decision-evidence map","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"module tree 와 package 책임"},{"assertion_id":"A-DEC-01","condition":"Phase C2 default (company-case-study evidence)","line_end":287,"line_start":287,"modality":"must","object":"Gradle multi-module + Clean Architecture / Hexagonal boundary","predicate":"uses","quote":"| D1 | Phase C2 기본 구조는 Gradle multi-module + Clean Architecture / Hexagonal boundary | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 두 자료 모두 사례이며 공식 표준은 아님. ca-tmpl에 그대로 이식하려면 build.gradle dependency graph와 ArchUnit rule로 별도 검증 필요 |","scope":"skeleton module structure","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"Phase C2 기본 구조"},{"assertion_id":"A-DEC-02","condition":"unconditional (framework-neutral domain model)","line_end":288,"line_start":288,"modality":"must_not","object":"adapter/framework 의존","predicate":"forbids","quote":"| D2 | `domain-core`는 framework-neutral domain model을 담고 adapter/framework에 의존하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/official-docs/arch-clean-architecture-uncle-bob.md` | `company-case-study + engineering-blog` | `shared-contract` value-only type까지 허용할지 여부는 ca-tmpl 자체 결정 |","scope":"domain-core module","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"domain-core"},{"assertion_id":"A-DEC-03","condition":"unconditional","line_end":289,"line_start":289,"modality":"must_not","object":"adapter 구현체와 통신 (domain에만 직접 의존)","predicate":"forbids","quote":"| D3 | `application-core`는 domain에만 직접 의존하고 adapter 구현체와 통신하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring transaction boundary를 application port로 추상화할 때 `spring-tx` 의존을 어느 module에 둘지는 TransactionPort branch와 함께 검증 필요 |","scope":"application-core module","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"application-core"},{"assertion_id":"A-DEC-04","condition":"unconditional","line_end":290,"line_start":290,"modality":"must","object":"inbound(adapter-web)와 outbound(adapter-persistence, adapter-outbound) 물리 분리","predicate":"other","quote":"| D4 | adapter module은 inbound(`adapter-web`)와 outbound(`adapter-persistence`, `adapter-outbound`)로 물리 분리 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4`, `raw/official-docs/hexagonal-cockburn-wikipedia-summary.md#HEX-WIKI-C5` | `company-case-study + official-reference` | adapter를 persistence/outbound로 나누는 세부 module 수는 ca-tmpl 자체 운영 결정 |","scope":"adapter modules","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"adapter module"},{"assertion_id":"A-DEC-05","condition":"unconditional","line_end":291,"line_start":291,"modality":"must","object":"public API / port interface를 통해서만 허용","predicate":"requires","quote":"| D5 | module 간 통신은 public API / port interface를 통해서만 허용 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring Modulith를 바로 도입하지 않으면 public API 강제는 ArchUnit/package-private convention으로 보완해야 함 |","scope":"inter-module communication","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"module 간 통신"},{"assertion_id":"A-DEC-06","condition":"unconditional","line_end":292,"line_start":292,"modality":"must_not","object":"business/domain concept (skeleton-wide operational contract만 허용)","predicate":"forbids","quote":"| D6 | `shared-contract`에는 skeleton-wide operational contract만 두고 business/domain concept는 금지 | `raw/official-docs/feature-first-uncle-bob-screaming-architecture-2011.md#SCREAM-C1` | `engineering-blog` | `shared-contract`가 커지면 de-facto common dumping ground가 될 수 있음. registry owner와 forbidden import rule 필요 |","scope":"shared-contract module","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"shared-contract"},{"assertion_id":"A-DEC-07","condition":"UNSUPPORTED_DECISION — 외부 공식 근거 없음","line_end":293,"line_start":293,"modality":"must_not","object":"production module이 import (fixture module)","predicate":"forbids","quote":"| D7 _(UNSUPPORTED_DECISION)_ | `sample-portfolio`은 fixture module이며 production module이 import하면 실패 | D1~D5에서 파생된 ca-tmpl 자체 결정 — 외부 공식 근거 없음 | `project-decision` | 외부 직접 근거 부족. ArchUnit + Gradle dependency rule로 실증 필요. **UNSUPPORTED_DECISION** — external official-doc/company-tech-blog claim 없음. 외부 근거 보강 시 갱신 예정 |","scope":"sample-portfolio module","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"sample-portfolio"},{"assertion_id":"A-DEC-08","condition":"Phase C2 default","line_end":294,"line_start":294,"modality":"must","object":"multi-module (single-module은 축소형 문서/예제로만 허용)","predicate":"requires","quote":"| D8 | single-module 구조는 축소형 문서/예제로만 허용하고 Phase C2 기본값은 multi-module | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 작은 프로젝트에서는 single-module이 비용이 낮을 수 있음. ca-tmpl은 skeleton template이므로 boundary 학습/검증 비용을 감수한다는 프로젝트 결정 |","scope":"module topology","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"Phase C2 기본값"},{"assertion_id":"A-DEC-09","condition":"소비자 module public ABI(port interface 반환·파라미터 타입)에 타 module type 노출 시","line_end":295,"line_start":295,"modality":"must","object":"기본값 implementation, public ABI 노출 시에만 api","predicate":"requires","quote":"| D9 | module 간 dependency 선언 기본값은 `implementation`이며, 소비자 module의 public ABI(port interface 반환·파라미터 타입)에 타 module type이 노출될 때만 `api` 사용 | `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C2`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C3`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C4` | `official-vendor-doc` | 각 module의 `build.gradle` dependency 선언 시 `api` vs `implementation` 구분 기준이 없어 정책 미정이었던 구멍을 해소. ca-tmpl 8개 module 모두에 적용 | 어느 module이 실제로 `api`를 써야 하는지(예: `application-core`가 `domain-core`를 `api`로 선언해야 하는지)는 port interface 설계 완료 후 검증 필요. `bootJar` 런타임 포함 여부는 별도 확인 |","scope":"gradle dependency 선언","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"module 간 dependency 선언"},{"assertion_id":"A-DEC-10","condition":"unconditional","line_end":296,"line_start":296,"modality":"must","object":"app-bootstrap 모듈 dev.caskeleton.bootstrap root package (default package 사용 금지)","predicate":"maps_to","quote":"| D10 | `@SpringBootApplication` 은 `app-bootstrap` 모듈의 `dev.caskeleton.bootstrap` (root package) 에 배치한다. default package 사용 금지. | `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C1`, `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C2`, `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C3`, `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C4` | `official-vendor-doc` | multi-module 구조에서 `@SpringBootApplication` 이 어느 모듈·패키지에 위치해야 하는지는 이 공식 근거로 직접 뒷받침되지 않음 (단일 모듈 기준 설명). `scanBasePackages` 추가 설정 필요 여부는 integration test로 검증 필요 |","scope":"app-bootstrap bootstrap class","source_surface":"SURF-0FDCA02A3C2677944D45","subject":"@SpringBootApplication"},{"assertion_id":"A-EFD-01","condition":"build 또는 architecture test","line_end":468,"line_start":468,"modality":"must_not","object":"build 또는 architecture test에서 차단","predicate":"forbids","quote":"- 순환 module dependency·bootstrap 역참조·shared-contract의 구현 의존 유입은 build 또는 architecture test에서 차단한다.","scope":"module dependency","source_surface":"SURF-2E606ED3B04B61A6D166","subject":"순환 module dependency·bootstrap 역참조·shared-contract의 구현 의존 유입"},{"assertion_id":"A-EFD-02","condition":"unconditional","line_end":469,"line_start":469,"modality":"observed","object":"본 blueprint","predicate":"consumes","quote":"- onboarding·application port·architecture enforcement 계약이 본 blueprint를 소비한다.","scope":"downstream consumers","source_surface":"SURF-2E606ED3B04B61A6D166","subject":"onboarding·application port·architecture enforcement 계약"},{"assertion_id":"A-IMP-01","condition":"unconditional","line_end":462,"line_start":462,"modality":"must","object":"Gradle module과 package 양쪽에 고정","predicate":"maps_to","quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다.","scope":"module/package responsibility","source_surface":"SURF-65B227AF1D7F8F3C1C99","subject":"domain-core·application-core·adapter-*·shared-contract·app-bootstrap 책임"},{"assertion_id":"A-IMP-02","condition":"unconditional","line_end":463,"line_start":463,"modality":"must","object":"한 방향으로만 선언","predicate":"requires","quote":"- 허용 dependency는 한 방향으로만 선언하고 forbidden fixture가 architecture gate에서 실패해야 한다.","scope":"dependency direction","source_surface":"SURF-65B227AF1D7F8F3C1C99","subject":"허용 dependency"},{"assertion_id":"A-IMP-03","condition":"unconditional","line_end":463,"line_start":463,"modality":"must","object":"architecture gate에서 실패","predicate":"has_failure_behavior","quote":"- 허용 dependency는 한 방향으로만 선언하고 forbidden fixture가 architecture gate에서 실패해야 한다.","scope":"architecture gate","source_surface":"SURF-65B227AF1D7F8F3C1C99","subject":"forbidden fixture"},{"assertion_id":"A-IMP-04","condition":"신규 domain onboarding 시","line_end":464,"line_start":464,"modality":"must","object":"이 문서의 module 책임 참조 (blueprint 복사 금지)","predicate":"requires","quote":"- 신규 domain onboarding은 blueprint를 복사하지 않고 이 문서의 module 책임을 참조한다.","scope":"domain onboarding","source_surface":"SURF-65B227AF1D7F8F3C1C99","subject":"신규 domain onboarding"},{"assertion_id":"A-SCP-01","condition":"포함 범위","line_end":86,"line_start":80,"modality":"observed","object":"Gradle multi-module blueprint / module dependency direction / module 내부 package blueprint / shared-common 허용 범위 / sample module 격리 기준 / architecture rule 연결 기준 / single-module 축소형 예외","predicate":"other","quote":"- Gradle multi-module blueprint.\n- module dependency direction.\n- module 내부 package blueprint.\n- shared/common module 허용 범위.\n- sample module 격리 기준.\n- architecture rule 연결 기준.\n- single-module 축소형은 예외 mapping으로만 허용.","scope":"branch scope","source_surface":"SURF-C80079AE67EBBB64FFB1","subject":"본 branch 포함 범위"},{"assertion_id":"A-SCP-02","condition":"축소형은 예외 mapping only","line_end":86,"line_start":86,"modality":"may","object":"예외 mapping으로만 허용 (Phase C2 기본값 아님)","predicate":"other","quote":"- single-module 축소형은 예외 mapping으로만 허용.","scope":"module topology","source_surface":"SURF-C80079AE67EBBB64FFB1","subject":"single-module 축소형"},{"assertion_id":"A-SCP-03","condition":"제외 범위","line_end":91,"line_start":90,"modality":"must_not","object":"build tool plugin 구현 / code generator 구현","predicate":"forbids","quote":"- build tool plugin 구현.\n- code generator 구현.","scope":"branch scope","source_surface":"SURF-C80079AE67EBBB64FFB1","subject":"본 branch 제외 범위"}],"candidate_manifest_sha256":"540835567ba0ff596acdd57a3004e8d2bcdb586d8ad8bab9aaf9206ff9ab7ec5","candidates":[{"assertion_a":"A-BCP-04","assertion_b":"A-BCP-05","candidate_id":"SEM-D07F4763C7A900F2A34E","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-01","assertion_b":"A-CTV-02","candidate_id":"SEM-786F5A9503CFDFFCC18D","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-01","assertion_b":"A-CTV-03","candidate_id":"SEM-602AFBABF1B4DD8FBD4D","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-01","assertion_b":"A-CTV-05","candidate_id":"SEM-C77E90652CE359061316","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-01","assertion_b":"A-DEC-03","candidate_id":"SEM-20005C5761E993A6BB07","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-01","assertion_b":"A-DEC-09","candidate_id":"SEM-230D10E339DC3FEDDF24","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-01","assertion_b":"A-IMP-01","candidate_id":"SEM-7879AD04B4F097B03B94","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-02","assertion_b":"A-CTV-03","candidate_id":"SEM-C287E8E76A1D49CC5A2B","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-02","assertion_b":"A-CTV-05","candidate_id":"SEM-C4C6286F40632698BFF8","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-02","assertion_b":"A-DEC-02","candidate_id":"SEM-93187F7CFE9C5134AF32","grouping_key":{"condition":"","predicate":"forbids","scope":"domain-core module","subject":"domain-core"},"rule_ids":["C6"]},{"assertion_a":"A-CTV-02","assertion_b":"A-DEC-09","candidate_id":"SEM-CE5FF229DC1D12C02A12","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-02","assertion_b":"A-IMP-01","candidate_id":"SEM-5DE597CF4942FAA46DFB","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-03","assertion_b":"A-CTV-05","candidate_id":"SEM-1C95E889CF91F452C0E4","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-03","assertion_b":"A-DEC-03","candidate_id":"SEM-8A1761586F24F83FD7E6","grouping_key":{"condition":"","predicate":"","scope":"application-core module","subject":"application-core"},"rule_ids":["C6"]},{"assertion_a":"A-CTV-03","assertion_b":"A-DEC-09","candidate_id":"SEM-9C8449AB3D25B66B721C","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-03","assertion_b":"A-IMP-01","candidate_id":"SEM-FF361C37C69B4D5E5F0C","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-04","assertion_b":"A-DEC-02","candidate_id":"SEM-6E387811AF35CB94FA3E","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-04","assertion_b":"A-DEC-06","candidate_id":"SEM-72A2FEE27D0E664F0E0D","grouping_key":{"condition":"","predicate":"forbids","scope":"shared-contract module","subject":"shared-contract"},"rule_ids":["C3","C6"]},{"assertion_a":"A-CTV-04","assertion_b":"A-IMP-01","candidate_id":"SEM-F803CC272F9779D82F7B","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-CTV-05","assertion_b":"A-DEC-07","candidate_id":"SEM-4CA315DC369AC3BAAE24","grouping_key":{"condition":"","predicate":"forbids","scope":"sample-portfolio module","subject":"sample-portfolio"},"rule_ids":["C6"]},{"assertion_a":"A-DEC-01","assertion_b":"A-DEC-02","candidate_id":"SEM-49CCB72CE7CED9A8ED69","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-01","assertion_b":"A-DEC-03","candidate_id":"SEM-C744C2A157947FCB0B29","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-01","assertion_b":"A-DEC-04","candidate_id":"SEM-B218FDC1B558196EFB50","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-01","assertion_b":"A-DEC-05","candidate_id":"SEM-D29637DE8AD7612CF35F","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-01","assertion_b":"A-DEC-08","candidate_id":"SEM-608563015D2A7EA0E391","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-02","assertion_b":"A-DEC-06","candidate_id":"SEM-C3A1F2DAEEDDA482B04F","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-02","assertion_b":"A-DEC-08","candidate_id":"SEM-6900E686C391270B7FBD","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-02","assertion_b":"A-DEC-09","candidate_id":"SEM-9197B25A6769319543E2","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-02","assertion_b":"A-IMP-01","candidate_id":"SEM-AE09244C8EF6E2EB4B2B","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-03","assertion_b":"A-DEC-04","candidate_id":"SEM-F6043697B9E9A8F49EA3","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-03","assertion_b":"A-DEC-05","candidate_id":"SEM-51AD9CB57B30A8E36190","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-03","assertion_b":"A-DEC-08","candidate_id":"SEM-0632C9589841EBD5D924","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-03","assertion_b":"A-DEC-09","candidate_id":"SEM-BFC9FA59E73BE6B30431","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-03","assertion_b":"A-IMP-01","candidate_id":"SEM-E4575EDEBD8A2451E576","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-04","assertion_b":"A-DEC-05","candidate_id":"SEM-302E211D1C3C5039E4BC","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-04","assertion_b":"A-DEC-08","candidate_id":"SEM-A4EDEEE41DA744313D66","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-05","assertion_b":"A-DEC-08","candidate_id":"SEM-F333E4780FD3EDAA4DFC","grouping_key":{"condition":"","predicate":"requires","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-06","assertion_b":"A-IMP-01","candidate_id":"SEM-020CD88F6AF95B4DD1D1","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-09","assertion_b":"A-DEC-10","candidate_id":"SEM-416CB38993ADB3DC6466","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-09","assertion_b":"A-IMP-01","candidate_id":"SEM-34A6442000CDBC91D36B","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A-DEC-10","assertion_b":"A-IMP-01","candidate_id":"SEM-791AA7FC0BC8874183D0","grouping_key":{"condition":"unconditional","predicate":"maps_to","scope":"","subject":""},"rule_ids":["C6"]}],"coverage":{"assertions":33,"candidate_pairs":41,"eligible_surfaces":6,"processed_surfaces":6},"document_sha256":"7c51d963ffc0749c68c2a0128923a22b19d736189029c05a94d0b74fc0d88af4","explicit_blocking":[],"mode":"local","ontology_sha256":"76d41a29233c830e1940ebb3244263e2b9bfb8dd6a01f2a1d1c51ce5a1b10468","output_schema":"semantic-audit-result/v1","schema_version":"semantic-verdict-request/v1","subject":"raw/branch-notes/feature-skeleton-package-blueprint-contract.md"},"audit_request_sha256":"1b38fe2299456a27cf9ed3a9ee34eb9810a4cdf4eb4650a371752ce45b5c3c66","audit_result":{"auditor":{"contract_version":"semantic-coherence/v1","model_id":"claude-opus-4-8","run_id":"ab514cdbad9e4c270"},"mode":"local","request_sha256":"1b38fe2299456a27cf9ed3a9ee34eb9810a4cdf4eb4650a371752ce45b5c3c66","schema_version":"semantic-audit-result/v1","subject":"raw/branch-notes/feature-skeleton-package-blueprint-contract.md","verdicts":[{"candidate_id":"SEM-D07F4763C7A900F2A34E","evidence_a":{"line_end":49,"line_start":49,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1` | Gradle multi-module에서 domain-core·application-core·adapter-*·shared-contract·app-bootstrap·sample-portfolio 책임을 분리한다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"evidence_b":{"line_end":50,"line_start":50,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1` | build tool은 Gradle Groovy DSL이다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"proof_manifest":null,"rationale":"A-BCP-04(module layout 책임 분리)와 A-BCP-05(build tool = Gradle Groovy DSL)는 같은 branch contract packet의 서로 다른 두 상속 프로젝트 결정으로, 각기 다른 계약 속성(module layout vs build tooling)을 다루며 상호 배타적 값을 다투지 않고 공존한다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-786F5A9503CFDFFCC18D","evidence_a":{"line_end":304,"line_start":304,"quote":"| Gradle multi-module이 application/domain과 adapter 의존을 build graph 수준에서 차단한다 | 우아한형제들/카카오뱅크 사례는 구조 사례이며 ca-tmpl build.gradle이 아직 없음 | `./gradlew verifyCleanArchitectureDependencies`. `application-core`가 `adapter-*`에 의존하면 실패 | `locally-verified` |"},"evidence_b":{"line_end":305,"line_start":305,"quote":"| `domain-core`가 framework-neutral POJO로 유지된다 | domain module에 Spring/JPA annotation이 들어오는 순간 Clean Architecture 경계가 약해짐 | ArchUnit: `domain-core`에서 `org.springframework..`, `jakarta.persistence..`, `javax.persistence..` import 금지 | `locally-verified` |"},"proof_manifest":null,"rationale":"A-CTV-01(build graph 수준에서 app/domain→adapter 의존 차단)과 A-CTV-02(domain-core POJO 유지·Spring/JPA annotation import 금지)는 scope(build graph dependency vs domain-core module)가 다른 별개의 호환 제약으로, 함께 아키텍처 경계를 구성한다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-602AFBABF1B4DD8FBD4D","evidence_a":{"line_end":304,"line_start":304,"quote":"| Gradle multi-module이 application/domain과 adapter 의존을 build graph 수준에서 차단한다 | 우아한형제들/카카오뱅크 사례는 구조 사례이며 ca-tmpl build.gradle이 아직 없음 | `./gradlew verifyCleanArchitectureDependencies`. `application-core`가 `adapter-*`에 의존하면 실패 | `locally-verified` |"},"evidence_b":{"line_end":306,"line_start":306,"quote":"| `application-core`가 outbound 구현체가 아닌 port interface만 사용한다 | multi-module이어도 project dependency를 잘못 열면 adapter 구현체 직접 호출이 가능 | ArchUnit + Gradle: `application-core` -> `adapter-*` dependency 금지. 현재 production `application-core`는 anchor 중심이며, reference repository port는 `sample-portfolio/domain/repository`에 격리됨 | `locally-verified` |"},"proof_manifest":null,"rationale":"A-CTV-01(build graph에서 app/domain→adapter 차단)과 A-CTV-03(application-core는 port interface만 사용)은 같은 방향의 의존 제약을 서로 다른 층위(build graph vs application-core)에서 정교화하는 호환 detail이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C77E90652CE359061316","evidence_a":{"line_end":304,"line_start":304,"quote":"| Gradle multi-module이 application/domain과 adapter 의존을 build graph 수준에서 차단한다 | 우아한형제들/카카오뱅크 사례는 구조 사례이며 ca-tmpl build.gradle이 아직 없음 | `./gradlew verifyCleanArchitectureDependencies`. `application-core`가 `adapter-*`에 의존하면 실패 | `locally-verified` |"},"evidence_b":{"line_end":308,"line_start":308,"quote":"| `sample-portfolio`이 production module로 역수입되지 않는다 | sample은 fixture이지만 편의상 production에서 import할 위험이 있음 | Gradle dependency rule + ArchUnit: production modules must not depend on `sample-portfolio` | `locally-verified` |"},"proof_manifest":null,"rationale":"A-CTV-01(build graph 의존 차단)과 A-CTV-05(sample-portfolio production 역수입 금지)는 scope가 다른 병렬 제약으로, 상대의 배타적 책임을 침범하지 않고 공존한다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-20005C5761E993A6BB07","evidence_a":{"line_end":304,"line_start":304,"quote":"| Gradle multi-module이 application/domain과 adapter 의존을 build graph 수준에서 차단한다 | 우아한형제들/카카오뱅크 사례는 구조 사례이며 ca-tmpl build.gradle이 아직 없음 | `./gradlew verifyCleanArchitectureDependencies`. `application-core`가 `adapter-*`에 의존하면 실패 | `locally-verified` |"},"evidence_b":{"line_end":289,"line_start":289,"quote":"| D3 | `application-core`는 domain에만 직접 의존하고 adapter 구현체와 통신하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring transaction boundary를 application port로 추상화할 때 `spring-tx` 의존을 어느 module에 둘지는 TransactionPort branch와 함께 검증 필요 |"},"proof_manifest":null,"rationale":"A-DEC-03(application-core는 domain에만 의존, adapter 구현체와 통신 안 함) 결정에 대해 A-CTV-01이 build graph 수준 차단이라는 검증 detail을 공급한다. 의미 변경 없는 충실한 방향 일치로 drift 아님.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-230D10E339DC3FEDDF24","evidence_a":{"line_end":304,"line_start":304,"quote":"| Gradle multi-module이 application/domain과 adapter 의존을 build graph 수준에서 차단한다 | 우아한형제들/카카오뱅크 사례는 구조 사례이며 ca-tmpl build.gradle이 아직 없음 | `./gradlew verifyCleanArchitectureDependencies`. `application-core`가 `adapter-*`에 의존하면 실패 | `locally-verified` |"},"evidence_b":{"line_end":295,"line_start":295,"quote":"| D9 | module 간 dependency 선언 기본값은 `implementation`이며, 소비자 module의 public ABI(port interface 반환·파라미터 타입)에 타 module type이 노출될 때만 `api` 사용 | `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C2`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C3`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C4` | `official-vendor-doc` | 각 module의 `build.gradle` dependency 선언 시 `api` vs `implementation` 구분 기준이 없어 정책 미정이었던 구멍을 해소. ca-tmpl 8개 module 모두에 적용 | 어느 module이 실제로 `api`를 써야 하는지(예: `application-core`가 `domain-core`를 `api`로 선언해야 하는지)는 port interface 설계 완료 후 검증 필요. `bootJar` 런타임 포함 여부는 별도 확인 |"},"proof_manifest":null,"rationale":"A-CTV-01(build graph 의존 방향 차단)과 A-DEC-09(dependency 선언 기본 implementation, public ABI 노출 시 api)은 서로 직교하는 호환 관심사(의존 방향 금지 vs api/implementation 가시성)이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-7879AD04B4F097B03B94","evidence_a":{"line_end":304,"line_start":304,"quote":"| Gradle multi-module이 application/domain과 adapter 의존을 build graph 수준에서 차단한다 | 우아한형제들/카카오뱅크 사례는 구조 사례이며 ca-tmpl build.gradle이 아직 없음 | `./gradlew verifyCleanArchitectureDependencies`. `application-core`가 `adapter-*`에 의존하면 실패 | `locally-verified` |"},"evidence_b":{"line_end":462,"line_start":462,"quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다."},"proof_manifest":null,"rationale":"A-CTV-01(의존 차단 검증)과 A-IMP-01(module/package 책임 고정)은 같은 blueprint의 상호 보완 facet으로, 배타적 책임 충돌 없이 공존한다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C287E8E76A1D49CC5A2B","evidence_a":{"line_end":305,"line_start":305,"quote":"| `domain-core`가 framework-neutral POJO로 유지된다 | domain module에 Spring/JPA annotation이 들어오는 순간 Clean Architecture 경계가 약해짐 | ArchUnit: `domain-core`에서 `org.springframework..`, `jakarta.persistence..`, `javax.persistence..` import 금지 | `locally-verified` |"},"evidence_b":{"line_end":306,"line_start":306,"quote":"| `application-core`가 outbound 구현체가 아닌 port interface만 사용한다 | multi-module이어도 project dependency를 잘못 열면 adapter 구현체 직접 호출이 가능 | ArchUnit + Gradle: `application-core` -> `adapter-*` dependency 금지. 현재 production `application-core`는 anchor 중심이며, reference repository port는 `sample-portfolio/domain/repository`에 격리됨 | `locally-verified` |"},"proof_manifest":null,"rationale":"A-CTV-02(domain-core POJO)와 A-CTV-03(application-core port-only)은 서로 다른 module에 대한 별개의 호환 검증 제약이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C4C6286F40632698BFF8","evidence_a":{"line_end":305,"line_start":305,"quote":"| `domain-core`가 framework-neutral POJO로 유지된다 | domain module에 Spring/JPA annotation이 들어오는 순간 Clean Architecture 경계가 약해짐 | ArchUnit: `domain-core`에서 `org.springframework..`, `jakarta.persistence..`, `javax.persistence..` import 금지 | `locally-verified` |"},"evidence_b":{"line_end":308,"line_start":308,"quote":"| `sample-portfolio`이 production module로 역수입되지 않는다 | sample은 fixture이지만 편의상 production에서 import할 위험이 있음 | Gradle dependency rule + ArchUnit: production modules must not depend on `sample-portfolio` | `locally-verified` |"},"proof_manifest":null,"rationale":"A-CTV-02(domain-core POJO)와 A-CTV-05(sample-portfolio 역수입 금지)는 서로 다른 scope의 병렬 독립 제약으로 충돌 없이 공존한다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-93187F7CFE9C5134AF32","evidence_a":{"line_end":305,"line_start":305,"quote":"| `domain-core`가 framework-neutral POJO로 유지된다 | domain module에 Spring/JPA annotation이 들어오는 순간 Clean Architecture 경계가 약해짐 | ArchUnit: `domain-core`에서 `org.springframework..`, `jakarta.persistence..`, `javax.persistence..` import 금지 | `locally-verified` |"},"evidence_b":{"line_end":288,"line_start":288,"quote":"| D2 | `domain-core`는 framework-neutral domain model을 담고 adapter/framework에 의존하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/official-docs/arch-clean-architecture-uncle-bob.md` | `company-case-study + engineering-blog` | `shared-contract` value-only type까지 허용할지 여부는 ca-tmpl 자체 결정 |"},"proof_manifest":null,"rationale":"같은 subject/scope(domain-core)에서 A-DEC-02는 framework-neutral·adapter/framework 미의존을 결정하고 A-CTV-02는 ArchUnit annotation-import 금지라는 검증 detail을 공급한다. 의미 변경 없는 충실한 재진술이라 drift 아님.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-CE5FF229DC1D12C02A12","evidence_a":{"line_end":305,"line_start":305,"quote":"| `domain-core`가 framework-neutral POJO로 유지된다 | domain module에 Spring/JPA annotation이 들어오는 순간 Clean Architecture 경계가 약해짐 | ArchUnit: `domain-core`에서 `org.springframework..`, `jakarta.persistence..`, `javax.persistence..` import 금지 | `locally-verified` |"},"evidence_b":{"line_end":295,"line_start":295,"quote":"| D9 | module 간 dependency 선언 기본값은 `implementation`이며, 소비자 module의 public ABI(port interface 반환·파라미터 타입)에 타 module type이 노출될 때만 `api` 사용 | `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C2`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C3`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C4` | `official-vendor-doc` | 각 module의 `build.gradle` dependency 선언 시 `api` vs `implementation` 구분 기준이 없어 정책 미정이었던 구멍을 해소. ca-tmpl 8개 module 모두에 적용 | 어느 module이 실제로 `api`를 써야 하는지(예: `application-core`가 `domain-core`를 `api`로 선언해야 하는지)는 port interface 설계 완료 후 검증 필요. `bootJar` 런타임 포함 여부는 별도 확인 |"},"proof_manifest":null,"rationale":"A-CTV-02(domain-core POJO)와 A-DEC-09(dependency 기본 implementation/api)은 직교하는 호환 관심사이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-5DE597CF4942FAA46DFB","evidence_a":{"line_end":305,"line_start":305,"quote":"| `domain-core`가 framework-neutral POJO로 유지된다 | domain module에 Spring/JPA annotation이 들어오는 순간 Clean Architecture 경계가 약해짐 | ArchUnit: `domain-core`에서 `org.springframework..`, `jakarta.persistence..`, `javax.persistence..` import 금지 | `locally-verified` |"},"evidence_b":{"line_end":462,"line_start":462,"quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다."},"proof_manifest":null,"rationale":"A-CTV-02(domain-core POJO 검증)와 A-IMP-01(module/package 책임 고정)은 상호 보완적이고 충돌 없다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-1C95E889CF91F452C0E4","evidence_a":{"line_end":306,"line_start":306,"quote":"| `application-core`가 outbound 구현체가 아닌 port interface만 사용한다 | multi-module이어도 project dependency를 잘못 열면 adapter 구현체 직접 호출이 가능 | ArchUnit + Gradle: `application-core` -> `adapter-*` dependency 금지. 현재 production `application-core`는 anchor 중심이며, reference repository port는 `sample-portfolio/domain/repository`에 격리됨 | `locally-verified` |"},"evidence_b":{"line_end":308,"line_start":308,"quote":"| `sample-portfolio`이 production module로 역수입되지 않는다 | sample은 fixture이지만 편의상 production에서 import할 위험이 있음 | Gradle dependency rule + ArchUnit: production modules must not depend on `sample-portfolio` | `locally-verified` |"},"proof_manifest":null,"rationale":"A-CTV-03(application-core port-only)와 A-CTV-05(sample-portfolio 역수입 금지)는 서로 다른 scope의 호환 제약이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-8A1761586F24F83FD7E6","evidence_a":{"line_end":306,"line_start":306,"quote":"| `application-core`가 outbound 구현체가 아닌 port interface만 사용한다 | multi-module이어도 project dependency를 잘못 열면 adapter 구현체 직접 호출이 가능 | ArchUnit + Gradle: `application-core` -> `adapter-*` dependency 금지. 현재 production `application-core`는 anchor 중심이며, reference repository port는 `sample-portfolio/domain/repository`에 격리됨 | `locally-verified` |"},"evidence_b":{"line_end":289,"line_start":289,"quote":"| D3 | `application-core`는 domain에만 직접 의존하고 adapter 구현체와 통신하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring transaction boundary를 application port로 추상화할 때 `spring-tx` 의존을 어느 module에 둘지는 TransactionPort branch와 함께 검증 필요 |"},"proof_manifest":null,"rationale":"같은 subject application-core에서 A-DEC-03은 domain-only 의존을 결정하고 A-CTV-03은 port interface만 사용한다는 동일 취지를 검증 detail(ArchUnit+Gradle)로 정교화한다. 의미 변경 없어 drift 아님.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-9C8449AB3D25B66B721C","evidence_a":{"line_end":306,"line_start":306,"quote":"| `application-core`가 outbound 구현체가 아닌 port interface만 사용한다 | multi-module이어도 project dependency를 잘못 열면 adapter 구현체 직접 호출이 가능 | ArchUnit + Gradle: `application-core` -> `adapter-*` dependency 금지. 현재 production `application-core`는 anchor 중심이며, reference repository port는 `sample-portfolio/domain/repository`에 격리됨 | `locally-verified` |"},"evidence_b":{"line_end":295,"line_start":295,"quote":"| D9 | module 간 dependency 선언 기본값은 `implementation`이며, 소비자 module의 public ABI(port interface 반환·파라미터 타입)에 타 module type이 노출될 때만 `api` 사용 | `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C2`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C3`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C4` | `official-vendor-doc` | 각 module의 `build.gradle` dependency 선언 시 `api` vs `implementation` 구분 기준이 없어 정책 미정이었던 구멍을 해소. ca-tmpl 8개 module 모두에 적용 | 어느 module이 실제로 `api`를 써야 하는지(예: `application-core`가 `domain-core`를 `api`로 선언해야 하는지)는 port interface 설계 완료 후 검증 필요. `bootJar` 런타임 포함 여부는 별도 확인 |"},"proof_manifest":null,"rationale":"A-CTV-03(port-only 사용)과 A-DEC-09(dependency api/implementation 기본)은 직교하는 호환 관심사이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-FF361C37C69B4D5E5F0C","evidence_a":{"line_end":306,"line_start":306,"quote":"| `application-core`가 outbound 구현체가 아닌 port interface만 사용한다 | multi-module이어도 project dependency를 잘못 열면 adapter 구현체 직접 호출이 가능 | ArchUnit + Gradle: `application-core` -> `adapter-*` dependency 금지. 현재 production `application-core`는 anchor 중심이며, reference repository port는 `sample-portfolio/domain/repository`에 격리됨 | `locally-verified` |"},"evidence_b":{"line_end":462,"line_start":462,"quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다."},"proof_manifest":null,"rationale":"A-CTV-03(port-only 검증)과 A-IMP-01(책임 고정)은 상호 보완적이고 충돌 없다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-6E387811AF35CB94FA3E","evidence_a":{"line_end":307,"line_start":307,"quote":"| `shared-contract`가 business common으로 오염되지 않는다 | shared module은 커지기 쉬워 domain concept가 흘러들 위험이 있음 | ArchUnit package rule: `shared`에는 response/error/header/logging/tracing/metrics/registry/annotation만 허용. 현재는 package anchor만 존재 | `locally-verified-empty-anchor` |"},"evidence_b":{"line_end":288,"line_start":288,"quote":"| D2 | `domain-core`는 framework-neutral domain model을 담고 adapter/framework에 의존하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/official-docs/arch-clean-architecture-uncle-bob.md` | `company-case-study + engineering-blog` | `shared-contract` value-only type까지 허용할지 여부는 ca-tmpl 자체 결정 |"},"proof_manifest":null,"rationale":"A-CTV-04(shared-contract business common 오염 금지)와 A-DEC-02(domain-core framework-neutral)는 서로 다른 module에 대한 호환 제약이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-72A2FEE27D0E664F0E0D","evidence_a":{"line_end":307,"line_start":307,"quote":"| `shared-contract`가 business common으로 오염되지 않는다 | shared module은 커지기 쉬워 domain concept가 흘러들 위험이 있음 | ArchUnit package rule: `shared`에는 response/error/header/logging/tracing/metrics/registry/annotation만 허용. 현재는 package anchor만 존재 | `locally-verified-empty-anchor` |"},"evidence_b":{"line_end":292,"line_start":292,"quote":"| D6 | `shared-contract`에는 skeleton-wide operational contract만 두고 business/domain concept는 금지 | `raw/official-docs/feature-first-uncle-bob-screaming-architecture-2011.md#SCREAM-C1` | `engineering-blog` | `shared-contract`가 커지면 de-facto common dumping ground가 될 수 있음. registry owner와 forbidden import rule 필요 |"},"proof_manifest":null,"rationale":"같은 subject shared-contract에서 A-DEC-06은 business/domain concept 금지를 결정하고 A-CTV-04는 허용 목록(response/error/header/logging/tracing/metrics/registry/annotation)이라는 검증 detail을 공급한다. 동일 취지의 재진술로 drift 아님.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-F803CC272F9779D82F7B","evidence_a":{"line_end":307,"line_start":307,"quote":"| `shared-contract`가 business common으로 오염되지 않는다 | shared module은 커지기 쉬워 domain concept가 흘러들 위험이 있음 | ArchUnit package rule: `shared`에는 response/error/header/logging/tracing/metrics/registry/annotation만 허용. 현재는 package anchor만 존재 | `locally-verified-empty-anchor` |"},"evidence_b":{"line_end":462,"line_start":462,"quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다."},"proof_manifest":null,"rationale":"A-CTV-04(shared-contract 오염 금지)와 A-IMP-01(책임 고정)은 상호 보완적이고 충돌 없다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-4CA315DC369AC3BAAE24","evidence_a":{"line_end":308,"line_start":308,"quote":"| `sample-portfolio`이 production module로 역수입되지 않는다 | sample은 fixture이지만 편의상 production에서 import할 위험이 있음 | Gradle dependency rule + ArchUnit: production modules must not depend on `sample-portfolio` | `locally-verified` |"},"evidence_b":{"line_end":293,"line_start":293,"quote":"| D7 _(UNSUPPORTED_DECISION)_ | `sample-portfolio`은 fixture module이며 production module이 import하면 실패 | D1~D5에서 파생된 ca-tmpl 자체 결정 — 외부 공식 근거 없음 | `project-decision` | 외부 직접 근거 부족. ArchUnit + Gradle dependency rule로 실증 필요. **UNSUPPORTED_DECISION** — external official-doc/company-tech-blog claim 없음. 외부 근거 보강 시 갱신 예정 |"},"proof_manifest":null,"rationale":"같은 subject sample-portfolio에서 A-DEC-07(UNSUPPORTED_DECISION)은 production import 실패를 결정하며 ArchUnit+Gradle 실증을 필요로 명시하고, A-CTV-05가 바로 그 locally-verified 검증을 공급한다. 동일 의미로 drift 아님.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-49CCB72CE7CED9A8ED69","evidence_a":{"line_end":287,"line_start":287,"quote":"| D1 | Phase C2 기본 구조는 Gradle multi-module + Clean Architecture / Hexagonal boundary | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 두 자료 모두 사례이며 공식 표준은 아님. ca-tmpl에 그대로 이식하려면 build.gradle dependency graph와 ArchUnit rule로 별도 검증 필요 |"},"evidence_b":{"line_end":288,"line_start":288,"quote":"| D2 | `domain-core`는 framework-neutral domain model을 담고 adapter/framework에 의존하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/official-docs/arch-clean-architecture-uncle-bob.md` | `company-case-study + engineering-blog` | `shared-contract` value-only type까지 허용할지 여부는 ca-tmpl 자체 결정 |"},"proof_manifest":null,"rationale":"A-DEC-01(Phase C2 기본 = multi-module + CA/Hexagonal)의 전체 구조 안에서 A-DEC-02(domain-core framework-neutral)가 세부 module 제약을 공급한다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C744C2A157947FCB0B29","evidence_a":{"line_end":287,"line_start":287,"quote":"| D1 | Phase C2 기본 구조는 Gradle multi-module + Clean Architecture / Hexagonal boundary | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 두 자료 모두 사례이며 공식 표준은 아님. ca-tmpl에 그대로 이식하려면 build.gradle dependency graph와 ArchUnit rule로 별도 검증 필요 |"},"evidence_b":{"line_end":289,"line_start":289,"quote":"| D3 | `application-core`는 domain에만 직접 의존하고 adapter 구현체와 통신하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring transaction boundary를 application port로 추상화할 때 `spring-tx` 의존을 어느 module에 둘지는 TransactionPort branch와 함께 검증 필요 |"},"proof_manifest":null,"rationale":"A-DEC-01의 전체 구조 안에서 A-DEC-03(application-core는 domain에만 의존)이 세부 의존 규칙을 공급한다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-B218FDC1B558196EFB50","evidence_a":{"line_end":287,"line_start":287,"quote":"| D1 | Phase C2 기본 구조는 Gradle multi-module + Clean Architecture / Hexagonal boundary | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 두 자료 모두 사례이며 공식 표준은 아님. ca-tmpl에 그대로 이식하려면 build.gradle dependency graph와 ArchUnit rule로 별도 검증 필요 |"},"evidence_b":{"line_end":290,"line_start":290,"quote":"| D4 | adapter module은 inbound(`adapter-web`)와 outbound(`adapter-persistence`, `adapter-outbound`)로 물리 분리 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4`, `raw/official-docs/hexagonal-cockburn-wikipedia-summary.md#HEX-WIKI-C5` | `company-case-study + official-reference` | adapter를 persistence/outbound로 나누는 세부 module 수는 ca-tmpl 자체 운영 결정 |"},"proof_manifest":null,"rationale":"A-DEC-01의 전체 구조 안에서 A-DEC-04(adapter inbound/outbound 물리 분리)가 세부 module 배치를 공급한다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-D29637DE8AD7612CF35F","evidence_a":{"line_end":287,"line_start":287,"quote":"| D1 | Phase C2 기본 구조는 Gradle multi-module + Clean Architecture / Hexagonal boundary | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 두 자료 모두 사례이며 공식 표준은 아님. ca-tmpl에 그대로 이식하려면 build.gradle dependency graph와 ArchUnit rule로 별도 검증 필요 |"},"evidence_b":{"line_end":291,"line_start":291,"quote":"| D5 | module 간 통신은 public API / port interface를 통해서만 허용 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring Modulith를 바로 도입하지 않으면 public API 강제는 ArchUnit/package-private convention으로 보완해야 함 |"},"proof_manifest":null,"rationale":"A-DEC-01의 전체 구조 안에서 A-DEC-05(module 간 통신은 public API/port만)가 통신 규칙 detail을 공급한다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-608563015D2A7EA0E391","evidence_a":{"line_end":287,"line_start":287,"quote":"| D1 | Phase C2 기본 구조는 Gradle multi-module + Clean Architecture / Hexagonal boundary | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 두 자료 모두 사례이며 공식 표준은 아님. ca-tmpl에 그대로 이식하려면 build.gradle dependency graph와 ArchUnit rule로 별도 검증 필요 |"},"evidence_b":{"line_end":294,"line_start":294,"quote":"| D8 | single-module 구조는 축소형 문서/예제로만 허용하고 Phase C2 기본값은 multi-module | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 작은 프로젝트에서는 single-module이 비용이 낮을 수 있음. ca-tmpl은 skeleton template이므로 boundary 학습/검증 비용을 감수한다는 프로젝트 결정 |"},"proof_manifest":null,"rationale":"A-DEC-01과 A-DEC-08 모두 Phase C2 기본값을 multi-module로 일치시키며, A-DEC-08은 single-module 축소형 예외라는 추가 detail을 공급한다. 모순 없이 보완.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C3A1F2DAEEDDA482B04F","evidence_a":{"line_end":288,"line_start":288,"quote":"| D2 | `domain-core`는 framework-neutral domain model을 담고 adapter/framework에 의존하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/official-docs/arch-clean-architecture-uncle-bob.md` | `company-case-study + engineering-blog` | `shared-contract` value-only type까지 허용할지 여부는 ca-tmpl 자체 결정 |"},"evidence_b":{"line_end":292,"line_start":292,"quote":"| D6 | `shared-contract`에는 skeleton-wide operational contract만 두고 business/domain concept는 금지 | `raw/official-docs/feature-first-uncle-bob-screaming-architecture-2011.md#SCREAM-C1` | `engineering-blog` | `shared-contract`가 커지면 de-facto common dumping ground가 될 수 있음. registry owner와 forbidden import rule 필요 |"},"proof_manifest":null,"rationale":"A-DEC-02(domain-core framework-neutral)와 A-DEC-06(shared-contract 내용 제한)은 서로 다른 module에 대한 호환 금지 제약이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-6900E686C391270B7FBD","evidence_a":{"line_end":288,"line_start":288,"quote":"| D2 | `domain-core`는 framework-neutral domain model을 담고 adapter/framework에 의존하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/official-docs/arch-clean-architecture-uncle-bob.md` | `company-case-study + engineering-blog` | `shared-contract` value-only type까지 허용할지 여부는 ca-tmpl 자체 결정 |"},"evidence_b":{"line_end":294,"line_start":294,"quote":"| D8 | single-module 구조는 축소형 문서/예제로만 허용하고 Phase C2 기본값은 multi-module | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 작은 프로젝트에서는 single-module이 비용이 낮을 수 있음. ca-tmpl은 skeleton template이므로 boundary 학습/검증 비용을 감수한다는 프로젝트 결정 |"},"proof_manifest":null,"rationale":"A-DEC-02(domain-core 규칙)와 A-DEC-08(module topology)은 직교하는 호환 결정이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-9197B25A6769319543E2","evidence_a":{"line_end":288,"line_start":288,"quote":"| D2 | `domain-core`는 framework-neutral domain model을 담고 adapter/framework에 의존하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/official-docs/arch-clean-architecture-uncle-bob.md` | `company-case-study + engineering-blog` | `shared-contract` value-only type까지 허용할지 여부는 ca-tmpl 자체 결정 |"},"evidence_b":{"line_end":295,"line_start":295,"quote":"| D9 | module 간 dependency 선언 기본값은 `implementation`이며, 소비자 module의 public ABI(port interface 반환·파라미터 타입)에 타 module type이 노출될 때만 `api` 사용 | `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C2`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C3`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C4` | `official-vendor-doc` | 각 module의 `build.gradle` dependency 선언 시 `api` vs `implementation` 구분 기준이 없어 정책 미정이었던 구멍을 해소. ca-tmpl 8개 module 모두에 적용 | 어느 module이 실제로 `api`를 써야 하는지(예: `application-core`가 `domain-core`를 `api`로 선언해야 하는지)는 port interface 설계 완료 후 검증 필요. `bootJar` 런타임 포함 여부는 별도 확인 |"},"proof_manifest":null,"rationale":"A-DEC-02(domain-core POJO)와 A-DEC-09(dependency api/implementation 기본)은 직교하는 호환 관심사이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-AE09244C8EF6E2EB4B2B","evidence_a":{"line_end":288,"line_start":288,"quote":"| D2 | `domain-core`는 framework-neutral domain model을 담고 adapter/framework에 의존하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/official-docs/arch-clean-architecture-uncle-bob.md` | `company-case-study + engineering-blog` | `shared-contract` value-only type까지 허용할지 여부는 ca-tmpl 자체 결정 |"},"evidence_b":{"line_end":462,"line_start":462,"quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다."},"proof_manifest":null,"rationale":"A-DEC-02(domain-core 규칙)와 A-IMP-01(책임 고정)은 상호 보완적이고 충돌 없다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-F6043697B9E9A8F49EA3","evidence_a":{"line_end":289,"line_start":289,"quote":"| D3 | `application-core`는 domain에만 직접 의존하고 adapter 구현체와 통신하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring transaction boundary를 application port로 추상화할 때 `spring-tx` 의존을 어느 module에 둘지는 TransactionPort branch와 함께 검증 필요 |"},"evidence_b":{"line_end":290,"line_start":290,"quote":"| D4 | adapter module은 inbound(`adapter-web`)와 outbound(`adapter-persistence`, `adapter-outbound`)로 물리 분리 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4`, `raw/official-docs/hexagonal-cockburn-wikipedia-summary.md#HEX-WIKI-C5` | `company-case-study + official-reference` | adapter를 persistence/outbound로 나누는 세부 module 수는 ca-tmpl 자체 운영 결정 |"},"proof_manifest":null,"rationale":"A-DEC-03(application-core 의존)과 A-DEC-04(adapter 물리 분리)는 서로 다른 module에 대한 호환 결정이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-51AD9CB57B30A8E36190","evidence_a":{"line_end":289,"line_start":289,"quote":"| D3 | `application-core`는 domain에만 직접 의존하고 adapter 구현체와 통신하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring transaction boundary를 application port로 추상화할 때 `spring-tx` 의존을 어느 module에 둘지는 TransactionPort branch와 함께 검증 필요 |"},"evidence_b":{"line_end":291,"line_start":291,"quote":"| D5 | module 간 통신은 public API / port interface를 통해서만 허용 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring Modulith를 바로 도입하지 않으면 public API 강제는 ArchUnit/package-private convention으로 보완해야 함 |"},"proof_manifest":null,"rationale":"A-DEC-03(application-core는 domain에만 의존, adapter 구현체 미통신)에 대해 A-DEC-05(통신은 public API/port만)가 그 메커니즘을 공급한다. 상호 배타적이지 않은 보완.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-0632C9589841EBD5D924","evidence_a":{"line_end":289,"line_start":289,"quote":"| D3 | `application-core`는 domain에만 직접 의존하고 adapter 구현체와 통신하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring transaction boundary를 application port로 추상화할 때 `spring-tx` 의존을 어느 module에 둘지는 TransactionPort branch와 함께 검증 필요 |"},"evidence_b":{"line_end":294,"line_start":294,"quote":"| D8 | single-module 구조는 축소형 문서/예제로만 허용하고 Phase C2 기본값은 multi-module | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 작은 프로젝트에서는 single-module이 비용이 낮을 수 있음. ca-tmpl은 skeleton template이므로 boundary 학습/검증 비용을 감수한다는 프로젝트 결정 |"},"proof_manifest":null,"rationale":"A-DEC-03(application-core 규칙)과 A-DEC-08(module topology)은 직교하는 호환 결정이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-BFC9FA59E73BE6B30431","evidence_a":{"line_end":289,"line_start":289,"quote":"| D3 | `application-core`는 domain에만 직접 의존하고 adapter 구현체와 통신하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring transaction boundary를 application port로 추상화할 때 `spring-tx` 의존을 어느 module에 둘지는 TransactionPort branch와 함께 검증 필요 |"},"evidence_b":{"line_end":295,"line_start":295,"quote":"| D9 | module 간 dependency 선언 기본값은 `implementation`이며, 소비자 module의 public ABI(port interface 반환·파라미터 타입)에 타 module type이 노출될 때만 `api` 사용 | `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C2`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C3`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C4` | `official-vendor-doc` | 각 module의 `build.gradle` dependency 선언 시 `api` vs `implementation` 구분 기준이 없어 정책 미정이었던 구멍을 해소. ca-tmpl 8개 module 모두에 적용 | 어느 module이 실제로 `api`를 써야 하는지(예: `application-core`가 `domain-core`를 `api`로 선언해야 하는지)는 port interface 설계 완료 후 검증 필요. `bootJar` 런타임 포함 여부는 별도 확인 |"},"proof_manifest":null,"rationale":"A-DEC-03(application-core 규칙)과 A-DEC-09(dependency api/implementation)은 직교하는 호환 관심사이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-E4575EDEBD8A2451E576","evidence_a":{"line_end":289,"line_start":289,"quote":"| D3 | `application-core`는 domain에만 직접 의존하고 adapter 구현체와 통신하지 않음 | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring transaction boundary를 application port로 추상화할 때 `spring-tx` 의존을 어느 module에 둘지는 TransactionPort branch와 함께 검증 필요 |"},"evidence_b":{"line_end":462,"line_start":462,"quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다."},"proof_manifest":null,"rationale":"A-DEC-03(application-core 규칙)과 A-IMP-01(책임 고정)은 상호 보완적이고 충돌 없다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-302E211D1C3C5039E4BC","evidence_a":{"line_end":290,"line_start":290,"quote":"| D4 | adapter module은 inbound(`adapter-web`)와 outbound(`adapter-persistence`, `adapter-outbound`)로 물리 분리 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4`, `raw/official-docs/hexagonal-cockburn-wikipedia-summary.md#HEX-WIKI-C5` | `company-case-study + official-reference` | adapter를 persistence/outbound로 나누는 세부 module 수는 ca-tmpl 자체 운영 결정 |"},"evidence_b":{"line_end":291,"line_start":291,"quote":"| D5 | module 간 통신은 public API / port interface를 통해서만 허용 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring Modulith를 바로 도입하지 않으면 public API 강제는 ArchUnit/package-private convention으로 보완해야 함 |"},"proof_manifest":null,"rationale":"A-DEC-04(adapter inbound/outbound 분리)와 A-DEC-05(통신은 public API/port만)는 호환되는 서로 다른 facet의 결정이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-A4EDEEE41DA744313D66","evidence_a":{"line_end":290,"line_start":290,"quote":"| D4 | adapter module은 inbound(`adapter-web`)와 outbound(`adapter-persistence`, `adapter-outbound`)로 물리 분리 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4`, `raw/official-docs/hexagonal-cockburn-wikipedia-summary.md#HEX-WIKI-C5` | `company-case-study + official-reference` | adapter를 persistence/outbound로 나누는 세부 module 수는 ca-tmpl 자체 운영 결정 |"},"evidence_b":{"line_end":294,"line_start":294,"quote":"| D8 | single-module 구조는 축소형 문서/예제로만 허용하고 Phase C2 기본값은 multi-module | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 작은 프로젝트에서는 single-module이 비용이 낮을 수 있음. ca-tmpl은 skeleton template이므로 boundary 학습/검증 비용을 감수한다는 프로젝트 결정 |"},"proof_manifest":null,"rationale":"A-DEC-04(adapter 분리)와 A-DEC-08(module topology)은 직교하는 호환 결정이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-F333E4780FD3EDAA4DFC","evidence_a":{"line_end":291,"line_start":291,"quote":"| D5 | module 간 통신은 public API / port interface를 통해서만 허용 | `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C2`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | Spring Modulith를 바로 도입하지 않으면 public API 강제는 ArchUnit/package-private convention으로 보완해야 함 |"},"evidence_b":{"line_end":294,"line_start":294,"quote":"| D8 | single-module 구조는 축소형 문서/예제로만 허용하고 Phase C2 기본값은 multi-module | `raw/company-tech-blogs/woowahan-hexagonal-multimodule.md#WW-HEX-C1`, `raw/company-tech-blogs/modulith-kakaobank-techblog-2025.md#KAKAOBANK-MOD-C4` | `company-case-study` | 작은 프로젝트에서는 single-module이 비용이 낮을 수 있음. ca-tmpl은 skeleton template이므로 boundary 학습/검증 비용을 감수한다는 프로젝트 결정 |"},"proof_manifest":null,"rationale":"A-DEC-05(통신 규칙)과 A-DEC-08(module topology)은 직교하는 호환 결정이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-020CD88F6AF95B4DD1D1","evidence_a":{"line_end":292,"line_start":292,"quote":"| D6 | `shared-contract`에는 skeleton-wide operational contract만 두고 business/domain concept는 금지 | `raw/official-docs/feature-first-uncle-bob-screaming-architecture-2011.md#SCREAM-C1` | `engineering-blog` | `shared-contract`가 커지면 de-facto common dumping ground가 될 수 있음. registry owner와 forbidden import rule 필요 |"},"evidence_b":{"line_end":462,"line_start":462,"quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다."},"proof_manifest":null,"rationale":"A-DEC-06(shared-contract 내용 제한)과 A-IMP-01(책임 고정)은 상호 보완적이고 충돌 없다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-416CB38993ADB3DC6466","evidence_a":{"line_end":295,"line_start":295,"quote":"| D9 | module 간 dependency 선언 기본값은 `implementation`이며, 소비자 module의 public ABI(port interface 반환·파라미터 타입)에 타 module type이 노출될 때만 `api` 사용 | `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C2`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C3`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C4` | `official-vendor-doc` | 각 module의 `build.gradle` dependency 선언 시 `api` vs `implementation` 구분 기준이 없어 정책 미정이었던 구멍을 해소. ca-tmpl 8개 module 모두에 적용 | 어느 module이 실제로 `api`를 써야 하는지(예: `application-core`가 `domain-core`를 `api`로 선언해야 하는지)는 port interface 설계 완료 후 검증 필요. `bootJar` 런타임 포함 여부는 별도 확인 |"},"evidence_b":{"line_end":296,"line_start":296,"quote":"| D10 | `@SpringBootApplication` 은 `app-bootstrap` 모듈의 `dev.caskeleton.bootstrap` (root package) 에 배치한다. default package 사용 금지. | `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C1`, `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C2`, `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C3`, `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C4` | `official-vendor-doc` | multi-module 구조에서 `@SpringBootApplication` 이 어느 모듈·패키지에 위치해야 하는지는 이 공식 근거로 직접 뒷받침되지 않음 (단일 모듈 기준 설명). `scanBasePackages` 추가 설정 필요 여부는 integration test로 검증 필요 |"},"proof_manifest":null,"rationale":"A-DEC-09(dependency api/implementation 기본)과 A-DEC-10(@SpringBootApplication의 app-bootstrap root package 배치)은 직교하는 호환 결정이다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-34A6442000CDBC91D36B","evidence_a":{"line_end":295,"line_start":295,"quote":"| D9 | module 간 dependency 선언 기본값은 `implementation`이며, 소비자 module의 public ABI(port interface 반환·파라미터 타입)에 타 module type이 노출될 때만 `api` 사용 | `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C2`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C3`, `raw/official-docs/gradle-java-library-api-vs-implementation.md#GRADLE-JAVALIB-C4` | `official-vendor-doc` | 각 module의 `build.gradle` dependency 선언 시 `api` vs `implementation` 구분 기준이 없어 정책 미정이었던 구멍을 해소. ca-tmpl 8개 module 모두에 적용 | 어느 module이 실제로 `api`를 써야 하는지(예: `application-core`가 `domain-core`를 `api`로 선언해야 하는지)는 port interface 설계 완료 후 검증 필요. `bootJar` 런타임 포함 여부는 별도 확인 |"},"evidence_b":{"line_end":462,"line_start":462,"quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다."},"proof_manifest":null,"rationale":"A-DEC-09(dependency 기본 선언)과 A-IMP-01(책임 고정)은 상호 보완적이고 충돌 없다.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-791AA7FC0BC8874183D0","evidence_a":{"line_end":296,"line_start":296,"quote":"| D10 | `@SpringBootApplication` 은 `app-bootstrap` 모듈의 `dev.caskeleton.bootstrap` (root package) 에 배치한다. default package 사용 금지. | `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C1`, `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C2`, `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C3`, `raw/official-docs/spring-boot-structuring-your-code.md#SB-STRUCT-C4` | `official-vendor-doc` | multi-module 구조에서 `@SpringBootApplication` 이 어느 모듈·패키지에 위치해야 하는지는 이 공식 근거로 직접 뒷받침되지 않음 (단일 모듈 기준 설명). `scanBasePackages` 추가 설정 필요 여부는 integration test로 검증 필요 |"},"evidence_b":{"line_end":462,"line_start":462,"quote":"- `domain-core`·`application-core`·`adapter-*`·`shared-contract`·`app-bootstrap`의 책임을 Gradle module과 package 양쪽에 고정한다."},"proof_manifest":null,"rationale":"A-IMP-01은 app-bootstrap을 포함한 책임을 module/package 양쪽에 고정하고, A-DEC-10은 그 app-bootstrap의 구체 bootstrap package(dev.caskeleton.bootstrap)를 공급한다. 상대의 배타적 책임을 침범하지 않는 정교화.","verdict":"COMPLEMENTARY"}]},"auditor":{"contract_version":"semantic-coherence/v1","model_id":"claude-opus-4-8","run_id":"ab514cdbad9e4c270"},"auditor_contract_sha256":"1cbc67c27e5183a272687f635e3682a26d56785a1cf144da562eb7edd8f6cbce","coverage":{"candidate_pairs":41,"dropped_pairs":0,"eligible_surfaces":6,"processed_pairs":41,"processed_surfaces":6},"document_id":"3064402e6ff5407708ff81764f7ab0f9bf17925185157890125a68b285504e8b","document_sha256":"7c51d963ffc0749c68c2a0128923a22b19d736189029c05a94d0b74fc0d88af4","findings":{"blocking":0,"readiness_blocking":0,"verified":0},"mode":"local","ontology_sha256":"5d601b96f0ca4d75eea89e9086c38e3acf2c4f0c7833846ef58c6a5719603126","policy_sha256":"0465598e9c1c4f2c3400ba51bf4719aa4890d60d56dc83304fb2224e660562b7","proof_manifest_sha256":"37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570","schema_version":"semantic-certificate/v1","semantic_audit_sha256":"b26f52c269d8bac11188c7ca7fd9c0b6c631f238c8e49942c90f41a30dcdcc41","subject":"raw/branch-notes/feature-skeleton-package-blueprint-contract.md","typed_contract_graph_sha256":"481fc3335a494c454ab13ad1d6a6ddccdec99aa8e083f6720ff8886bfa19cc89","verdict":"PASS"}
|