2 lines
79 KiB
JSON
2 lines
79 KiB
JSON
{"audit_request":{"assertions":[{"assertion_id":"SA-01","condition":"완료 조건 (Work Item completion)","line_end":44,"line_start":44,"modality":"must","object":"JSON·date·decimal serialization contract test 통과","predicate":"requires","quote":"- **완료 조건**: JSON·date·decimal serialization contract test가 통과한다","scope":"branch completion","source_surface":"SURF-2DB2FA400155F82D32C3","subject":"branch feature-schema-serialization-contract"},{"assertion_id":"SA-02","condition":"inherited project decision (생성 시 프로젝트 개정 1)","line_end":51,"line_start":51,"modality":"observed","object":"Spring Boot transitive Jackson 2.18.x","predicate":"uses","quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-JSON-001@1` | JSON stack은 Spring Boot transitive Jackson 2.18.x다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |","scope":"project-inherited stack","source_surface":"SURF-2DB2FA400155F82D32C3","subject":"JSON stack"},{"assertion_id":"SA-03","condition":"unconditional","line_end":56,"line_start":56,"modality":"must","object":"branch-local 결정 (이 packet 에서 복제 금지)","predicate":"owns","quote":"> 기존 branch-local 결정은 아래 `## Decision Evidence Map / 결정-근거 매핑`의 D-row가 소유하며 이 packet에서 복제하지 않는다.","scope":"branch-local decisions","source_surface":"SURF-2DB2FA400155F82D32C3","subject":"Decision Evidence Map D-row"},{"assertion_id":"SA-04","condition":"unconditional","line_end":43,"line_start":43,"modality":"observed","object":"contract_packet: 1","predicate":"has_schema","quote":"- **패킷 스키마**: `contract_packet: 1`","scope":"packet schema","source_surface":"SURF-2DB2FA400155F82D32C3","subject":"branch contract packet"},{"assertion_id":"SA-05","condition":"unconditional","line_end":251,"line_start":251,"modality":"observed","object":"정책 근거지만 ca-tmpl 의 ObjectMapper 빈 설정 / OpenAPI drift / 도구 선택의 실제 동작을 보장하지 않음","predicate":"other","quote":"> 외부 표준 (Jackson / BigDecimal / Avro / Protobuf) 는 정책 근거지만 ca-tmpl 의 ObjectMapper 빈 설정 / OpenAPI drift / 도구 선택의 실제 동작을 보장하지 않음.","scope":"verification caveat","source_surface":"SURF-1E4E261EE4C8393DB0FE","subject":"외부 표준 (Jackson / BigDecimal / Avro / Protobuf)"},{"assertion_id":"SA-06","condition":"status planned (미검증)","line_end":255,"line_start":255,"modality":"unknown","object":"UTC RFC 3339 (non-UTC 또는 timezone 없는 datetime 미발생)","predicate":"has_schema","quote":"| ca-tmpl 의 모든 응답에서 UTC가 아닌 datetime 또는 timezone 없는 datetime 이 발생하지 않는다 | serialization snapshot test 없으면 LocalDateTime / LocalDate 혼용 또는 non-UTC offset 허용 가능 | OpenAPI snapshot test + Jackson serialization test 로 모든 datetime 필드가 RFC 3339 UTC `Z` 형식인지 검증 | `planned` |","scope":"response datetime","source_surface":"SURF-1E4E261EE4C8393DB0FE","subject":"ca-tmpl 응답 datetime"},{"assertion_id":"SA-07","condition":"status planned (미검증)","line_end":257,"line_start":257,"modality":"unknown","object":"@JsonIgnoreProperties(ignoreUnknown=true)","predicate":"forbids","quote":"| `@JsonIgnoreProperties(ignoreUnknown=true)` 가 ca-tmpl 의 어떤 DTO 클래스에도 붙어 있지 않다 | annotation 우회 시 D4 정책 무력화 | ArchUnit rule: `@JsonIgnoreProperties(ignoreUnknown=true)` 사용 시 build fail | `planned` |","scope":"DTO annotation","source_surface":"SURF-1E4E261EE4C8393DB0FE","subject":"ca-tmpl DTO 클래스"},{"assertion_id":"SA-08","condition":"status planned (미검증)","line_end":258,"line_start":258,"modality":"unknown","object":"new BigDecimal(double) / new BigDecimal(float) 호출","predicate":"forbids","quote":"| `new BigDecimal(double)` / `new BigDecimal(float)` 호출이 ca-tmpl 코드에 없다 | `SBMS-C3` 위험이 실제로 발생 가능 — 컴파일러는 차단 안 함 | ArchUnit rule + 정적 분석으로 해당 생성자 호출 차단 | `planned` |","scope":"BigDecimal construction","source_surface":"SURF-1E4E261EE4C8393DB0FE","subject":"ca-tmpl 코드"},{"assertion_id":"SA-09","condition":"status planned (미검증)","line_end":260,"line_start":260,"modality":"unknown","object":"ca-tmpl response 의 schema 없는 field 노출 차단","predicate":"validates","quote":"| OpenAPI drift 검증이 ca-tmpl response 의 모든 schema 없는 field 노출을 차단한다 | Jackson 만으로는 보장 불가 (`SJUF-C1` Does-not-prove 컬럼) — verification suite 별도 책임 (D5) | `feature-api-contract-baseline` + OpenAPI snapshot diff CI gate 실행 + dummy field 추가 시 fail 시연 | `planned` |","scope":"response drift","source_surface":"SURF-1E4E261EE4C8393DB0FE","subject":"OpenAPI drift 검증"},{"assertion_id":"SA-10","condition":"unconditional","line_end":173,"line_start":173,"modality":"must","object":"framework default 에 암묵적 위임","predicate":"forbids","quote":"| D1 | serialization 을 framework default 에 암묵적으로 맡기지 않음 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C2` (`FAIL_ON_NULL_FOR_PRIMITIVES` default disabled — null → 0 silent 변환) | `official-vendor-doc` | Spring Boot `JacksonProperties` 가 일부 default override 가능 — `spring.jackson.deserialization.*` 명시 권장이 본 branch 외 별도 검증 필요 |","scope":"serialization policy","source_surface":"SURF-10BC0AB17B522B79FE68","subject":"D1 serialization"},{"assertion_id":"SA-11","condition":"unconditional","line_end":174,"line_start":174,"modality":"must","object":"ISO-8601 offset datetime, 서버 timezone = UTC","predicate":"has_schema","quote":"| D2 | datetime = ISO-8601 offset datetime, 서버 timezone = UTC | `raw/official-docs/rfc3339-datetime-utc.md#RFC3339-C2` (true interoperability = UTC, daylight saving 회피), `#RFC3339-C4` (RFC 3339 = ISO 8601 profile, 새 Internet protocol 에서 SHOULD), `#RFC3339-C1` (\"Z\" suffix = UTC offset 00:00), `#RFC3339-C5` (ABNF: `time-offset = \"Z\" / time-numoffset` — alphabetic timezone 약어 금지), `#RFC3339-C7` (생성 시 대문자 \"Z\" SHOULD), `#RFC3339-C8` (예시: `1985-04-12T23:20:50.52Z`) | `official-standard` (IETF RFC 3339) | RFC 3339 는 numeric offset (예: `-08:00`) 도 valid syntactically (RFC3339-C2 Does-not-prove) — \"UTC 만 허용\" 의 strict MUST 는 아니므로 ca-tmpl \"서버 timezone = UTC\" 강제는 운영 정책 보강. Jackson `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` 의 실제 직렬화 형식은 별도 검증 필요 (Usage Boundary 참조) |","scope":"datetime serialization","source_surface":"SURF-10BC0AB17B522B79FE68","subject":"D2 datetime"},{"assertion_id":"SA-12","condition":"domain override 허용","line_end":175,"line_start":175,"modality":"must","object":"string serialization 또는 fixed scale decimal (API별 한 가지), 기본 scale 2, rounding HALF_UP","predicate":"has_schema","quote":"| D3 | money/decimal = string serialization 또는 fixed scale decimal 중 API별 한 가지 명시. 기본 scale = 2, rounding = `HALF_UP` (domain override 허용) | `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C1` (scale 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C2` (HALF_UP 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C3` (`new BigDecimal(double)` 위험), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C4` (`new BigDecimal(String)` 권장) | `official-vendor-doc` (Oracle Javadoc) | `SBMS-C2` \"Does not prove\" 컬럼: HALF_UP 이 회계 / 세무 표준이 모든 도메인에 강제되지는 않음 — domain override 정책 정합. KRW/JPY 같은 scale 0 통화는 별도 처리 필요 |","scope":"money/decimal serialization","source_surface":"SURF-10BC0AB17B522B79FE68","subject":"D3 money/decimal"},{"assertion_id":"SA-13","condition":"unconditional","line_end":176,"line_start":176,"modality":"must","object":"request unknown JSON field (fail-fast) + response schema 에 없는 public field 노출","predicate":"forbids","quote":"| D4 | request unknown JSON field = fail-fast, response = schema 에 없는 public field 노출 금지 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C1` (Jackson 2.13 default = `FAIL_ON_UNKNOWN_PROPERTIES=true` enabled), `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C4` (`READ_UNKNOWN_ENUM_VALUES_AS_NULL` default disabled — 정합), `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2` (Avro 는 반대로 unknown 자동 ignore — 대조 근거) | `official-vendor-doc` (Jackson) + `official-standard` (Avro 대조) | response 측 \"schema 없는 field 노출 금지\" 는 Jackson 만으로 자동 강제 불가 — OpenAPI drift 검증 필요 (`SJUF-C1` Does-not-prove). Avro / Protobuf 모델과 ca-tmpl 결정이 반대 방향임을 보존 |","scope":"unknown field handling","source_surface":"SURF-10BC0AB17B522B79FE68","subject":"D4 unknown field"},{"assertion_id":"SA-14","condition":"unconditional","line_end":177,"line_start":177,"modality":"must","object":"verification suite (본 branch 는 serialization producer)","predicate":"delegates","quote":"| D5 | OpenAPI drift 집행권 = verification suite. 본 branch 는 serialization producer | (sibling branch `feature-api-contract-baseline` 와 책임 분담; 외부 raw 직접 근거 없음. 해당 sibling branch 의 OpenAPI drift gate Decision 에 의존 — §엣지·실패·의존 참조) | UNSUPPORTED_DECISION | sibling branch governance. **sibling branch 미작성/미착수 시 D4 의 response-side \"schema 없는 field 미노출\" 강제는 본 branch 완료 후에도 미보증 상태** — sibling status + 대응 Decision ID 확인 필요 |","scope":"drift enforcement authority","source_surface":"SURF-10BC0AB17B522B79FE68","subject":"OpenAPI drift 집행권"},{"assertion_id":"SA-15","condition":"status needs-confirmation (도구 미정)","line_end":178,"line_start":178,"modality":"must","object":"재사용 (OpenAPI x-removed-fields extension 또는 markdown 카탈로그로 정의)","predicate":"forbids","quote":"| D6 | 제거된 field name / number 재사용 금지 정책을 OpenAPI `x-removed-fields` extension 또는 markdown 카탈로그로 정의 (status: `needs-confirmation`) | `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C2` (Protobuf field number 재사용 금지 표준), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C3` (reserved 필수), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C4` (재사용 시 risk catalog: 디버깅 손실 / parse error / PII 누출 / 데이터 손상), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C5` (JSON encoding 에서 field name 재사용 위험), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C1`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C2`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C5` (OpenAPI `x-` extension 메커니즘 — 정책 자체는 자체 lint 필요), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C6` (JSON Schema `deprecated` 가 재사용 차단 아님) | `official-standard` (Protobuf + OpenAPI + JSON Schema) | `PRVJ-C5` Does-not-prove: `x-removed-fields` 같은 특정 확장이 표준이 아님 — 자체 lint 작성 필요. 도구 선택 자체는 코드 단계 (status `needs-confirmation`) |","scope":"field reuse policy","source_surface":"SURF-10BC0AB17B522B79FE68","subject":"D6 제거된 field name/number"},{"assertion_id":"SA-16","condition":"outbox/event 한정","line_end":179,"line_start":179,"modality":"may","object":"outbox/event 한정 검토 (REST/JSON 외부 API 는 JSON 유지)","predicate":"uses","quote":"| D7 (대안 비교) | Avro Schema Registry 채택은 outbox/event 한정 검토 가치 — REST/JSON 외부 API 는 JSON 유지 | `raw/official-docs/schema-avro-evolution-rules.md#SAER-C1`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C3`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C4` (Avro 의 4 schema resolution 규칙) | `official-standard` | Avro backward/forward/full compatibility **level enforcement** 정의 인용 미확보 (raw 의 \"미확인 / 후속 확인 필요\" 섹션 명시) — 본문 §외부 근거의 \"자동 검사\" 표현은 4 resolution 규칙 확인분만 근거, compatibility level 자동 enforcement 는 Confluent Schema Registry 별도 fetch 필요 |","scope":"schema registry alternative","source_surface":"SURF-10BC0AB17B522B79FE68","subject":"D7 Avro Schema Registry 채택"},{"assertion_id":"SA-17","condition":"scale 0 통화","line_end":240,"line_start":240,"modality":"must","object":"domain override 로 scale 0 명시 (default scale 2 와 충돌)","predicate":"requires","quote":" - **scale 0 통화 (KRW/JPY)**: default scale 2 와 충돌 — domain override 로 scale 0 명시 (D3 Open Risk). schema note 없이 섞이면 `money/decimal` 테스트 실패.","scope":"money/decimal edge","source_surface":"SURF-30E17D1F20CF6F16E163","subject":"scale 0 통화 (KRW/JPY)"},{"assertion_id":"SA-18","condition":"numeric offset (-08:00) 발생 시","line_end":241,"line_start":241,"modality":"must","object":"서버 timezone = UTC (numeric offset 비-Z 출력 시 정책 위반)","predicate":"enforces","quote":" - **numeric offset (`-08:00`)**: RFC 3339 상 syntactically valid (`RFC3339-C2` Does-not-prove) 이나 ca-tmpl 운영 정책은 \"서버 timezone = UTC\" 강제 — offset 비-`Z` 출력 발생 시 운영 정책 위반으로 판정 필요.","scope":"datetime edge","source_surface":"SURF-30E17D1F20CF6F16E163","subject":"ca-tmpl 운영 정책"},{"assertion_id":"SA-19","condition":"JavaTimeModule 미등록 시 RFC 3339 위반","line_end":243,"line_start":243,"modality":"must","object":"JavaTimeModule 등록 (WRITE_DATES_AS_TIMESTAMPS=false 단독 불충분)","predicate":"requires","quote":" - **`JavaTimeModule` 미등록**: `jackson-datatype-jsr310` 의존성 누락 또는 module 등록 누락 시 `LocalDateTime` 이 `[2026, 5, 21, 10, 30]` 배열로 직렬화되어 RFC 3339 계약 위반이 런타임에서야 발견됨 — `WRITE_DATES_AS_TIMESTAMPS=false` 단독으로는 불충분, `ObjectMapper.registerModule(new JavaTimeModule())`(또는 Spring Boot auto-config 의존성) 까지 필요.","scope":"datetime module registration","source_surface":"SURF-30E17D1F20CF6F16E163","subject":"ObjectMapper"},{"assertion_id":"SA-20","condition":"sibling branch 의존","line_end":246,"line_start":246,"modality":"must","object":"feature-api-contract-baseline 의 OpenAPI drift gate (sibling 미착수 시 D4 response-side 미보증)","predicate":"delegates","quote":" - [[raw/branch-notes/feature-api-contract-baseline]] 의 OpenAPI drift gate 에 의존 — D5 가 drift 집행권을 위임. 그 gate 의 schema-없는-field 차단이 본 branch 의 \"response 측 미노출\" 결정을 실제로 강제. **해당 sibling branch 의 status + 대응 Decision ID 확인 필요** — 미착수 시 D4 response-side 강제는 미보증.","scope":"cross-branch dependency","source_surface":"SURF-30E17D1F20CF6F16E163","subject":"본 branch 의 D5 response-side 강제"},{"assertion_id":"SA-21","condition":"sibling branch 확정 시","line_end":247,"line_start":247,"modality":"must","object":"feature-api-compatibility-deprecation-contract 에서 확정 (needs-confirmation 해소)","predicate":"delegates","quote":" - [[raw/branch-notes/feature-api-compatibility-deprecation-contract]] — response field rename/versioning + 제거 field 재사용 정책(D6) 의 실제 도구가 여기서 확정되면 본 branch 의 `needs-confirmation` 해소.","scope":"cross-branch dependency","source_surface":"SURF-30E17D1F20CF6F16E163","subject":"제거 field 재사용 정책 (D6) 실제 도구"},{"assertion_id":"SA-22","condition":"unconditional","line_end":198,"line_start":198,"modality":"must","object":"spring.jackson.deserialization.fail-on-unknown-properties=true (fail)","predicate":"enforces","quote":"| unknown field | fail | `spring.jackson.deserialization.fail-on-unknown-properties=true` | D4 / SJUF-C1 |","scope":"ObjectMapper config","source_surface":"SURF-A14F454150AA7113429C","subject":"unknown field 역직렬화"},{"assertion_id":"SA-23","condition":"unconditional","line_end":201,"line_start":201,"modality":"must","object":"WRITE_DATES_AS_TIMESTAMPS=false + JavaTimeModule (ISO-8601)","predicate":"uses","quote":"| datetime 직렬화 | ISO-8601 | `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` | D2 / RFC3339-C4,C7 |","scope":"ObjectMapper config","source_surface":"SURF-A14F454150AA7113429C","subject":"datetime 직렬화"},{"assertion_id":"SA-24","condition":"unconditional","line_end":225,"line_start":225,"modality":"must","object":"역직렬화 직후 ~ 유효성 검증 이전의 web inbound mapper 계층 (Domain Service 는 재분리 안 함)","predicate":"owns","quote":"> - **레이어 경계**: null/empty/missing 분리 책임은 **역직렬화 직후 ~ 유효성 검증 이전의 web inbound mapper 계층** 이 소유 (Controller DTO → Command/Query 변환 시점). Domain Service 는 이미 분리된 3-상태를 받음 — Domain 에서 재분리하지 않음.","scope":"mapper layer boundary","source_surface":"SURF-A14F454150AA7113429C","subject":"null/empty/missing 분리 책임"},{"assertion_id":"SA-25","condition":"OUT_OF_BRANCH_SCOPE","line_end":230,"line_start":230,"modality":"must","object":"verification suite 소유; drift gate CI 구현 detail 은 feature-api-contract-baseline 로 이관 (본 branch 는 serialization producer)","predicate":"delegates","quote":"> - **OpenAPI drift 집행 메커니즘** (D5): 집행권은 verification suite 소유. 본 branch 는 serialization producer 일 뿐 — drift gate 의 CI 구현 detail 은 sibling `feature-api-contract-baseline` 로 이관.","scope":"drift enforcement authority","source_surface":"SURF-A14F454150AA7113429C","subject":"OpenAPI drift 집행 메커니즘 (D5)"},{"assertion_id":"SA-26","condition":"OUT_OF_BRANCH_SCOPE","line_end":231,"line_start":231,"modality":"must","object":"feature-api-compatibility-deprecation-contract 소관","predicate":"delegates","quote":"> - **response field rename / versioning** (TODO drain 시 위임): `feature-api-compatibility-deprecation-contract` 소관.","scope":"field versioning","source_surface":"SURF-A14F454150AA7113429C","subject":"response field rename / versioning"},{"assertion_id":"SA-27","condition":"outbox/event 한정 (OUT_OF_BRANCH_SCOPE)","line_end":233,"line_start":233,"modality":"may","object":"outbox/event 한정; 외부 REST/JSON 은 JSON 유지","predicate":"uses","quote":"> - **Avro Schema Registry 채택** (D7): outbox/event 한정 별도 검토. 외부 REST/JSON 은 JSON 유지. Confluent compatibility enforcement 메커니즘 미확보.","scope":"schema registry alternative","source_surface":"SURF-A14F454150AA7113429C","subject":"Avro Schema Registry 채택 (D7)"},{"assertion_id":"SA-28","condition":"포함 범위","line_end":81,"line_start":81,"modality":"must","object":"date/time/timezone serialization 기준","predicate":"owns","quote":"- date/time/timezone serialization 기준.","scope":"branch scope","source_surface":"SURF-F81B36EFF607B1F17F0C","subject":"본 branch 범위"},{"assertion_id":"SA-29","condition":"포함 범위","line_end":82,"line_start":82,"modality":"must","object":"BigDecimal/money scale/rounding 기준","predicate":"owns","quote":"- BigDecimal/money scale/rounding 기준.","scope":"branch scope","source_surface":"SURF-F81B36EFF607B1F17F0C","subject":"본 branch 범위"},{"assertion_id":"SA-30","condition":"포함 범위","line_end":84,"line_start":84,"modality":"must","object":"null/empty/missing field 의미 구분","predicate":"owns","quote":"- null/empty/missing field 의미 구분.","scope":"branch scope","source_surface":"SURF-F81B36EFF607B1F17F0C","subject":"본 branch 범위"},{"assertion_id":"SA-31","condition":"포함 범위","line_end":86,"line_start":86,"modality":"must","object":"response field rename/versioning 기준","predicate":"owns","quote":"- response field rename/versioning 기준.","scope":"branch scope","source_surface":"SURF-F81B36EFF607B1F17F0C","subject":"본 branch 범위"},{"assertion_id":"SA-32","condition":"포함 범위","line_end":87,"line_start":87,"modality":"must","object":"OpenAPI schema drift 검증","predicate":"owns","quote":"- OpenAPI schema drift 검증.","scope":"branch scope","source_surface":"SURF-F81B36EFF607B1F17F0C","subject":"본 branch 범위"},{"assertion_id":"SA-33","condition":"제외 범위","line_end":91,"line_start":91,"modality":"must_not","object":"domain-specific schema (제외)","predicate":"other","quote":"- domain-specific schema.","scope":"branch scope","source_surface":"SURF-F81B36EFF607B1F17F0C","subject":"본 branch 범위"},{"assertion_id":"SA-34","condition":"제외 범위","line_end":93,"line_start":93,"modality":"must_not","object":"public API deprecation policy (제외)","predicate":"other","quote":"- public API deprecation policy.","scope":"branch scope","source_surface":"SURF-F81B36EFF607B1F17F0C","subject":"본 branch 범위"}],"candidate_manifest_sha256":"d51e74b31538990a06dd55fb4bcf1ab306a495feff9ae701140486b1dff69c0a","candidates":[{"assertion_a":"SA-06","assertion_b":"SA-07","candidate_id":"SEM-35BA994E74093B7607DB","grouping_key":{"condition":"status planned (미검증)","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-06","assertion_b":"SA-08","candidate_id":"SEM-3B21B3D297B04F5DCC08","grouping_key":{"condition":"status planned (미검증)","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-06","assertion_b":"SA-09","candidate_id":"SEM-82274BB0B510AF0A3F37","grouping_key":{"condition":"status planned (미검증)","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-07","assertion_b":"SA-08","candidate_id":"SEM-3DD55117FD7063615670","grouping_key":{"condition":"status planned (미검증)","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-07","assertion_b":"SA-09","candidate_id":"SEM-1227C6A7EDD2AD659A90","grouping_key":{"condition":"status planned (미검증)","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-08","assertion_b":"SA-09","candidate_id":"SEM-D0F34C82F9FFE8E356A6","grouping_key":{"condition":"status planned (미검증)","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-08","assertion_b":"SA-12","candidate_id":"SEM-EA5A6FC1065FD25D3186","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-09","assertion_b":"SA-13","candidate_id":"SEM-1728180FEF12712476A4","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-09","assertion_b":"SA-14","candidate_id":"SEM-6EBEBACB5C3A61E0C1A0","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-09","assertion_b":"SA-25","candidate_id":"SEM-722FA4814D585B792E5E","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-10","assertion_b":"SA-12","candidate_id":"SEM-2A979A5BC872CFD20F63","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-10","assertion_b":"SA-13","candidate_id":"SEM-BAFBB26D0214D4332602","grouping_key":{"condition":"unconditional","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-11","assertion_b":"SA-13","candidate_id":"SEM-BAA497207FDDE468C67E","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-11","assertion_b":"SA-15","candidate_id":"SEM-76A31EDF16F89254EAF2","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-11","assertion_b":"SA-16","candidate_id":"SEM-F480CD30980291A8029B","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-11","assertion_b":"SA-18","candidate_id":"SEM-7E1DB1A5FF13D9A6382A","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-11","assertion_b":"SA-19","candidate_id":"SEM-4AF6C4298A38F6703C67","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-11","assertion_b":"SA-23","candidate_id":"SEM-A6E16DD93612672E0DE0","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-12","assertion_b":"SA-13","candidate_id":"SEM-C37D6DA20FF08FFEC910","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-12","assertion_b":"SA-17","candidate_id":"SEM-0537872224928D38C070","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-13","assertion_b":"SA-15","candidate_id":"SEM-0DA0AE31A9DD29494DB1","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-13","assertion_b":"SA-16","candidate_id":"SEM-EDCD7FC1D63F892B9A08","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-14","assertion_b":"SA-25","candidate_id":"SEM-3B4263CD28CBFFEFE76C","grouping_key":{"condition":"","predicate":"delegates","scope":"drift enforcement authority","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-15","assertion_b":"SA-16","candidate_id":"SEM-DDFBE815F9B98201763E","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-15","assertion_b":"SA-21","candidate_id":"SEM-8A91076B0B2C3306EAA5","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-16","assertion_b":"SA-27","candidate_id":"SEM-1990187A8CF0F65FE087","grouping_key":{"condition":"","predicate":"uses","scope":"schema registry alternative","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-19","assertion_b":"SA-23","candidate_id":"SEM-141A1BE4635D6865657C","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-21","assertion_b":"SA-31","candidate_id":"SEM-C2DFCBA96EF024AA29EC","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-24","assertion_b":"SA-30","candidate_id":"SEM-F5783B29F5F524D070A8","grouping_key":{"condition":"","predicate":"owns","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"SA-28","assertion_b":"SA-29","candidate_id":"SEM-139AD622A7BF51079F86","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-28","assertion_b":"SA-30","candidate_id":"SEM-EE3B48CF6E9DC73C0299","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-28","assertion_b":"SA-31","candidate_id":"SEM-2ADFB6B2EC768455C6A3","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-28","assertion_b":"SA-32","candidate_id":"SEM-C933DD74F96302AA4FC5","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-29","assertion_b":"SA-30","candidate_id":"SEM-A2EB9C27F5D8A4421758","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-29","assertion_b":"SA-31","candidate_id":"SEM-C6EE3F32F1BC4C747867","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-29","assertion_b":"SA-32","candidate_id":"SEM-B2ED4C05EEBF63533B70","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-30","assertion_b":"SA-31","candidate_id":"SEM-F85B6266104254821301","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-30","assertion_b":"SA-32","candidate_id":"SEM-6650D8D88703F7C14FCA","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-31","assertion_b":"SA-32","candidate_id":"SEM-29051E605805972E6310","grouping_key":{"condition":"포함 범위","predicate":"owns","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]},{"assertion_a":"SA-33","assertion_b":"SA-34","candidate_id":"SEM-60C88D7664D4ECEA3CEB","grouping_key":{"condition":"제외 범위","predicate":"other","scope":"branch scope","subject":"본 branch 범위"},"rule_ids":["BASE"]}],"coverage":{"assertions":34,"candidate_pairs":40,"eligible_surfaces":6,"processed_surfaces":6},"document_sha256":"36d5371e9609dbeb6b9f2ec22d0a0979a8902896d3b6c7845447fee4234cb563","explicit_blocking":[],"mode":"local","ontology_sha256":"76d41a29233c830e1940ebb3244263e2b9bfb8dd6a01f2a1d1c51ce5a1b10468","output_schema":"semantic-audit-result/v1","schema_version":"semantic-verdict-request/v1","subject":"raw/branch-notes/feature-schema-serialization-contract.md"},"audit_request_sha256":"0fe73e3573176e4ac030ffab906595a787dbaba3653fb4ca5463f0eea00084d1","audit_result":{"auditor":{"contract_version":"semantic-coherence/v1","model_id":"claude-opus-4-8","run_id":"a40778d63720cd461"},"mode":"local","request_sha256":"0fe73e3573176e4ac030ffab906595a787dbaba3653fb4ca5463f0eea00084d1","schema_version":"semantic-audit-result/v1","subject":"raw/branch-notes/feature-schema-serialization-contract.md","verdicts":[{"candidate_id":"SEM-35BA994E74093B7607DB","evidence_a":{"line_end":255,"line_start":255,"quote":"| ca-tmpl 의 모든 응답에서 UTC가 아닌 datetime 또는 timezone 없는 datetime 이 발생하지 않는다 | serialization snapshot test 없으면 LocalDateTime / LocalDate 혼용 또는 non-UTC offset 허용 가능 | OpenAPI snapshot test + Jackson serialization test 로 모든 datetime 필드가 RFC 3339 UTC `Z` 형식인지 검증 | `planned` |"},"evidence_b":{"line_end":257,"line_start":257,"quote":"| `@JsonIgnoreProperties(ignoreUnknown=true)` 가 ca-tmpl 의 어떤 DTO 클래스에도 붙어 있지 않다 | annotation 우회 시 D4 정책 무력화 | ArchUnit rule: `@JsonIgnoreProperties(ignoreUnknown=true)` 사용 시 build fail | `planned` |"},"proof_manifest":null,"rationale":"SA-06 (datetime UTC RFC 3339) and SA-07 (forbid @JsonIgnoreProperties(ignoreUnknown=true)) are two distinct planned verification checks over different targets (response datetime vs DTO annotation). They coexist without either taking over the other's responsibility.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-3B21B3D297B04F5DCC08","evidence_a":{"line_end":255,"line_start":255,"quote":"| ca-tmpl 의 모든 응답에서 UTC가 아닌 datetime 또는 timezone 없는 datetime 이 발생하지 않는다 | serialization snapshot test 없으면 LocalDateTime / LocalDate 혼용 또는 non-UTC offset 허용 가능 | OpenAPI snapshot test + Jackson serialization test 로 모든 datetime 필드가 RFC 3339 UTC `Z` 형식인지 검증 | `planned` |"},"evidence_b":{"line_end":258,"line_start":258,"quote":"| `new BigDecimal(double)` / `new BigDecimal(float)` 호출이 ca-tmpl 코드에 없다 | `SBMS-C3` 위험이 실제로 발생 가능 — 컴파일러는 차단 안 함 | ArchUnit rule + 정적 분석으로 해당 생성자 호출 차단 | `planned` |"},"proof_manifest":null,"rationale":"SA-06 (datetime UTC) and SA-08 (forbid new BigDecimal(double)/(float)) are independent planned verification checks over different scopes (datetime vs BigDecimal construction). No shared property; compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-82274BB0B510AF0A3F37","evidence_a":{"line_end":255,"line_start":255,"quote":"| ca-tmpl 의 모든 응답에서 UTC가 아닌 datetime 또는 timezone 없는 datetime 이 발생하지 않는다 | serialization snapshot test 없으면 LocalDateTime / LocalDate 혼용 또는 non-UTC offset 허용 가능 | OpenAPI snapshot test + Jackson serialization test 로 모든 datetime 필드가 RFC 3339 UTC `Z` 형식인지 검증 | `planned` |"},"evidence_b":{"line_end":260,"line_start":260,"quote":"| OpenAPI drift 검증이 ca-tmpl response 의 모든 schema 없는 field 노출을 차단한다 | Jackson 만으로는 보장 불가 (`SJUF-C1` Does-not-prove 컬럼) — verification suite 별도 책임 (D5) | `feature-api-contract-baseline` + OpenAPI snapshot diff CI gate 실행 + dummy field 추가 시 fail 시연 | `planned` |"},"proof_manifest":null,"rationale":"SA-06 (datetime UTC) and SA-09 (OpenAPI drift blocks undeclared response fields) are separate planned verification checks over different concerns (datetime vs response drift). Compatible, non-overlapping.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-3DD55117FD7063615670","evidence_a":{"line_end":257,"line_start":257,"quote":"| `@JsonIgnoreProperties(ignoreUnknown=true)` 가 ca-tmpl 의 어떤 DTO 클래스에도 붙어 있지 않다 | annotation 우회 시 D4 정책 무력화 | ArchUnit rule: `@JsonIgnoreProperties(ignoreUnknown=true)` 사용 시 build fail | `planned` |"},"evidence_b":{"line_end":258,"line_start":258,"quote":"| `new BigDecimal(double)` / `new BigDecimal(float)` 호출이 ca-tmpl 코드에 없다 | `SBMS-C3` 위험이 실제로 발생 가능 — 컴파일러는 차단 안 함 | ArchUnit rule + 정적 분석으로 해당 생성자 호출 차단 | `planned` |"},"proof_manifest":null,"rationale":"Both are planned 'forbids' verification checks but over different targets: SA-07 forbids @JsonIgnoreProperties on DTOs, SA-08 forbids new BigDecimal(double/float). Different contract properties; no mutual exclusion.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-1227C6A7EDD2AD659A90","evidence_a":{"line_end":257,"line_start":257,"quote":"| `@JsonIgnoreProperties(ignoreUnknown=true)` 가 ca-tmpl 의 어떤 DTO 클래스에도 붙어 있지 않다 | annotation 우회 시 D4 정책 무력화 | ArchUnit rule: `@JsonIgnoreProperties(ignoreUnknown=true)` 사용 시 build fail | `planned` |"},"evidence_b":{"line_end":260,"line_start":260,"quote":"| OpenAPI drift 검증이 ca-tmpl response 의 모든 schema 없는 field 노출을 차단한다 | Jackson 만으로는 보장 불가 (`SJUF-C1` Does-not-prove 컬럼) — verification suite 별도 책임 (D5) | `feature-api-contract-baseline` + OpenAPI snapshot diff CI gate 실행 + dummy field 추가 시 fail 시연 | `planned` |"},"proof_manifest":null,"rationale":"SA-07 (forbid @JsonIgnoreProperties) and SA-09 (OpenAPI drift validation) are distinct planned checks over DTO-annotation vs response-drift scopes. Compatible details, no shared property.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-D0F34C82F9FFE8E356A6","evidence_a":{"line_end":258,"line_start":258,"quote":"| `new BigDecimal(double)` / `new BigDecimal(float)` 호출이 ca-tmpl 코드에 없다 | `SBMS-C3` 위험이 실제로 발생 가능 — 컴파일러는 차단 안 함 | ArchUnit rule + 정적 분석으로 해당 생성자 호출 차단 | `planned` |"},"evidence_b":{"line_end":260,"line_start":260,"quote":"| OpenAPI drift 검증이 ca-tmpl response 의 모든 schema 없는 field 노출을 차단한다 | Jackson 만으로는 보장 불가 (`SJUF-C1` Does-not-prove 컬럼) — verification suite 별도 책임 (D5) | `feature-api-contract-baseline` + OpenAPI snapshot diff CI gate 실행 + dummy field 추가 시 fail 시연 | `planned` |"},"proof_manifest":null,"rationale":"SA-08 (forbid new BigDecimal(double/float)) and SA-09 (OpenAPI drift validation) are independent planned checks over BigDecimal-construction vs response-drift scopes. No conflict.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-EA5A6FC1065FD25D3186","evidence_a":{"line_end":258,"line_start":258,"quote":"| `new BigDecimal(double)` / `new BigDecimal(float)` 호출이 ca-tmpl 코드에 없다 | `SBMS-C3` 위험이 실제로 발생 가능 — 컴파일러는 차단 안 함 | ArchUnit rule + 정적 분석으로 해당 생성자 호출 차단 | `planned` |"},"evidence_b":{"line_end":175,"line_start":175,"quote":"| D3 | money/decimal = string serialization 또는 fixed scale decimal 중 API별 한 가지 명시. 기본 scale = 2, rounding = `HALF_UP` (domain override 허용) | `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C1` (scale 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C2` (HALF_UP 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C3` (`new BigDecimal(double)` 위험), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C4` (`new BigDecimal(String)` 권장) | `official-vendor-doc` (Oracle Javadoc) | `SBMS-C2` \"Does not prove\" 컬럼: HALF_UP 이 회계 / 세무 표준이 모든 도메인에 강제되지는 않음 — domain override 정책 정합. KRW/JPY 같은 scale 0 통화는 별도 처리 필요 |"},"proof_manifest":null,"rationale":"SA-08 is a planned verification (no new BigDecimal(double)) that supports the D3 decimal decision in SA-12 (SBMS-C3 risk); it supplies an enforcement detail without redefining D3's scale/rounding contract. Compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-1728180FEF12712476A4","evidence_a":{"line_end":260,"line_start":260,"quote":"| OpenAPI drift 검증이 ca-tmpl response 의 모든 schema 없는 field 노출을 차단한다 | Jackson 만으로는 보장 불가 (`SJUF-C1` Does-not-prove 컬럼) — verification suite 별도 책임 (D5) | `feature-api-contract-baseline` + OpenAPI snapshot diff CI gate 실행 + dummy field 추가 시 fail 시연 | `planned` |"},"evidence_b":{"line_end":176,"line_start":176,"quote":"| D4 | request unknown JSON field = fail-fast, response = schema 에 없는 public field 노출 금지 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C1` (Jackson 2.13 default = `FAIL_ON_UNKNOWN_PROPERTIES=true` enabled), `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C4` (`READ_UNKNOWN_ENUM_VALUES_AS_NULL` default disabled — 정합), `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2` (Avro 는 반대로 unknown 자동 ignore — 대조 근거) | `official-vendor-doc` (Jackson) + `official-standard` (Avro 대조) | response 측 \"schema 없는 field 노출 금지\" 는 Jackson 만으로 자동 강제 불가 — OpenAPI drift 검증 필요 (`SJUF-C1` Does-not-prove). Avro / Protobuf 모델과 ca-tmpl 결정이 반대 방향임을 보존 |"},"proof_manifest":null,"rationale":"SA-09 (OpenAPI drift blocks undeclared response fields) is the verification that enforces the response-side of D4 in SA-13 (which Jackson alone cannot enforce). It supplies the enforcement stage, not a competing decision. Compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-6EBEBACB5C3A61E0C1A0","evidence_a":{"line_end":260,"line_start":260,"quote":"| OpenAPI drift 검증이 ca-tmpl response 의 모든 schema 없는 field 노출을 차단한다 | Jackson 만으로는 보장 불가 (`SJUF-C1` Does-not-prove 컬럼) — verification suite 별도 책임 (D5) | `feature-api-contract-baseline` + OpenAPI snapshot diff CI gate 실행 + dummy field 추가 시 fail 시연 | `planned` |"},"evidence_b":{"line_end":177,"line_start":177,"quote":"| D5 | OpenAPI drift 집행권 = verification suite. 본 branch 는 serialization producer | (sibling branch `feature-api-contract-baseline` 와 책임 분담; 외부 raw 직접 근거 없음. 해당 sibling branch 의 OpenAPI drift gate Decision 에 의존 — §엣지·실패·의존 참조) | UNSUPPORTED_DECISION | sibling branch governance. **sibling branch 미작성/미착수 시 D4 의 response-side \"schema 없는 field 미노출\" 강제는 본 branch 완료 후에도 미보증 상태** — sibling status + 대응 Decision ID 확인 필요 |"},"proof_manifest":null,"rationale":"SA-09 describes what OpenAPI drift verification does; SA-14 (D5) delegates that enforcement authority to the verification suite while this branch is the serialization producer. Producer/verifier split coexists; no takeover.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-722FA4814D585B792E5E","evidence_a":{"line_end":260,"line_start":260,"quote":"| OpenAPI drift 검증이 ca-tmpl response 의 모든 schema 없는 field 노출을 차단한다 | Jackson 만으로는 보장 불가 (`SJUF-C1` Does-not-prove 컬럼) — verification suite 별도 책임 (D5) | `feature-api-contract-baseline` + OpenAPI snapshot diff CI gate 실행 + dummy field 추가 시 fail 시연 | `planned` |"},"evidence_b":{"line_end":230,"line_start":230,"quote":"> - **OpenAPI drift 집행 메커니즘** (D5): 집행권은 verification suite 소유. 본 branch 는 serialization producer 일 뿐 — drift gate 의 CI 구현 detail 은 sibling `feature-api-contract-baseline` 로 이관."},"proof_manifest":null,"rationale":"SA-09 (drift verification behavior) and SA-25 (D5 delegates drift-gate CI implementation to sibling feature-api-contract-baseline, verification suite owns authority) are compatible: behavior vs authority/implementation split. No conflict.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-2A979A5BC872CFD20F63","evidence_a":{"line_end":173,"line_start":173,"quote":"| D1 | serialization 을 framework default 에 암묵적으로 맡기지 않음 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C2` (`FAIL_ON_NULL_FOR_PRIMITIVES` default disabled — null → 0 silent 변환) | `official-vendor-doc` | Spring Boot `JacksonProperties` 가 일부 default override 가능 — `spring.jackson.deserialization.*` 명시 권장이 본 branch 외 별도 검증 필요 |"},"evidence_b":{"line_end":175,"line_start":175,"quote":"| D3 | money/decimal = string serialization 또는 fixed scale decimal 중 API별 한 가지 명시. 기본 scale = 2, rounding = `HALF_UP` (domain override 허용) | `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C1` (scale 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C2` (HALF_UP 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C3` (`new BigDecimal(double)` 위험), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C4` (`new BigDecimal(String)` 권장) | `official-vendor-doc` (Oracle Javadoc) | `SBMS-C2` \"Does not prove\" 컬럼: HALF_UP 이 회계 / 세무 표준이 모든 도메인에 강제되지는 않음 — domain override 정책 정합. KRW/JPY 같은 scale 0 통화는 별도 처리 필요 |"},"proof_manifest":null,"rationale":"SA-10 (D1: no implicit reliance on framework serialization defaults) and SA-12 (D3: money/decimal scale/rounding) are two independent decisions over different concerns. Compatible constraints.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-BAFBB26D0214D4332602","evidence_a":{"line_end":173,"line_start":173,"quote":"| D1 | serialization 을 framework default 에 암묵적으로 맡기지 않음 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C2` (`FAIL_ON_NULL_FOR_PRIMITIVES` default disabled — null → 0 silent 변환) | `official-vendor-doc` | Spring Boot `JacksonProperties` 가 일부 default override 가능 — `spring.jackson.deserialization.*` 명시 권장이 본 branch 외 별도 검증 필요 |"},"evidence_b":{"line_end":176,"line_start":176,"quote":"| D4 | request unknown JSON field = fail-fast, response = schema 에 없는 public field 노출 금지 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C1` (Jackson 2.13 default = `FAIL_ON_UNKNOWN_PROPERTIES=true` enabled), `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C4` (`READ_UNKNOWN_ENUM_VALUES_AS_NULL` default disabled — 정합), `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2` (Avro 는 반대로 unknown 자동 ignore — 대조 근거) | `official-vendor-doc` (Jackson) + `official-standard` (Avro 대조) | response 측 \"schema 없는 field 노출 금지\" 는 Jackson 만으로 자동 강제 불가 — OpenAPI drift 검증 필요 (`SJUF-C1` Does-not-prove). Avro / Protobuf 모델과 ca-tmpl 결정이 반대 방향임을 보존 |"},"proof_manifest":null,"rationale":"Both are unconditional 'forbids' but distinct decisions: SA-10 (D1) forbids implicit framework-default serialization; SA-13 (D4) forbids unknown request fields / undeclared response fields. Different properties, no mutual exclusion.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-BAA497207FDDE468C67E","evidence_a":{"line_end":174,"line_start":174,"quote":"| D2 | datetime = ISO-8601 offset datetime, 서버 timezone = UTC | `raw/official-docs/rfc3339-datetime-utc.md#RFC3339-C2` (true interoperability = UTC, daylight saving 회피), `#RFC3339-C4` (RFC 3339 = ISO 8601 profile, 새 Internet protocol 에서 SHOULD), `#RFC3339-C1` (\"Z\" suffix = UTC offset 00:00), `#RFC3339-C5` (ABNF: `time-offset = \"Z\" / time-numoffset` — alphabetic timezone 약어 금지), `#RFC3339-C7` (생성 시 대문자 \"Z\" SHOULD), `#RFC3339-C8` (예시: `1985-04-12T23:20:50.52Z`) | `official-standard` (IETF RFC 3339) | RFC 3339 는 numeric offset (예: `-08:00`) 도 valid syntactically (RFC3339-C2 Does-not-prove) — \"UTC 만 허용\" 의 strict MUST 는 아니므로 ca-tmpl \"서버 timezone = UTC\" 강제는 운영 정책 보강. Jackson `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` 의 실제 직렬화 형식은 별도 검증 필요 (Usage Boundary 참조) |"},"evidence_b":{"line_end":176,"line_start":176,"quote":"| D4 | request unknown JSON field = fail-fast, response = schema 에 없는 public field 노출 금지 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C1` (Jackson 2.13 default = `FAIL_ON_UNKNOWN_PROPERTIES=true` enabled), `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C4` (`READ_UNKNOWN_ENUM_VALUES_AS_NULL` default disabled — 정합), `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2` (Avro 는 반대로 unknown 자동 ignore — 대조 근거) | `official-vendor-doc` (Jackson) + `official-standard` (Avro 대조) | response 측 \"schema 없는 field 노출 금지\" 는 Jackson 만으로 자동 강제 불가 — OpenAPI drift 검증 필요 (`SJUF-C1` Does-not-prove). Avro / Protobuf 모델과 ca-tmpl 결정이 반대 방향임을 보존 |"},"proof_manifest":null,"rationale":"SA-11 (D2 datetime = ISO-8601 offset, UTC) and SA-13 (D4 unknown-field handling) are separate decisions over datetime vs unknown-field scopes. Compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-76A31EDF16F89254EAF2","evidence_a":{"line_end":174,"line_start":174,"quote":"| D2 | datetime = ISO-8601 offset datetime, 서버 timezone = UTC | `raw/official-docs/rfc3339-datetime-utc.md#RFC3339-C2` (true interoperability = UTC, daylight saving 회피), `#RFC3339-C4` (RFC 3339 = ISO 8601 profile, 새 Internet protocol 에서 SHOULD), `#RFC3339-C1` (\"Z\" suffix = UTC offset 00:00), `#RFC3339-C5` (ABNF: `time-offset = \"Z\" / time-numoffset` — alphabetic timezone 약어 금지), `#RFC3339-C7` (생성 시 대문자 \"Z\" SHOULD), `#RFC3339-C8` (예시: `1985-04-12T23:20:50.52Z`) | `official-standard` (IETF RFC 3339) | RFC 3339 는 numeric offset (예: `-08:00`) 도 valid syntactically (RFC3339-C2 Does-not-prove) — \"UTC 만 허용\" 의 strict MUST 는 아니므로 ca-tmpl \"서버 timezone = UTC\" 강제는 운영 정책 보강. Jackson `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` 의 실제 직렬화 형식은 별도 검증 필요 (Usage Boundary 참조) |"},"evidence_b":{"line_end":178,"line_start":178,"quote":"| D6 | 제거된 field name / number 재사용 금지 정책을 OpenAPI `x-removed-fields` extension 또는 markdown 카탈로그로 정의 (status: `needs-confirmation`) | `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C2` (Protobuf field number 재사용 금지 표준), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C3` (reserved 필수), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C4` (재사용 시 risk catalog: 디버깅 손실 / parse error / PII 누출 / 데이터 손상), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C5` (JSON encoding 에서 field name 재사용 위험), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C1`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C2`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C5` (OpenAPI `x-` extension 메커니즘 — 정책 자체는 자체 lint 필요), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C6` (JSON Schema `deprecated` 가 재사용 차단 아님) | `official-standard` (Protobuf + OpenAPI + JSON Schema) | `PRVJ-C5` Does-not-prove: `x-removed-fields` 같은 특정 확장이 표준이 아님 — 자체 lint 작성 필요. 도구 선택 자체는 코드 단계 (status `needs-confirmation`) |"},"proof_manifest":null,"rationale":"SA-11 (D2 datetime) and SA-15 (D6 forbid removed-field reuse) are independent decisions over unrelated concerns. No shared property; compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-F480CD30980291A8029B","evidence_a":{"line_end":174,"line_start":174,"quote":"| D2 | datetime = ISO-8601 offset datetime, 서버 timezone = UTC | `raw/official-docs/rfc3339-datetime-utc.md#RFC3339-C2` (true interoperability = UTC, daylight saving 회피), `#RFC3339-C4` (RFC 3339 = ISO 8601 profile, 새 Internet protocol 에서 SHOULD), `#RFC3339-C1` (\"Z\" suffix = UTC offset 00:00), `#RFC3339-C5` (ABNF: `time-offset = \"Z\" / time-numoffset` — alphabetic timezone 약어 금지), `#RFC3339-C7` (생성 시 대문자 \"Z\" SHOULD), `#RFC3339-C8` (예시: `1985-04-12T23:20:50.52Z`) | `official-standard` (IETF RFC 3339) | RFC 3339 는 numeric offset (예: `-08:00`) 도 valid syntactically (RFC3339-C2 Does-not-prove) — \"UTC 만 허용\" 의 strict MUST 는 아니므로 ca-tmpl \"서버 timezone = UTC\" 강제는 운영 정책 보강. Jackson `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` 의 실제 직렬화 형식은 별도 검증 필요 (Usage Boundary 참조) |"},"evidence_b":{"line_end":179,"line_start":179,"quote":"| D7 (대안 비교) | Avro Schema Registry 채택은 outbox/event 한정 검토 가치 — REST/JSON 외부 API 는 JSON 유지 | `raw/official-docs/schema-avro-evolution-rules.md#SAER-C1`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C3`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C4` (Avro 의 4 schema resolution 규칙) | `official-standard` | Avro backward/forward/full compatibility **level enforcement** 정의 인용 미확보 (raw 의 \"미확인 / 후속 확인 필요\" 섹션 명시) — 본문 §외부 근거의 \"자동 검사\" 표현은 4 resolution 규칙 확인분만 근거, compatibility level 자동 enforcement 는 Confluent Schema Registry 별도 fetch 필요 |"},"proof_manifest":null,"rationale":"SA-11 (D2 datetime) and SA-16 (D7 Avro Schema Registry for outbox/event only) are distinct decisions over different transport scopes. Compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-7E1DB1A5FF13D9A6382A","evidence_a":{"line_end":174,"line_start":174,"quote":"| D2 | datetime = ISO-8601 offset datetime, 서버 timezone = UTC | `raw/official-docs/rfc3339-datetime-utc.md#RFC3339-C2` (true interoperability = UTC, daylight saving 회피), `#RFC3339-C4` (RFC 3339 = ISO 8601 profile, 새 Internet protocol 에서 SHOULD), `#RFC3339-C1` (\"Z\" suffix = UTC offset 00:00), `#RFC3339-C5` (ABNF: `time-offset = \"Z\" / time-numoffset` — alphabetic timezone 약어 금지), `#RFC3339-C7` (생성 시 대문자 \"Z\" SHOULD), `#RFC3339-C8` (예시: `1985-04-12T23:20:50.52Z`) | `official-standard` (IETF RFC 3339) | RFC 3339 는 numeric offset (예: `-08:00`) 도 valid syntactically (RFC3339-C2 Does-not-prove) — \"UTC 만 허용\" 의 strict MUST 는 아니므로 ca-tmpl \"서버 timezone = UTC\" 강제는 운영 정책 보강. Jackson `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` 의 실제 직렬화 형식은 별도 검증 필요 (Usage Boundary 참조) |"},"evidence_b":{"line_end":241,"line_start":241,"quote":" - **numeric offset (`-08:00`)**: RFC 3339 상 syntactically valid (`RFC3339-C2` Does-not-prove) 이나 ca-tmpl 운영 정책은 \"서버 timezone = UTC\" 강제 — offset 비-`Z` 출력 발생 시 운영 정책 위반으로 판정 필요."},"proof_manifest":null,"rationale":"SA-18 elaborates SA-11's D2 'server timezone = UTC' as an edge case (numeric offset non-Z output = policy violation). Same UTC policy, direction preserved; SA-18 supplies the enforcement detail without changing meaning.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-4AF6C4298A38F6703C67","evidence_a":{"line_end":174,"line_start":174,"quote":"| D2 | datetime = ISO-8601 offset datetime, 서버 timezone = UTC | `raw/official-docs/rfc3339-datetime-utc.md#RFC3339-C2` (true interoperability = UTC, daylight saving 회피), `#RFC3339-C4` (RFC 3339 = ISO 8601 profile, 새 Internet protocol 에서 SHOULD), `#RFC3339-C1` (\"Z\" suffix = UTC offset 00:00), `#RFC3339-C5` (ABNF: `time-offset = \"Z\" / time-numoffset` — alphabetic timezone 약어 금지), `#RFC3339-C7` (생성 시 대문자 \"Z\" SHOULD), `#RFC3339-C8` (예시: `1985-04-12T23:20:50.52Z`) | `official-standard` (IETF RFC 3339) | RFC 3339 는 numeric offset (예: `-08:00`) 도 valid syntactically (RFC3339-C2 Does-not-prove) — \"UTC 만 허용\" 의 strict MUST 는 아니므로 ca-tmpl \"서버 timezone = UTC\" 강제는 운영 정책 보강. Jackson `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` 의 실제 직렬화 형식은 별도 검증 필요 (Usage Boundary 참조) |"},"evidence_b":{"line_end":243,"line_start":243,"quote":" - **`JavaTimeModule` 미등록**: `jackson-datatype-jsr310` 의존성 누락 또는 module 등록 누락 시 `LocalDateTime` 이 `[2026, 5, 21, 10, 30]` 배열로 직렬화되어 RFC 3339 계약 위반이 런타임에서야 발견됨 — `WRITE_DATES_AS_TIMESTAMPS=false` 단독으로는 불충분, `ObjectMapper.registerModule(new JavaTimeModule())`(또는 Spring Boot auto-config 의존성) 까지 필요."},"proof_manifest":null,"rationale":"SA-19 (ObjectMapper must register JavaTimeModule; WRITE_DATES_AS_TIMESTAMPS=false alone insufficient) supplies the implementation detail realizing SA-11's D2 ISO-8601/UTC datetime decision. Compatible detail, no takeover.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-A6E16DD93612672E0DE0","evidence_a":{"line_end":174,"line_start":174,"quote":"| D2 | datetime = ISO-8601 offset datetime, 서버 timezone = UTC | `raw/official-docs/rfc3339-datetime-utc.md#RFC3339-C2` (true interoperability = UTC, daylight saving 회피), `#RFC3339-C4` (RFC 3339 = ISO 8601 profile, 새 Internet protocol 에서 SHOULD), `#RFC3339-C1` (\"Z\" suffix = UTC offset 00:00), `#RFC3339-C5` (ABNF: `time-offset = \"Z\" / time-numoffset` — alphabetic timezone 약어 금지), `#RFC3339-C7` (생성 시 대문자 \"Z\" SHOULD), `#RFC3339-C8` (예시: `1985-04-12T23:20:50.52Z`) | `official-standard` (IETF RFC 3339) | RFC 3339 는 numeric offset (예: `-08:00`) 도 valid syntactically (RFC3339-C2 Does-not-prove) — \"UTC 만 허용\" 의 strict MUST 는 아니므로 ca-tmpl \"서버 timezone = UTC\" 강제는 운영 정책 보강. Jackson `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` 의 실제 직렬화 형식은 별도 검증 필요 (Usage Boundary 참조) |"},"evidence_b":{"line_end":201,"line_start":201,"quote":"| datetime 직렬화 | ISO-8601 | `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` | D2 / RFC3339-C4,C7 |"},"proof_manifest":null,"rationale":"SA-23 is the ObjectMapper config (WRITE_DATES_AS_TIMESTAMPS=false + JavaTimeModule) that implements SA-11's D2 ISO-8601/UTC datetime decision. Config detail supporting the decision; compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C37D6DA20FF08FFEC910","evidence_a":{"line_end":175,"line_start":175,"quote":"| D3 | money/decimal = string serialization 또는 fixed scale decimal 중 API별 한 가지 명시. 기본 scale = 2, rounding = `HALF_UP` (domain override 허용) | `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C1` (scale 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C2` (HALF_UP 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C3` (`new BigDecimal(double)` 위험), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C4` (`new BigDecimal(String)` 권장) | `official-vendor-doc` (Oracle Javadoc) | `SBMS-C2` \"Does not prove\" 컬럼: HALF_UP 이 회계 / 세무 표준이 모든 도메인에 강제되지는 않음 — domain override 정책 정합. KRW/JPY 같은 scale 0 통화는 별도 처리 필요 |"},"evidence_b":{"line_end":176,"line_start":176,"quote":"| D4 | request unknown JSON field = fail-fast, response = schema 에 없는 public field 노출 금지 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C1` (Jackson 2.13 default = `FAIL_ON_UNKNOWN_PROPERTIES=true` enabled), `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C4` (`READ_UNKNOWN_ENUM_VALUES_AS_NULL` default disabled — 정합), `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2` (Avro 는 반대로 unknown 자동 ignore — 대조 근거) | `official-vendor-doc` (Jackson) + `official-standard` (Avro 대조) | response 측 \"schema 없는 field 노출 금지\" 는 Jackson 만으로 자동 강제 불가 — OpenAPI drift 검증 필요 (`SJUF-C1` Does-not-prove). Avro / Protobuf 모델과 ca-tmpl 결정이 반대 방향임을 보존 |"},"proof_manifest":null,"rationale":"SA-12 (D3 money/decimal) and SA-13 (D4 unknown-field handling) are independent decisions over different concerns. No shared property; compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-0537872224928D38C070","evidence_a":{"line_end":175,"line_start":175,"quote":"| D3 | money/decimal = string serialization 또는 fixed scale decimal 중 API별 한 가지 명시. 기본 scale = 2, rounding = `HALF_UP` (domain override 허용) | `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C1` (scale 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C2` (HALF_UP 정의), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C3` (`new BigDecimal(double)` 위험), `raw/official-docs/schema-bigdecimal-money-serialization-java.md#SBMS-C4` (`new BigDecimal(String)` 권장) | `official-vendor-doc` (Oracle Javadoc) | `SBMS-C2` \"Does not prove\" 컬럼: HALF_UP 이 회계 / 세무 표준이 모든 도메인에 강제되지는 않음 — domain override 정책 정합. KRW/JPY 같은 scale 0 통화는 별도 처리 필요 |"},"evidence_b":{"line_end":240,"line_start":240,"quote":" - **scale 0 통화 (KRW/JPY)**: default scale 2 와 충돌 — domain override 로 scale 0 명시 (D3 Open Risk). schema note 없이 섞이면 `money/decimal` 테스트 실패."},"proof_manifest":null,"rationale":"SA-12 sets D3 default scale = 2 but explicitly permits domain override and notes scale-0 currencies need separate handling; SA-17 applies scale 0 under the differing condition 'scale 0 통화 (KRW/JPY)'. The differing currency-type condition explains the different scale value — a permitted variant, not a conflict.","verdict":"CONTEXTUAL_VARIANT"},{"candidate_id":"SEM-0DA0AE31A9DD29494DB1","evidence_a":{"line_end":176,"line_start":176,"quote":"| D4 | request unknown JSON field = fail-fast, response = schema 에 없는 public field 노출 금지 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C1` (Jackson 2.13 default = `FAIL_ON_UNKNOWN_PROPERTIES=true` enabled), `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C4` (`READ_UNKNOWN_ENUM_VALUES_AS_NULL` default disabled — 정합), `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2` (Avro 는 반대로 unknown 자동 ignore — 대조 근거) | `official-vendor-doc` (Jackson) + `official-standard` (Avro 대조) | response 측 \"schema 없는 field 노출 금지\" 는 Jackson 만으로 자동 강제 불가 — OpenAPI drift 검증 필요 (`SJUF-C1` Does-not-prove). Avro / Protobuf 모델과 ca-tmpl 결정이 반대 방향임을 보존 |"},"evidence_b":{"line_end":178,"line_start":178,"quote":"| D6 | 제거된 field name / number 재사용 금지 정책을 OpenAPI `x-removed-fields` extension 또는 markdown 카탈로그로 정의 (status: `needs-confirmation`) | `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C2` (Protobuf field number 재사용 금지 표준), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C3` (reserved 필수), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C4` (재사용 시 risk catalog: 디버깅 손실 / parse error / PII 누출 / 데이터 손상), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C5` (JSON encoding 에서 field name 재사용 위험), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C1`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C2`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C5` (OpenAPI `x-` extension 메커니즘 — 정책 자체는 자체 lint 필요), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C6` (JSON Schema `deprecated` 가 재사용 차단 아님) | `official-standard` (Protobuf + OpenAPI + JSON Schema) | `PRVJ-C5` Does-not-prove: `x-removed-fields` 같은 특정 확장이 표준이 아님 — 자체 lint 작성 필요. 도구 선택 자체는 코드 단계 (status `needs-confirmation`) |"},"proof_manifest":null,"rationale":"Both are 'forbids' decisions but distinct: SA-13 (D4) forbids unknown request / undeclared response fields; SA-15 (D6) forbids reuse of removed field names/numbers. Different properties, no mutual exclusion.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-EDCD7FC1D63F892B9A08","evidence_a":{"line_end":176,"line_start":176,"quote":"| D4 | request unknown JSON field = fail-fast, response = schema 에 없는 public field 노출 금지 | `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C1` (Jackson 2.13 default = `FAIL_ON_UNKNOWN_PROPERTIES=true` enabled), `raw/official-docs/schema-jackson-unknown-field-handling.md#SJUF-C4` (`READ_UNKNOWN_ENUM_VALUES_AS_NULL` default disabled — 정합), `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2` (Avro 는 반대로 unknown 자동 ignore — 대조 근거) | `official-vendor-doc` (Jackson) + `official-standard` (Avro 대조) | response 측 \"schema 없는 field 노출 금지\" 는 Jackson 만으로 자동 강제 불가 — OpenAPI drift 검증 필요 (`SJUF-C1` Does-not-prove). Avro / Protobuf 모델과 ca-tmpl 결정이 반대 방향임을 보존 |"},"evidence_b":{"line_end":179,"line_start":179,"quote":"| D7 (대안 비교) | Avro Schema Registry 채택은 outbox/event 한정 검토 가치 — REST/JSON 외부 API 는 JSON 유지 | `raw/official-docs/schema-avro-evolution-rules.md#SAER-C1`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C3`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C4` (Avro 의 4 schema resolution 규칙) | `official-standard` | Avro backward/forward/full compatibility **level enforcement** 정의 인용 미확보 (raw 의 \"미확인 / 후속 확인 필요\" 섹션 명시) — 본문 §외부 근거의 \"자동 검사\" 표현은 4 resolution 규칙 확인분만 근거, compatibility level 자동 enforcement 는 Confluent Schema Registry 별도 fetch 필요 |"},"proof_manifest":null,"rationale":"SA-13 (D4 unknown-field handling) and SA-16 (D7 Avro for outbox/event) are independent decisions over different scopes. Compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-3B4263CD28CBFFEFE76C","evidence_a":{"line_end":177,"line_start":177,"quote":"| D5 | OpenAPI drift 집행권 = verification suite. 본 branch 는 serialization producer | (sibling branch `feature-api-contract-baseline` 와 책임 분담; 외부 raw 직접 근거 없음. 해당 sibling branch 의 OpenAPI drift gate Decision 에 의존 — §엣지·실패·의존 참조) | UNSUPPORTED_DECISION | sibling branch governance. **sibling branch 미작성/미착수 시 D4 의 response-side \"schema 없는 field 미노출\" 강제는 본 branch 완료 후에도 미보증 상태** — sibling status + 대응 Decision ID 확인 필요 |"},"evidence_b":{"line_end":230,"line_start":230,"quote":"> - **OpenAPI drift 집행 메커니즘** (D5): 집행권은 verification suite 소유. 본 branch 는 serialization producer 일 뿐 — drift gate 의 CI 구현 detail 은 sibling `feature-api-contract-baseline` 로 이관."},"proof_manifest":null,"rationale":"SA-14 and SA-25 both state D5 (drift enforcement authority = verification suite, this branch = serialization producer). SA-25 adds the compatible detail that drift-gate CI implementation transfers to sibling feature-api-contract-baseline. Same direction preserved; added detail, no meaning drift.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-DDFBE815F9B98201763E","evidence_a":{"line_end":178,"line_start":178,"quote":"| D6 | 제거된 field name / number 재사용 금지 정책을 OpenAPI `x-removed-fields` extension 또는 markdown 카탈로그로 정의 (status: `needs-confirmation`) | `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C2` (Protobuf field number 재사용 금지 표준), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C3` (reserved 필수), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C4` (재사용 시 risk catalog: 디버깅 손실 / parse error / PII 누출 / 데이터 손상), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C5` (JSON encoding 에서 field name 재사용 위험), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C1`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C2`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C5` (OpenAPI `x-` extension 메커니즘 — 정책 자체는 자체 lint 필요), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C6` (JSON Schema `deprecated` 가 재사용 차단 아님) | `official-standard` (Protobuf + OpenAPI + JSON Schema) | `PRVJ-C5` Does-not-prove: `x-removed-fields` 같은 특정 확장이 표준이 아님 — 자체 lint 작성 필요. 도구 선택 자체는 코드 단계 (status `needs-confirmation`) |"},"evidence_b":{"line_end":179,"line_start":179,"quote":"| D7 (대안 비교) | Avro Schema Registry 채택은 outbox/event 한정 검토 가치 — REST/JSON 외부 API 는 JSON 유지 | `raw/official-docs/schema-avro-evolution-rules.md#SAER-C1`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C3`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C4` (Avro 의 4 schema resolution 규칙) | `official-standard` | Avro backward/forward/full compatibility **level enforcement** 정의 인용 미확보 (raw 의 \"미확인 / 후속 확인 필요\" 섹션 명시) — 본문 §외부 근거의 \"자동 검사\" 표현은 4 resolution 규칙 확인분만 근거, compatibility level 자동 enforcement 는 Confluent Schema Registry 별도 fetch 필요 |"},"proof_manifest":null,"rationale":"SA-15 (D6 removed-field reuse ban) and SA-16 (D7 Avro for outbox/event) are separate decisions over unrelated concerns. Compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-8A91076B0B2C3306EAA5","evidence_a":{"line_end":178,"line_start":178,"quote":"| D6 | 제거된 field name / number 재사용 금지 정책을 OpenAPI `x-removed-fields` extension 또는 markdown 카탈로그로 정의 (status: `needs-confirmation`) | `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C2` (Protobuf field number 재사용 금지 표준), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C3` (reserved 필수), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C4` (재사용 시 risk catalog: 디버깅 손실 / parse error / PII 누출 / 데이터 손상), `raw/official-docs/schema-protobuf-vs-json-evolution.md#SPVJ-C5` (JSON encoding 에서 field name 재사용 위험), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C1`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C2`, `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C5` (OpenAPI `x-` extension 메커니즘 — 정책 자체는 자체 lint 필요), `raw/official-docs/protobuf-reserved-vs-json-openapi-extension.md#PRVJ-C6` (JSON Schema `deprecated` 가 재사용 차단 아님) | `official-standard` (Protobuf + OpenAPI + JSON Schema) | `PRVJ-C5` Does-not-prove: `x-removed-fields` 같은 특정 확장이 표준이 아님 — 자체 lint 작성 필요. 도구 선택 자체는 코드 단계 (status `needs-confirmation`) |"},"evidence_b":{"line_end":247,"line_start":247,"quote":" - [[raw/branch-notes/feature-api-compatibility-deprecation-contract]] — response field rename/versioning + 제거 field 재사용 정책(D6) 의 실제 도구가 여기서 확정되면 본 branch 의 `needs-confirmation` 해소."},"proof_manifest":null,"rationale":"SA-15 states D6 (needs-confirmation) policy; SA-21 says the actual D6 tool is confirmed in sibling feature-api-compatibility-deprecation-contract, resolving that needs-confirmation. Delegation supplies where the open tool decision closes; compatible, precedence is stated (sibling).","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-1990187A8CF0F65FE087","evidence_a":{"line_end":179,"line_start":179,"quote":"| D7 (대안 비교) | Avro Schema Registry 채택은 outbox/event 한정 검토 가치 — REST/JSON 외부 API 는 JSON 유지 | `raw/official-docs/schema-avro-evolution-rules.md#SAER-C1`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C2`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C3`, `raw/official-docs/schema-avro-evolution-rules.md#SAER-C4` (Avro 의 4 schema resolution 규칙) | `official-standard` | Avro backward/forward/full compatibility **level enforcement** 정의 인용 미확보 (raw 의 \"미확인 / 후속 확인 필요\" 섹션 명시) — 본문 §외부 근거의 \"자동 검사\" 표현은 4 resolution 규칙 확인분만 근거, compatibility level 자동 enforcement 는 Confluent Schema Registry 별도 fetch 필요 |"},"evidence_b":{"line_end":233,"line_start":233,"quote":"> - **Avro Schema Registry 채택** (D7): outbox/event 한정 별도 검토. 외부 REST/JSON 은 JSON 유지. Confluent compatibility enforcement 메커니즘 미확보."},"proof_manifest":null,"rationale":"SA-16 and SA-27 both state D7 (Avro Schema Registry limited to outbox/event, external REST/JSON stays JSON). SA-27 adds the compatible caveat that Confluent compatibility enforcement is not yet secured. Same scope, added detail, no drift.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-141A1BE4635D6865657C","evidence_a":{"line_end":243,"line_start":243,"quote":" - **`JavaTimeModule` 미등록**: `jackson-datatype-jsr310` 의존성 누락 또는 module 등록 누락 시 `LocalDateTime` 이 `[2026, 5, 21, 10, 30]` 배열로 직렬화되어 RFC 3339 계약 위반이 런타임에서야 발견됨 — `WRITE_DATES_AS_TIMESTAMPS=false` 단독으로는 불충분, `ObjectMapper.registerModule(new JavaTimeModule())`(또는 Spring Boot auto-config 의존성) 까지 필요."},"evidence_b":{"line_end":201,"line_start":201,"quote":"| datetime 직렬화 | ISO-8601 | `WRITE_DATES_AS_TIMESTAMPS=false` + `JavaTimeModule` | D2 / RFC3339-C4,C7 |"},"proof_manifest":null,"rationale":"SA-23 gives the datetime ObjectMapper config (WRITE_DATES_AS_TIMESTAMPS=false + JavaTimeModule); SA-19 supplies the compatible failure-mode detail (module non-registration serializes LocalDateTime as an array, so the flag alone is insufficient). Same requirement, complementary detail.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C2DFCBA96EF024AA29EC","evidence_a":{"line_end":247,"line_start":247,"quote":" - [[raw/branch-notes/feature-api-compatibility-deprecation-contract]] — response field rename/versioning + 제거 field 재사용 정책(D6) 의 실제 도구가 여기서 확정되면 본 branch 의 `needs-confirmation` 해소."},"evidence_b":{"line_end":86,"line_start":86,"quote":"- response field rename/versioning 기준."},"proof_manifest":null,"rationale":"SA-31 lists 'response field rename/versioning 기준' as an in-scope concern; SA-21 delegates the actual tool for it to sibling feature-api-compatibility-deprecation-contract. Owns-as-listed-concern (criteria) vs tool delegated to a sibling is a producer/enforcer split, coexisting; precedence for the tool is stated. Not a contradiction.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-F5783B29F5F524D070A8","evidence_a":{"line_end":225,"line_start":225,"quote":"> - **레이어 경계**: null/empty/missing 분리 책임은 **역직렬화 직후 ~ 유효성 검증 이전의 web inbound mapper 계층** 이 소유 (Controller DTO → Command/Query 변환 시점). Domain Service 는 이미 분리된 3-상태를 받음 — Domain 에서 재분리하지 않음."},"evidence_b":{"line_end":84,"line_start":84,"quote":"- null/empty/missing field 의미 구분."},"proof_manifest":null,"rationale":"SA-30 lists null/empty/missing distinction as an in-scope branch concern; SA-24 refines that the web inbound mapper layer (post-deserialization, pre-validation) owns the responsibility. Branch-scope vs implementation-layer granularity; they agree the concern is handled here, SA-24 supplies the layer detail.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-139AD622A7BF51079F86","evidence_a":{"line_end":81,"line_start":81,"quote":"- date/time/timezone serialization 기준."},"evidence_b":{"line_end":82,"line_start":82,"quote":"- BigDecimal/money scale/rounding 기준."},"proof_manifest":null,"rationale":"SA-28 (owns date/time/timezone serialization criteria) and SA-29 (owns BigDecimal/money scale/rounding criteria) are distinct concerns jointly composing the branch's included scope. Different owned objects, no single-owner conflict.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-EE3B48CF6E9DC73C0299","evidence_a":{"line_end":81,"line_start":81,"quote":"- date/time/timezone serialization 기준."},"evidence_b":{"line_end":84,"line_start":84,"quote":"- null/empty/missing field 의미 구분."},"proof_manifest":null,"rationale":"SA-28 (date/time serialization) and SA-30 (null/empty/missing distinction) are separate in-scope concerns owned by the branch. Different objects; compatible scope-list members.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-2ADFB6B2EC768455C6A3","evidence_a":{"line_end":81,"line_start":81,"quote":"- date/time/timezone serialization 기준."},"evidence_b":{"line_end":86,"line_start":86,"quote":"- response field rename/versioning 기준."},"proof_manifest":null,"rationale":"SA-28 (date/time serialization) and SA-31 (response field rename/versioning criteria) are distinct in-scope concerns. Different owned objects; no mutual exclusion.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C933DD74F96302AA4FC5","evidence_a":{"line_end":81,"line_start":81,"quote":"- date/time/timezone serialization 기준."},"evidence_b":{"line_end":87,"line_start":87,"quote":"- OpenAPI schema drift 검증."},"proof_manifest":null,"rationale":"SA-28 (date/time serialization) and SA-32 (OpenAPI schema drift verification) are separate in-scope concerns owned by the branch. Different objects; compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-A2EB9C27F5D8A4421758","evidence_a":{"line_end":82,"line_start":82,"quote":"- BigDecimal/money scale/rounding 기준."},"evidence_b":{"line_end":84,"line_start":84,"quote":"- null/empty/missing field 의미 구분."},"proof_manifest":null,"rationale":"SA-29 (BigDecimal/money) and SA-30 (null/empty/missing) are distinct in-scope concerns. Different owned objects; no single-owner conflict.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C6EE3F32F1BC4C747867","evidence_a":{"line_end":82,"line_start":82,"quote":"- BigDecimal/money scale/rounding 기준."},"evidence_b":{"line_end":86,"line_start":86,"quote":"- response field rename/versioning 기준."},"proof_manifest":null,"rationale":"SA-29 (BigDecimal/money) and SA-31 (response field rename/versioning criteria) are separate in-scope concerns. Different objects; compatible scope-list members.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-B2ED4C05EEBF63533B70","evidence_a":{"line_end":82,"line_start":82,"quote":"- BigDecimal/money scale/rounding 기준."},"evidence_b":{"line_end":87,"line_start":87,"quote":"- OpenAPI schema drift 검증."},"proof_manifest":null,"rationale":"SA-29 (BigDecimal/money) and SA-32 (OpenAPI schema drift verification) are distinct in-scope concerns. Different owned objects; no conflict.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-F85B6266104254821301","evidence_a":{"line_end":84,"line_start":84,"quote":"- null/empty/missing field 의미 구분."},"evidence_b":{"line_end":86,"line_start":86,"quote":"- response field rename/versioning 기준."},"proof_manifest":null,"rationale":"SA-30 (null/empty/missing) and SA-31 (response field rename/versioning criteria) are separate in-scope concerns. Different objects; compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-6650D8D88703F7C14FCA","evidence_a":{"line_end":84,"line_start":84,"quote":"- null/empty/missing field 의미 구분."},"evidence_b":{"line_end":87,"line_start":87,"quote":"- OpenAPI schema drift 검증."},"proof_manifest":null,"rationale":"SA-30 (null/empty/missing) and SA-32 (OpenAPI schema drift verification) are distinct in-scope concerns owned by the branch. Different objects; no mutual exclusion.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-29051E605805972E6310","evidence_a":{"line_end":86,"line_start":86,"quote":"- response field rename/versioning 기준."},"evidence_b":{"line_end":87,"line_start":87,"quote":"- OpenAPI schema drift 검증."},"proof_manifest":null,"rationale":"SA-31 (response field rename/versioning criteria) and SA-32 (OpenAPI schema drift verification) are separate in-scope concerns. Different owned objects; compatible scope-list members.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-60C88D7664D4ECEA3CEB","evidence_a":{"line_end":91,"line_start":91,"quote":"- domain-specific schema."},"evidence_b":{"line_end":93,"line_start":93,"quote":"- public API deprecation policy."},"proof_manifest":null,"rationale":"SA-33 (domain-specific schema) and SA-34 (public API deprecation policy) are two distinct out-of-scope exclusions. Different objects both excluded; no conflict.","verdict":"COMPLEMENTARY"}]},"auditor":{"contract_version":"semantic-coherence/v1","model_id":"claude-opus-4-8","run_id":"a40778d63720cd461"},"auditor_contract_sha256":"1cbc67c27e5183a272687f635e3682a26d56785a1cf144da562eb7edd8f6cbce","coverage":{"candidate_pairs":40,"dropped_pairs":0,"eligible_surfaces":6,"processed_pairs":40,"processed_surfaces":6},"document_id":"2703a7c6e4b30861dcc31a7b4ba83bac1d7b207f4f621a91c4b25d05fde4ba64","document_sha256":"36d5371e9609dbeb6b9f2ec22d0a0979a8902896d3b6c7845447fee4234cb563","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":"395b2ef54e5521fee165249a8ffa28e41a610b1041e22111a6721d8bb400b679","subject":"raw/branch-notes/feature-schema-serialization-contract.md","typed_contract_graph_sha256":"481fc3335a494c454ab13ad1d6a6ddccdec99aa8e083f6720ff8886bfa19cc89","verdict":"PASS"}
|