Files
llm-wiki/harness/state/semantic-certificates/bf81339af7b1675cacfced0cb921ca3d9ddfcb5a5d3ad20b5643432036d705cb/0bceff0596ad4407a633b3c73905f8ead3d9260b57a444cb8aa150f15dc8c0bf.json
T

2 lines
128 KiB
JSON

{"audit_request":{"assertions":[{"assertion_id":"A01","condition":"unconditional","line_end":59,"line_start":59,"modality":"must","object":"지원 protocol과 timeout·failure contract test가 고정되어야 완료","predicate":"requires","quote":"- **완료 조건**: 지원 protocol과 timeout·failure contract test가 고정된다","scope":"브랜치 완료 조건","source_surface":"SURF-D66F11F8C886D0188D67","subject":"feature-streaming-response-contract branch"},{"assertion_id":"A02","condition":"unconditional","line_end":58,"line_start":58,"modality":"observed","object":"contract_packet: 1","predicate":"has_schema","quote":"- **패킷 스키마**: `contract_packet: 1`","scope":"계약 패킷 스키마","source_surface":"SURF-D66F11F8C886D0188D67","subject":"branch contract packet"},{"assertion_id":"A03","condition":"Work Item 완료 조건에 적용","line_end":66,"line_start":66,"modality":"must","object":"DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1 (URI prefix /v1 default, X-Api-Version compatibility 보조 header)","predicate":"uses","quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1` | URI prefix /v1이 default이며 X-Api-Version은 compatibility 실험용 보조 header다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |","scope":"상속한 프로젝트 결정","source_surface":"SURF-D66F11F8C886D0188D67","subject":"feature-streaming-response-contract branch"},{"assertion_id":"A04","condition":"Work Item 완료 조건에 적용","line_end":67,"line_start":67,"modality":"must","object":"DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1 (Resilience4j default, Spring Retry는 simple blocking retry에만)","predicate":"uses","quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1` | Resilience4j가 default이며 Spring Retry는 simple blocking retry에만 허용한다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |","scope":"상속한 프로젝트 결정","source_surface":"SURF-D66F11F8C886D0188D67","subject":"feature-streaming-response-contract branch"},{"assertion_id":"A05","condition":"unconditional","line_end":72,"line_start":72,"modality":"must","object":"Decision Evidence Map / 결정-근거 매핑의 D-row가 branch-local 결정을 소유; packet에서 복제하지 않음","predicate":"delegates","quote":"> 기존 branch-local 결정은 아래 `## Decision Evidence Map / 결정-근거 매핑`의 D-row가 소유하며 이 packet에서 복제하지 않는다.","scope":"branch-local 결정 소유권","source_surface":"SURF-D66F11F8C886D0188D67","subject":"branch contract packet branch-local decisions"},{"assertion_id":"A06","condition":"build 단계","line_end":250,"line_start":250,"modality":"observed","object":"production 코드의 SseEmitter·ResponseBodyEmitter import (build 단계 차단, fixtures GREEN)","predicate":"forbids","quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |","scope":"production 코드","source_surface":"SURF-BFDBF6667826F8F5004D","subject":"no_sse_emitter / no_response_body_emitter"},{"assertion_id":"A07","condition":"unconditional","line_end":251,"line_start":251,"modality":"observed","object":"org.springframework.web.socket.. + jakarta.websocket.. glob — WebSocket 표면만 차단 (over-block 없음)","predicate":"forbids","quote":"| `no_websocket_handler` 의 `org.springframework.web.socket..` + `jakarta.websocket..` glob 이 정확히 WebSocket 표면만 차단 (over-block 없음) | 패키지 glob 범위가 vendor 패키지 구조에 의존 | `SpringWebSocketHandlerFixture` (`@EnableWebSocket`), `JakartaWebSocketEndpointFixture` (`@ServerEndpoint`) fixtures → FixtureTest GREEN | `locally-verified` (2026-06-02) |","scope":"WebSocket 표면","source_surface":"SURF-BFDBF6667826F8F5004D","subject":"no_websocket_handler"},{"assertion_id":"A08","condition":"unconditional","line_end":252,"line_start":252,"modality":"must_not","object":"StreamingResponseBody (file-resource D8 다운로드) — 차단되지 않음, over-block guard GREEN","predicate":"forbids","quote":"| `StreamingResponseBody` 가 rule 에 걸리지 않아 file-resource D8 다운로드가 정상 build | blanket ban 시 false positive 위험 (핵심 회귀) | `StreamingResponseBodyAllowedFixture` over-block guard → 3개 D3 rule 모두 `hasViolation() == false` — GREEN | `locally-verified` (2026-06-02) |","scope":"file-resource D8 다운로드","source_surface":"SURF-BFDBF6667826F8F5004D","subject":"3개 D3 rule"},{"assertion_id":"A09","condition":"unconditional","line_end":253,"line_start":253,"modality":"observed","object":"3개 rule 등록이 기존 suite 와 충돌 없음 (CleanArchitectureTest 33 tests, 0 failures)","predicate":"validates","quote":"| ArchUnit suite host(boundary branch) 에 3개 rule 등록이 기존 suite 와 충돌 없음 | suite 구조·rule 명명 충돌 가능 | `CleanArchitectureTest` 33 tests (기존 30 + D3 3) — 0 failures | `locally-verified` (2026-06-02) |","scope":"ArchUnit suite host","source_surface":"SURF-BFDBF6667826F8F5004D","subject":"ArchUnit suite host (boundary branch)"},{"assertion_id":"A10","condition":"request-response only","line_end":188,"line_start":188,"modality":"must_not","object":"이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정","predicate":"forbids","quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |","scope":"이벤트/server-push 스트리밍","source_surface":"SURF-0D16DAE3B9DC1D8348AA","subject":"D1"},{"assertion_id":"A11","condition":"IN-SCOPE","line_end":189,"line_start":189,"modality":"must","object":"D1 을 ArchUnit import-ban 으로 정적 강제 (no_sse_emitter / no_response_body_emitter / no_websocket_handler)","predicate":"enforces","quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |","scope":"ArchUnit 정적 강제","source_surface":"SURF-0D16DAE3B9DC1D8348AA","subject":"D3"},{"assertion_id":"A12","condition":"재개 트리거 전까지 dormant","line_end":190,"line_start":190,"modality":"unknown","object":"이벤트 스트리밍 지원 계약(매커니즘/envelope/per-event span/timeout/cap/proxy) = 보류 (Deferred)","predicate":"other","quote":"| D2 | 이벤트 스트리밍 *지원* 계약(매커니즘/envelope/per-event span/timeout/cap/proxy) = 보류 (Deferred) | `WHATWG-SSE-C1~C6`, `RFC6455-C1~C6`, `RFC9112-CHUNK-C1~C5`, `SPRING-ASYNC-C1~C7`, `WOOWA-SSE-C1~C6`, `WOOWA-WS-C1~C5` (재개 시 재조사 불필요하게 보존) | `official-standard` + `official-vendor-doc` + `company-case-study` | 재개 트리거 전까지 dormant. 아래 OPEN 갭(per-event span) 동반 |","scope":"지원 계약","source_surface":"SURF-0D16DAE3B9DC1D8348AA","subject":"D2"},{"assertion_id":"A13","condition":"D3 의존 활성","line_end":194,"line_start":194,"modality":"must","object":"ArchUnit suite host = feature-boundary-validation-mapping-contract D5 (import-ban 선례), archunit-junit5 1.3.0 (project §34)","predicate":"uses","quote":"> - **(D3 의존, 활성)** ArchUnit suite **host = [[raw/branch-notes/feature-boundary-validation-mapping-contract]]** (D5 import-ban 선례). 본 branch 의 3개 rule 은 그 suite 에 등록. archunit-junit5 1.3.0 (project §34). suite 구조가 바뀌면 본 branch rule 영향.","scope":"교차 계약 의존","source_surface":"SURF-0D16DAE3B9DC1D8348AA","subject":"본 branch 3개 rule"},{"assertion_id":"A14","condition":"server-push 미지원 시","line_end":195,"line_start":195,"modality":"must","object":"feature-api-contract-baseline D17 (verified LRO: 202 + Location + polling endpoint + Retry-After)","predicate":"delegates","quote":"> - **(폴링 대안, 닫힘)** server-push 미지원 시 비동기 응답 우회 = [[raw/branch-notes/feature-api-contract-baseline]] **D17** (verified LRO: 202 + `Location` + polling endpoint + `Retry-After`). webhook 우회는 [[raw/branch-notes/feature-webhook-outbound-contract]] 가 미결정(forward-ref) + 동 branch 가 SSE 대체를 *본 branch* 로 역참조 → 상호 보류.","scope":"폴링 대안","source_surface":"SURF-0D16DAE3B9DC1D8348AA","subject":"server-push 미지원 우회"},{"assertion_id":"A15","condition":"unconditional","line_end":196,"line_start":196,"modality":"must","object":"feature-file-resource-handling-contract D8 (verified, 다운로드 메커니즘) 소유 → 차단 안 함","predicate":"delegates","quote":"> - **(D3 경계, OUT_OF_BRANCH_SCOPE)** `StreamingResponseBody` 는 [[raw/branch-notes/feature-file-resource-handling-contract]] D8 (verified, 다운로드 메커니즘) 소유 → 차단 안 함. blanket ban 시 파일 다운로드 build 실패하므로 명시적 제외.","scope":"D3 경계 OUT_OF_BRANCH_SCOPE","source_surface":"SURF-0D16DAE3B9DC1D8348AA","subject":"StreamingResponseBody"},{"assertion_id":"A16","condition":"D2 재개 시 tracing branch 와 동시 결정","line_end":197,"line_start":197,"modality":"unknown","object":"feature-distributed-tracing-contract D5/D7 은 traceparent 를 request 단위로 전파, long-lived streaming connection 없음 — 진짜 OPEN 갭","predicate":"other","quote":"> - **(D2 동반 OPEN, 미해결)** per-event trace span: [[raw/branch-notes/feature-distributed-tracing-contract]] D5/D7 은 traceparent 를 *request 단위* 로 전파하나 propagation surface(outbound HTTP/Kafka/Rabbit/scheduler)에 **long-lived streaming connection 없음**. \"한 connection 의 N개 event 에 traceId 를 어떻게\" 는 기존 Decision ID 로 닫히지 않는 진짜 OPEN 갭 — D2 재개 시 tracing branch 와 동시 결정 필요.","scope":"D2 동반 OPEN","source_surface":"SURF-0D16DAE3B9DC1D8348AA","subject":"per-event trace span"},{"assertion_id":"A17","condition":"rule glob 이 너무 넓으면 false positive","line_end":236,"line_start":236,"modality":"must_not","object":"StreamingResponseBody 를 rule 대상 FQN 목록에 포함(차단) — 기대: 포함하지 않음, 차단되면 안 됨","predicate":"forbids","quote":" - **false positive — `StreamingResponseBody` 오차단**: rule glob 이 너무 넓으면 file-resource D8 다운로드가 깨짐. 기대 동작 = `StreamingResponseBody` 는 rule 대상 FQN 목록에 *포함하지 않음* (§구현 가이드 명시적 비-차단). 차단되면 안 됨.","scope":"file-resource D8 다운로드","source_surface":"SURF-7A2F88DED6FB8C79DFFE","subject":"D3 차단 rule glob"},{"assertion_id":"A18","condition":"transitive dependency","line_end":237,"line_start":237,"modality":"observed","object":"transitive import 도 잡아 제3 라이브러리의 SseEmitter 참조가 false positive 가능 — 기대: production source 직접 의존만 위반","predicate":"has_failure_behavior","quote":" - **transitive dependency 차단**: `dependOnClassesThat()` 는 transitive import 도 잡으므로, 제3 라이브러리가 내부적으로 `SseEmitter` 를 참조하면 false positive 가능. 기대 동작 = production source 의 *직접* 의존만 위반으로 본다 (필요 시 `ImportOption` 으로 vendor 패키지 제외 — UNSUPPORTED_IMPL_DECISION). 해소 선례: [[raw/branch-notes/feature-boundary-validation-mapping-contract]] §구현 가이드 §8 `no_problem_detail_usage` 의 import-level 차단 trade-off 참조.","scope":"production source 직접 의존","source_surface":"SURF-7A2F88DED6FB8C79DFFE","subject":"D3 차단 rule (dependOnClassesThat)"},{"assertion_id":"A19","condition":"WebSocket 미사용이 default","line_end":238,"line_start":238,"modality":"must","object":"WebSocket 패키지 전체(하위 유틸 포함) — 전체 차단이 안전, 도입 시 rule 해제","predicate":"forbids","quote":" - **WebSocket 패키지 glob 과다**: `org.springframework.web.socket..` 전체 차단이 의도치 않은 하위 유틸까지 막을 수 있음. 기대 동작 = WebSocket 미사용이 default 이므로 전체 차단이 안전, 도입 시 rule 해제.","scope":"WebSocket 패키지 glob","source_surface":"SURF-7A2F88DED6FB8C79DFFE","subject":"no_websocket_handler (org.springframework.web.socket.. 전체)"},{"assertion_id":"A20","condition":"차단 위반 재현 fixture 는 test 에 존재","line_end":239,"line_start":239,"modality":"must","object":"rule scope = DoNotIncludeTests (production만)","predicate":"enforces","quote":" - **테스트 코드**: 차단 위반 재현 fixture 는 test 에 있어야 하므로 rule scope = `DoNotIncludeTests` (production만).","scope":"rule scope","source_surface":"SURF-7A2F88DED6FB8C79DFFE","subject":"D3 rule"},{"assertion_id":"A21","condition":"suite 구조·버전 변경 시 영향","line_end":241,"line_start":241,"modality":"must","object":"feature-boundary-validation-mapping-contract D5 / ArchUnit suite host (archunit-junit5 1.3.0, project §34)","predicate":"uses","quote":" - [[raw/branch-notes/feature-boundary-validation-mapping-contract]] **D5 / ArchUnit suite host** 에 의존 — 본 branch 3개 rule 을 그 suite 에 등록. suite 구조·archunit-junit5 버전(project §34, 1.3.0)이 바뀌면 본 branch 영향.","scope":"다른 계약 의존","source_surface":"SURF-7A2F88DED6FB8C79DFFE","subject":"본 branch 3개 rule"},{"assertion_id":"A22","condition":"D17 계약 변경 시 §구현 가이드 §2 갱신","line_end":242,"line_start":242,"modality":"must","object":"feature-api-contract-baseline D17 (미지원 시 비동기 우회 = LRO polling)","predicate":"consumes","quote":" - [[raw/branch-notes/feature-api-contract-baseline]] **D17** consume (미지원 시 비동기 우회 = LRO polling). D17 계약이 바뀌면 본 branch §구현 가이드 §2 대안 경로 갱신 필요.","scope":"다른 계약 의존","source_surface":"SURF-7A2F88DED6FB8C79DFFE","subject":"feature-streaming-response-contract branch"},{"assertion_id":"A23","condition":"D8 이 다른 streaming 클래스 도입 시 비-차단 목록 재검토","line_end":243,"line_start":243,"modality":"must","object":"feature-file-resource-handling-contract D8 과 경계 공유","predicate":"delegates","quote":" - [[raw/branch-notes/feature-file-resource-handling-contract]] **D8** 과 경계 공유 — `StreamingResponseBody` 소유권. D8 이 다른 streaming 클래스를 쓰기 시작하면 본 branch 비-차단 목록 재검토.","scope":"다른 계약 의존","source_surface":"SURF-7A2F88DED6FB8C79DFFE","subject":"StreamingResponseBody 소유권"},{"assertion_id":"A24","condition":"D2 재개 시 동시 결정","line_end":244,"line_start":244,"modality":"unknown","object":"feature-distributed-tracing-contract D5/D7 — long-lived connection per-event trace span 정책 미존재 (OPEN)","predicate":"other","quote":"- **D2 보류분 OPEN 의존 (재개 시)**: [[raw/branch-notes/feature-distributed-tracing-contract]] D5/D7 — long-lived connection 의 per-event trace span 정책 미존재. 재개 시 동시 결정 필요.","scope":"D2 보류 OPEN 의존","source_surface":"SURF-7A2F88DED6FB8C79DFFE","subject":"D2 보류분 per-event trace span"},{"assertion_id":"A25","condition":"unconditional","line_end":216,"line_start":216,"modality":"must","object":"org.springframework.web.servlet.mvc.method.annotation.SseEmitter (noClasses().should().dependOnClassesThat().haveFullyQualifiedName)","predicate":"forbids","quote":"| `no_sse_emitter` | `org.springframework.web.servlet.mvc.method.annotation.SseEmitter` | `noClasses().should().dependOnClassesThat().haveFullyQualifiedName(...)` | SSE server-push 의 직접 표면 (`SPRING-ASYNC-C4`) |","scope":"production import (D3)","source_surface":"SURF-85D2E8543C274F5601E5","subject":"no_sse_emitter"},{"assertion_id":"A26","condition":"unconditional","line_end":217,"line_start":217,"modality":"must","object":"org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter (SSE base + incremental 객체 emit; SseEmitter 가 상속)","predicate":"forbids","quote":"| `no_response_body_emitter` | `org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter` | 동일 | SSE 의 base + incremental 객체 emit (`SPRING-ASYNC-C3`). `SseEmitter` 가 이를 상속하므로 함께 차단. **비-SSE JSON object-stream 용도까지 server-push 모델로 간주해 차단** (`UNSUPPORTED_IMPL_DECISION④`) |","scope":"production import (D3)","source_surface":"SURF-85D2E8543C274F5601E5","subject":"no_response_body_emitter"},{"assertion_id":"A27","condition":"unconditional","line_end":218,"line_start":218,"modality":"must","object":"org.springframework.web.socket.. (패키지 전체) + jakarta.websocket.. (패키지 전체) via resideInAnyPackage","predicate":"forbids","quote":"| `no_websocket_handler` | `org.springframework.web.socket..` (패키지 전체) + `jakarta.websocket..` (패키지 전체) | `dependOnClassesThat().resideInAnyPackage(...)` | spring-websocket(`WebSocketHandler`, `@EnableWebSocket`, `@EnableWebSocketMessageBroker`/STOMP) + Jakarta `@ServerEndpoint` 계열 일괄 차단 (`RFC6455-C1` full-duplex 모델). **WebSocket 표면은 단일 FQN 이 없어 `haveFullyQualifiedName` 대신 `resideInAnyPackage` glob 불가피** (`UNSUPPORTED_IMPL_DECISION③`) |","scope":"production import (D3)","source_surface":"SURF-85D2E8543C274F5601E5","subject":"no_websocket_handler"},{"assertion_id":"A28","condition":"unconditional","line_end":221,"line_start":221,"modality":"must_not","object":"org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody — 차단하지 않음 (file-resource D8 소유, request-response 유지)","predicate":"forbids","quote":"- `org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody` — **차단하지 않음.** 대용량 다운로드용 응답 body 청크 전송 (`SPRING-ASYNC-C2`: \"for example, for a file download\"), 통신 모델은 request-response 유지. [[raw/branch-notes/feature-file-resource-handling-contract]] D8 (verified) 소유. blanket ban 시 다운로드 build 실패.","scope":"명시적 비-차단 OUT_OF_BRANCH_SCOPE","source_surface":"SURF-85D2E8543C274F5601E5","subject":"D3 rules"},{"assertion_id":"A29","condition":"ca-skeleton stack = spring-webmvc","line_end":222,"line_start":222,"modality":"observed","object":"WebFlux reactive 타입(Flux<ServerSentEvent> 등) — classpath 부재로 rule 불필요","predicate":"other","quote":"- WebFlux reactive 타입(`Flux<ServerSentEvent>` 등) — ca-skeleton stack 은 spring-webmvc(`SPRING-ASYNC-C1`/`C5` 의 servlet 전제)이므로 해당 클래스가 classpath 에 없음 → rule 불필요 (재개 시 WebFlux 전환하면 별도 검토).","scope":"명시적 비-차단","source_surface":"SURF-85D2E8543C274F5601E5","subject":"D3 rules"},{"assertion_id":"A30","condition":"테스트에서 차단 위반 재현 fixture 작성 허용","line_end":212,"line_start":212,"modality":"must","object":"차단 scope = production code only (ImportOption.DoNotIncludeTests)","predicate":"enforces","quote":"> - ⑤ **차단 scope = production code only** (`ImportOption.DoNotIncludeTests`) — 테스트에서 차단 위반 재현용 fixture 작성 가능하도록.","scope":"UNSUPPORTED_IMPL_DECISION⑤","source_surface":"SURF-85D2E8543C274F5601E5","subject":"D3 차단 rule"},{"assertion_id":"A31","condition":"비동기 결과 전달 필요 시","line_end":228,"line_start":228,"modality":"must","object":"feature-api-contract-baseline D17 LRO 패턴 (202 + Location + GET /operations/{id} polling + Retry-After)","predicate":"delegates","quote":"- 비동기 server→client 결과 전달이 필요하면: [[raw/branch-notes/feature-api-contract-baseline]] **D17** LRO 패턴 (202 + `Location` + `GET /operations/{id}` polling + `Retry-After`) 사용.","scope":"미지원 시 대안 경로","source_surface":"SURF-85D2E8543C274F5601E5","subject":"비동기 server→client 결과 전달"},{"assertion_id":"A32","condition":"외부 시스템 push 필요 시","line_end":229,"line_start":229,"modality":"may","object":"feature-webhook-outbound-contract (미결정, forward-ref)","predicate":"delegates","quote":"- 외부 시스템 push 가 필요하면: [[raw/branch-notes/feature-webhook-outbound-contract]] (미결정, forward-ref).","scope":"미지원 시 대안 경로","source_surface":"SURF-85D2E8543C274F5601E5","subject":"외부 시스템 push"},{"assertion_id":"A33","condition":"Trace D1→D3","line_end":205,"line_start":205,"modality":"must","object":"boundary branch ArchUnit suite host + archunit-junit5 1.3.0 (project §34); 차단 대상 클래스 정의 = SPRING-ASYNC-C4/C3; 메커니즘 선례 = boundary D5","predicate":"uses","quote":"> **Trace**: D1 (이벤트/server-push 스트리밍 미지원) → D3 (ArchUnit 정적 강제). 차단 대상 클래스 정의 = `SPRING-ASYNC-C4` (`SseEmitter` = `ResponseBodyEmitter` subclass, W3C SSE 포맷), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit). 메커니즘 선례 = [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (`no_problem_detail_usage` import-level 차단). suite host = boundary branch ArchUnit suite, archunit-junit5 1.3.0 (project §34).","scope":"구현 가이드 §1","source_surface":"SURF-85D2E8543C274F5601E5","subject":"D3 ArchUnit rules"},{"assertion_id":"A34","condition":"포함 범위 (결정 완료, 착수 가능)","line_end":112,"line_start":112,"modality":"must_not","object":"이벤트/server-push 스트리밍 지원 — D1: 미지원 확정","predicate":"forbids","quote":"- 이벤트/server-push 스트리밍 지원 여부 결정 → **D1: 미지원 확정**","scope":"포함 범위","source_surface":"SURF-AE680E31364F3865FCD9","subject":"feature-streaming-response-contract branch"},{"assertion_id":"A35","condition":"포함 범위 (결정 완료, 착수 가능)","line_end":113,"line_start":113,"modality":"must","object":"미지원의 ArchUnit 정적 강제 — D3: no_sse_emitter / no_response_body_emitter / no_websocket_handler","predicate":"enforces","quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)","scope":"포함 범위","source_surface":"SURF-AE680E31364F3865FCD9","subject":"feature-streaming-response-contract branch"},{"assertion_id":"A36","condition":"Deferred (보류)","line_end":117,"line_start":117,"modality":"may","object":"지원 결정 시 매커니즘 선택 (SSE / WebSocket / long-poll / chunked) — 재개 시 SSE 우선","predicate":"other","quote":"- 지원 결정 시 매커니즘 선택 (SSE / WebSocket / long-poll / chunked) — 재개 시 SSE 우선 (D2)","scope":"Deferred","source_surface":"SURF-AE680E31364F3865FCD9","subject":"D2 (지원 시 계약)"},{"assertion_id":"A37","condition":"Deferred (보류)","line_end":118,"line_start":118,"modality":"may","object":"지원 결정 시 event envelope shape + per-event trace context 전파 (tracing branch 와 OPEN)","predicate":"other","quote":"- 지원 결정 시 event envelope shape + per-event trace context 전파 (tracing branch 와 OPEN)","scope":"Deferred","source_surface":"SURF-AE680E31364F3865FCD9","subject":"D2 event envelope"},{"assertion_id":"A38","condition":"unconditional","line_end":125,"line_start":125,"modality":"must_not","object":"제외 — ca-skeleton 은 HTTP/REST default, gRPC 도입은 완전 별도 branch","predicate":"forbids","quote":"- gRPC streaming — ca-skeleton 은 HTTP/REST default, gRPC 도입은 완전 별도 branch","scope":"제외 범위","source_surface":"SURF-AE680E31364F3865FCD9","subject":"gRPC streaming"},{"assertion_id":"A39","condition":"unconditional","line_end":127,"line_start":127,"modality":"must","object":"feature-webhook-outbound-contract SSOT (제외 범위)","predicate":"delegates","quote":"- async webhook 발송 — [[raw/branch-notes/feature-webhook-outbound-contract]] SSOT","scope":"제외 범위","source_surface":"SURF-AE680E31364F3865FCD9","subject":"async webhook 발송"},{"assertion_id":"A40","condition":"unconditional","line_end":128,"line_start":128,"modality":"must","object":"feature-api-contract-baseline D17 SSOT (제외 범위)","predicate":"delegates","quote":"- async polling endpoint (LRO) — [[raw/branch-notes/feature-api-contract-baseline]] D17 SSOT","scope":"제외 범위","source_surface":"SURF-AE680E31364F3865FCD9","subject":"async polling endpoint (LRO)"}],"candidate_manifest_sha256":"a50021f8d2ce8f20bc2b377799dd9b5fa36e0c9081a6a62dbcc95a9bb09856c8","candidates":[{"assertion_a":"A01","assertion_b":"A03","candidate_id":"SEM-655ADD4228F7CAE9D047","grouping_key":{"condition":"","predicate":"","scope":"","subject":"feature-streaming-response-contract branch"},"rule_ids":["C3"]},{"assertion_a":"A01","assertion_b":"A04","candidate_id":"SEM-98369328CC7E7639F536","grouping_key":{"condition":"","predicate":"","scope":"","subject":"feature-streaming-response-contract branch"},"rule_ids":["C3"]},{"assertion_a":"A01","assertion_b":"A34","candidate_id":"SEM-70C845D1DEA19524BFED","grouping_key":{"condition":"","predicate":"","scope":"","subject":"feature-streaming-response-contract branch"},"rule_ids":["C3"]},{"assertion_a":"A01","assertion_b":"A35","candidate_id":"SEM-1468CFAA607BD1568591","grouping_key":{"condition":"","predicate":"","scope":"","subject":"feature-streaming-response-contract branch"},"rule_ids":["C3"]},{"assertion_a":"A03","assertion_b":"A04","candidate_id":"SEM-A2CC79B841E6525954A0","grouping_key":{"condition":"Work Item 완료 조건에 적용","predicate":"uses","scope":"상속한 프로젝트 결정","subject":"feature-streaming-response-contract branch"},"rule_ids":["BASE","C3","C6"]},{"assertion_a":"A03","assertion_b":"A11","candidate_id":"SEM-9A41EAA71D7E0B8ACB37","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A03","assertion_b":"A34","candidate_id":"SEM-B269103C2F80B849DC05","grouping_key":{"condition":"","predicate":"","scope":"","subject":"feature-streaming-response-contract branch"},"rule_ids":["C3"]},{"assertion_a":"A03","assertion_b":"A35","candidate_id":"SEM-6B36C631FB80E120AE11","grouping_key":{"condition":"","predicate":"","scope":"","subject":"feature-streaming-response-contract branch"},"rule_ids":["C3"]},{"assertion_a":"A04","assertion_b":"A11","candidate_id":"SEM-04539C33FC34CFB58E3C","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A04","assertion_b":"A34","candidate_id":"SEM-02155361E1C29DB88962","grouping_key":{"condition":"","predicate":"","scope":"","subject":"feature-streaming-response-contract branch"},"rule_ids":["C3"]},{"assertion_a":"A04","assertion_b":"A35","candidate_id":"SEM-1B697377B0E413CBB862","grouping_key":{"condition":"","predicate":"","scope":"","subject":"feature-streaming-response-contract branch"},"rule_ids":["C3"]},{"assertion_a":"A06","assertion_b":"A07","candidate_id":"SEM-93C419CAA2E267E7D86F","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A06","assertion_b":"A08","candidate_id":"SEM-89241A55BE0EE49EFDAE","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A06","assertion_b":"A09","candidate_id":"SEM-A12BBF997DD69FADBDD9","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A06","assertion_b":"A11","candidate_id":"SEM-F8234589BE503D3DFB9D","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A06","assertion_b":"A18","candidate_id":"SEM-A763D60D40F22256033A","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A06","assertion_b":"A25","candidate_id":"SEM-EE00D7A8DFD7760A2BC8","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A06","assertion_b":"A26","candidate_id":"SEM-C4B8319316262159E78D","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A06","assertion_b":"A33","candidate_id":"SEM-0605B5359B5A63A766BC","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A06","assertion_b":"A35","candidate_id":"SEM-1BA5873E64A1B4CB5EC8","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A07","assertion_b":"A08","candidate_id":"SEM-30FB86B3707B7F6197EB","grouping_key":{"condition":"unconditional","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A07","assertion_b":"A09","candidate_id":"SEM-B1917B6B4DF1E0458BE1","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A07","assertion_b":"A11","candidate_id":"SEM-E83955435337E7ED43DA","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A07","assertion_b":"A19","candidate_id":"SEM-3CFBEA109EA266D2730E","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A07","assertion_b":"A27","candidate_id":"SEM-A607497D134EE8457082","grouping_key":{"condition":"unconditional","predicate":"forbids","scope":"","subject":"no_websocket_handler"},"rule_ids":["C6"]},{"assertion_a":"A07","assertion_b":"A35","candidate_id":"SEM-02D3B1FCE33B5683D0BE","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A08","assertion_b":"A09","candidate_id":"SEM-AA592D614F3D40327A28","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A08","assertion_b":"A10","candidate_id":"SEM-3AF87FC3906856813907","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A08","assertion_b":"A15","candidate_id":"SEM-1D64524A2099A24F8C5C","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A08","assertion_b":"A17","candidate_id":"SEM-8B7E9F23F1729258919F","grouping_key":{"condition":"","predicate":"forbids","scope":"file-resource D8 다운로드","subject":""},"rule_ids":["C6"]},{"assertion_a":"A08","assertion_b":"A23","candidate_id":"SEM-F7016C9A81661F41DC39","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A11","candidate_id":"SEM-66F0C6353F85F47349BB","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A12","candidate_id":"SEM-7212CEF2ACD31B9B3BEF","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A14","candidate_id":"SEM-CE3F3160DCBBEA9D5DBA","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A15","candidate_id":"SEM-DAE5AAFA96B29558B508","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A17","candidate_id":"SEM-3347E971AD4073434507","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A22","candidate_id":"SEM-92C6FF19022D9B234E99","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A23","candidate_id":"SEM-1AE6F9D1089BE461789B","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A25","candidate_id":"SEM-E65AB1B9334A52775513","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A27","candidate_id":"SEM-206934F17F21136944A3","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A31","candidate_id":"SEM-FAD0F1C26827D0D72F5C","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A33","candidate_id":"SEM-89B1F8D400EDDE8F42B0","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A10","assertion_b":"A40","candidate_id":"SEM-415535166B2C33CDBBFB","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A11","assertion_b":"A12","candidate_id":"SEM-748D67E4637A161B67C5","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A11","assertion_b":"A13","candidate_id":"SEM-D1091C5F4DABA55917EB","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A11","assertion_b":"A18","candidate_id":"SEM-03A00D90A3662FDAEFA7","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A11","assertion_b":"A21","candidate_id":"SEM-C70D32EE978FD023C4FE","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A11","assertion_b":"A25","candidate_id":"SEM-128D135FB3965BF587ED","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A11","assertion_b":"A26","candidate_id":"SEM-A67F519D43F2931DE3CC","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A11","assertion_b":"A27","candidate_id":"SEM-F1E8B1ED1522145C92D8","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A11","assertion_b":"A33","candidate_id":"SEM-0515C24E3AC94C29FAFD","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A11","assertion_b":"A35","candidate_id":"SEM-C30633653BCC83E18F1A","grouping_key":{"condition":"","predicate":"enforces","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A13","assertion_b":"A18","candidate_id":"SEM-4136F0762D9D3A7BC8A2","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A13","assertion_b":"A21","candidate_id":"SEM-CA5F34FBB2CC365BA99B","grouping_key":{"condition":"","predicate":"uses","scope":"","subject":"본 branch 3개 rule"},"rule_ids":["C6"]},{"assertion_a":"A13","assertion_b":"A33","candidate_id":"SEM-FF50E0FBB7C9C212A376","grouping_key":{"condition":"","predicate":"uses","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A14","assertion_b":"A22","candidate_id":"SEM-E43198AB73301A722C52","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A14","assertion_b":"A31","candidate_id":"SEM-14076C4101BD7EAF5065","grouping_key":{"condition":"","predicate":"delegates","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A14","assertion_b":"A32","candidate_id":"SEM-76330581B45E1AD2BF7B","grouping_key":{"condition":"","predicate":"delegates","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A14","assertion_b":"A39","candidate_id":"SEM-30C1902BB2DE94A55A86","grouping_key":{"condition":"","predicate":"delegates","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A14","assertion_b":"A40","candidate_id":"SEM-379C85B80982E5253AD1","grouping_key":{"condition":"","predicate":"delegates","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A15","assertion_b":"A17","candidate_id":"SEM-9A546297E23F50E4DFD3","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A15","assertion_b":"A23","candidate_id":"SEM-B7ED647AA7F4C11387A7","grouping_key":{"condition":"","predicate":"delegates","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A15","assertion_b":"A28","candidate_id":"SEM-9402D3872A985573808E","grouping_key":{"condition":"unconditional","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A16","assertion_b":"A24","candidate_id":"SEM-EACCEF5C1AE3D42B77F4","grouping_key":{"condition":"","predicate":"other","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A17","assertion_b":"A23","candidate_id":"SEM-08A72CDFC716E7135CCB","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A18","assertion_b":"A21","candidate_id":"SEM-5977BF9D48D78BFC86A2","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A18","assertion_b":"A26","candidate_id":"SEM-2C0BDAF21C0766C9C7FB","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A18","assertion_b":"A33","candidate_id":"SEM-5F36972BA719550E4A3E","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A19","assertion_b":"A27","candidate_id":"SEM-77325803A5B73AB9B882","grouping_key":{"condition":"","predicate":"forbids","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A21","assertion_b":"A33","candidate_id":"SEM-E3A10CA3E887A6C123AA","grouping_key":{"condition":"","predicate":"uses","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A22","assertion_b":"A31","candidate_id":"SEM-218D815DB5C622397FCA","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A22","assertion_b":"A40","candidate_id":"SEM-B02E0005DB2E802C681F","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A23","assertion_b":"A28","candidate_id":"SEM-2BE5364F3E59E14F4D24","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A25","assertion_b":"A33","candidate_id":"SEM-2F40C1629564F37BC388","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A25","assertion_b":"A35","candidate_id":"SEM-2E4F016E793AEC4B215E","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A26","assertion_b":"A33","candidate_id":"SEM-8B661B783F716E8FC2FE","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A26","assertion_b":"A35","candidate_id":"SEM-564E5716DE46D0C1E730","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A27","assertion_b":"A35","candidate_id":"SEM-7D40F6DB6E5BEBA1584D","grouping_key":{"condition":"","predicate":"","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A31","assertion_b":"A40","candidate_id":"SEM-09A4573242B3E87C3AEF","grouping_key":{"condition":"","predicate":"delegates","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A32","assertion_b":"A39","candidate_id":"SEM-77E32400AEC157801ACF","grouping_key":{"condition":"","predicate":"delegates","scope":"","subject":""},"rule_ids":["C6"]},{"assertion_a":"A34","assertion_b":"A35","candidate_id":"SEM-A5A09D2E3896D9A51B57","grouping_key":{"condition":"포함 범위 (결정 완료, 착수 가능)","predicate":"","scope":"포함 범위","subject":"feature-streaming-response-contract branch"},"rule_ids":["C3"]}],"coverage":{"assertions":40,"candidate_pairs":81,"eligible_surfaces":6,"processed_surfaces":6},"document_sha256":"0bceff0596ad4407a633b3c73905f8ead3d9260b57a444cb8aa150f15dc8c0bf","explicit_blocking":[],"mode":"local","ontology_sha256":"76d41a29233c830e1940ebb3244263e2b9bfb8dd6a01f2a1d1c51ce5a1b10468","output_schema":"semantic-audit-result/v1","schema_version":"semantic-verdict-request/v1","subject":"raw/branch-notes/feature-streaming-response-contract.md"},"audit_request_sha256":"ef0570e2bb7ebeea3f5d7871b831f3ab686cc7feebb3f47dcaa13607f83440e0","audit_result":{"auditor":{"contract_version":"semantic-coherence/v1","model_id":"claude-opus-4-8","run_id":"a33f5543661c371ac"},"mode":"local","request_sha256":"ef0570e2bb7ebeea3f5d7871b831f3ab686cc7feebb3f47dcaa13607f83440e0","schema_version":"semantic-audit-result/v1","subject":"raw/branch-notes/feature-streaming-response-contract.md","verdicts":[{"candidate_id":"SEM-655ADD4228F7CAE9D047","evidence_a":{"line_end":59,"line_start":59,"quote":"- **완료 조건**: 지원 protocol과 timeout·failure contract test가 고정된다"},"evidence_b":{"line_end":66,"line_start":66,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1` | URI prefix /v1이 default이며 X-Api-Version은 compatibility 실험용 보조 header다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"proof_manifest":null,"rationale":"A01 states the branch completion condition (protocol + timeout/failure contract tests fixed); A03 records an inherited project decision the branch uses (API-VERSIONING /v1 default). Different compatible facets of the same branch; A03 adds a constraint without overriding A01's exclusive completion criterion.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-98369328CC7E7639F536","evidence_a":{"line_end":59,"line_start":59,"quote":"- **완료 조건**: 지원 protocol과 timeout·failure contract test가 고정된다"},"evidence_b":{"line_end":67,"line_start":67,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1` | Resilience4j가 default이며 Spring Retry는 simple blocking retry에만 허용한다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"proof_manifest":null,"rationale":"A01 is the branch completion condition; A04 is a distinct inherited project decision (RESILIENCE: Resilience4j default). Compatible facets of the same subject, no shared property in conflict.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-70C845D1DEA19524BFED","evidence_a":{"line_end":59,"line_start":59,"quote":"- **완료 조건**: 지원 protocol과 timeout·failure contract test가 고정된다"},"evidence_b":{"line_end":112,"line_start":112,"quote":"- 이벤트/server-push 스트리밍 지원 여부 결정 → **D1: 미지원 확정**"},"proof_manifest":null,"rationale":"A01 (completion = protocol + timeout/failure tests fixed) and A34 (D1: event/server-push streaming unsupported) describe different facets — completion criterion vs scope decision — that coexist.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-1468CFAA607BD1568591","evidence_a":{"line_end":59,"line_start":59,"quote":"- **완료 조건**: 지원 protocol과 timeout·failure contract test가 고정된다"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A01 (branch completion condition) and A35 (D3 ArchUnit enforcement in scope) are compatible facets of the same branch; A35 supplies an enforcement detail without touching A01's completion property.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-A2CC79B841E6525954A0","evidence_a":{"line_end":66,"line_start":66,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1` | URI prefix /v1이 default이며 X-Api-Version은 compatibility 실험용 보조 header다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"evidence_b":{"line_end":67,"line_start":67,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1` | Resilience4j가 default이며 Spring Retry는 simple blocking retry에만 허용한다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"proof_manifest":null,"rationale":"A03 (API-VERSIONING) and A04 (RESILIENCE) are two distinct inherited project decisions under the same condition/scope; they address different contract properties and both apply — no exclusive value collision.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-9A41EAA71D7E0B8ACB37","evidence_a":{"line_end":66,"line_start":66,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1` | URI prefix /v1이 default이며 X-Api-Version은 compatibility 실험용 보조 header다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"evidence_b":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"proof_manifest":null,"rationale":"A03 (inherited versioning decision) and A11 (D3 ArchUnit import-ban enforcing D1) address unrelated properties of the branch; compatible, neither takes over the other.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-B269103C2F80B849DC05","evidence_a":{"line_end":66,"line_start":66,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1` | URI prefix /v1이 default이며 X-Api-Version은 compatibility 실험용 보조 header다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"evidence_b":{"line_end":112,"line_start":112,"quote":"- 이벤트/server-push 스트리밍 지원 여부 결정 → **D1: 미지원 확정**"},"proof_manifest":null,"rationale":"A03 (inherited versioning decision) and A34 (D1 non-support scope) are independent, compatible branch facets.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-6B36C631FB80E120AE11","evidence_a":{"line_end":66,"line_start":66,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-API-VERSIONING-001@1` | URI prefix /v1이 default이며 X-Api-Version은 compatibility 실험용 보조 header다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A03 (inherited versioning decision) and A35 (D3 enforcement in scope) address different properties; compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-04539C33FC34CFB58E3C","evidence_a":{"line_end":67,"line_start":67,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1` | Resilience4j가 default이며 Spring Retry는 simple blocking retry에만 허용한다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"evidence_b":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"proof_manifest":null,"rationale":"A04 (inherited RESILIENCE decision) and A11 (D3 ArchUnit enforcement) are unrelated compatible facets of the branch.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-02155361E1C29DB88962","evidence_a":{"line_end":67,"line_start":67,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1` | Resilience4j가 default이며 Spring Retry는 simple blocking retry에만 허용한다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"evidence_b":{"line_end":112,"line_start":112,"quote":"- 이벤트/server-push 스트리밍 지원 여부 결정 → **D1: 미지원 확정**"},"proof_manifest":null,"rationale":"A04 (inherited RESILIENCE decision) and A34 (D1 non-support scope) are independent compatible facets.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-1B697377B0E413CBB862","evidence_a":{"line_end":67,"line_start":67,"quote":"| `DEC-CA-SKELETON-OPERATIONAL-CONTRACT-RESILIENCE-001@1` | Resilience4j가 default이며 Spring Retry는 simple blocking retry에만 허용한다 | Work Item 완료 조건에 적용 | [[raw/project-notes/ca-skeleton-operational-contract]] |"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A04 (inherited RESILIENCE decision) and A35 (D3 enforcement in scope) address different properties; compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-93C419CAA2E267E7D86F","evidence_a":{"line_end":250,"line_start":250,"quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":251,"line_start":251,"quote":"| `no_websocket_handler` 의 `org.springframework.web.socket..` + `jakarta.websocket..` glob 이 정확히 WebSocket 표면만 차단 (over-block 없음) | 패키지 glob 범위가 vendor 패키지 구조에 의존 | `SpringWebSocketHandlerFixture` (`@EnableWebSocket`), `JakartaWebSocketEndpointFixture` (`@ServerEndpoint`) fixtures → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"proof_manifest":null,"rationale":"A06 forbids SseEmitter/ResponseBodyEmitter; A07 forbids the WebSocket surface. Distinct, non-overlapping import bans that jointly implement D3 — no shared target.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-89241A55BE0EE49EFDAE","evidence_a":{"line_end":250,"line_start":250,"quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":252,"line_start":252,"quote":"| `StreamingResponseBody` 가 rule 에 걸리지 않아 file-resource D8 다운로드가 정상 build | blanket ban 시 false positive 위험 (핵심 회귀) | `StreamingResponseBodyAllowedFixture` over-block guard → 3개 D3 rule 모두 `hasViolation() == false` — GREEN | `locally-verified` (2026-06-02) |"},"proof_manifest":null,"rationale":"A06 bans SseEmitter/ResponseBodyEmitter; A08 keeps StreamingResponseBody allowed (over-block guard GREEN). Different target classes (X != Y), explicitly distinguished; not a contradiction.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-A12BBF997DD69FADBDD9","evidence_a":{"line_end":250,"line_start":250,"quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":253,"line_start":253,"quote":"| ArchUnit suite host(boundary branch) 에 3개 rule 등록이 기존 suite 와 충돌 없음 | suite 구조·rule 명명 충돌 가능 | `CleanArchitectureTest` 33 tests (기존 30 + D3 3) — 0 failures | `locally-verified` (2026-06-02) |"},"proof_manifest":null,"rationale":"A06 (verified import ban) and A09 (verified no-conflict rule registration, 33 tests) are distinct verified facets of the same D3 suite.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-F8234589BE503D3DFB9D","evidence_a":{"line_end":250,"line_start":250,"quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"proof_manifest":null,"rationale":"A06 supplies the concrete verified ban that realizes A11's D3 import-ban enforcement decision; detail under a decision, no takeover.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-A763D60D40F22256033A","evidence_a":{"line_end":250,"line_start":250,"quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":237,"line_start":237,"quote":" - **transitive dependency 차단**: `dependOnClassesThat()` 는 transitive import 도 잡으므로, 제3 라이브러리가 내부적으로 `SseEmitter` 를 참조하면 false positive 가능. 기대 동작 = production source 의 *직접* 의존만 위반으로 본다 (필요 시 `ImportOption` 으로 vendor 패키지 제외 — UNSUPPORTED_IMPL_DECISION). 해소 선례: [[raw/branch-notes/feature-boundary-validation-mapping-contract]] §구현 가이드 §8 `no_problem_detail_usage` 의 import-level 차단 trade-off 참조."},"proof_manifest":null,"rationale":"A06 verifies the ban blocks direct production imports (fixtures GREEN); A18 raises a residual transitive-dependency false-positive caveat under a different condition. Compatible caveat, no conflicting value.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-EE00D7A8DFD7760A2BC8","evidence_a":{"line_end":250,"line_start":250,"quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":216,"line_start":216,"quote":"| `no_sse_emitter` | `org.springframework.web.servlet.mvc.method.annotation.SseEmitter` | `noClasses().should().dependOnClassesThat().haveFullyQualifiedName(...)` | SSE server-push 의 직접 표면 (`SPRING-ASYNC-C4`) |"},"proof_manifest":null,"rationale":"A06 (verified SSE/emitter ban) and A25 (no_sse_emitter FQN + matcher detail) describe the same rule at different granularity; A25 adds implementation detail.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C4B8319316262159E78D","evidence_a":{"line_end":250,"line_start":250,"quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":217,"line_start":217,"quote":"| `no_response_body_emitter` | `org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter` | 동일 | SSE 의 base + incremental 객체 emit (`SPRING-ASYNC-C3`). `SseEmitter` 가 이를 상속하므로 함께 차단. **비-SSE JSON object-stream 용도까지 server-push 모델로 간주해 차단** (`UNSUPPORTED_IMPL_DECISION④`) |"},"proof_manifest":null,"rationale":"A06 (verified ban) and A26 (no_response_body_emitter FQN detail) describe the same rule; A26 adds the FQN/matcher detail.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-0605B5359B5A63A766BC","evidence_a":{"line_end":250,"line_start":250,"quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":205,"line_start":205,"quote":"> **Trace**: D1 (이벤트/server-push 스트리밍 미지원) → D3 (ArchUnit 정적 강제). 차단 대상 클래스 정의 = `SPRING-ASYNC-C4` (`SseEmitter` = `ResponseBodyEmitter` subclass, W3C SSE 포맷), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit). 메커니즘 선례 = [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (`no_problem_detail_usage` import-level 차단). suite host = boundary branch ArchUnit suite, archunit-junit5 1.3.0 (project §34)."},"proof_manifest":null,"rationale":"A06 (verified ban) and A33 (D1->D3 trace + SPRING-ASYNC class rationale) are compatible; A33 supplies the derivation rationale for the ban A06 verifies.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-1BA5873E64A1B4CB5EC8","evidence_a":{"line_end":250,"line_start":250,"quote":"| `no_sse_emitter` / `no_response_body_emitter` 가 production 코드의 `SseEmitter`·`ResponseBodyEmitter` import 를 build 단계에서 실제 차단 | ArchUnit rule 작성 후 실측 전까지 동작 미보장 | violations-as-data fixtures (`SseEmitterUsingFixture`, `ResponseBodyEmitterUsingFixture`) → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A06 (verified ban) and A35 (D3 enforcement declared in scope) are compatible; A06 is the verified realization of the in-scope enforcement A35 states.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-30FB86B3707B7F6197EB","evidence_a":{"line_end":251,"line_start":251,"quote":"| `no_websocket_handler` 의 `org.springframework.web.socket..` + `jakarta.websocket..` glob 이 정확히 WebSocket 표면만 차단 (over-block 없음) | 패키지 glob 범위가 vendor 패키지 구조에 의존 | `SpringWebSocketHandlerFixture` (`@EnableWebSocket`), `JakartaWebSocketEndpointFixture` (`@ServerEndpoint`) fixtures → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":252,"line_start":252,"quote":"| `StreamingResponseBody` 가 rule 에 걸리지 않아 file-resource D8 다운로드가 정상 build | blanket ban 시 false positive 위험 (핵심 회귀) | `StreamingResponseBodyAllowedFixture` over-block guard → 3개 D3 rule 모두 `hasViolation() == false` — GREEN | `locally-verified` (2026-06-02) |"},"proof_manifest":null,"rationale":"A07 bans the WebSocket surface; A08 keeps StreamingResponseBody allowed. Distinct target classes, no shared property in conflict.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-B1917B6B4DF1E0458BE1","evidence_a":{"line_end":251,"line_start":251,"quote":"| `no_websocket_handler` 의 `org.springframework.web.socket..` + `jakarta.websocket..` glob 이 정확히 WebSocket 표면만 차단 (over-block 없음) | 패키지 glob 범위가 vendor 패키지 구조에 의존 | `SpringWebSocketHandlerFixture` (`@EnableWebSocket`), `JakartaWebSocketEndpointFixture` (`@ServerEndpoint`) fixtures → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":253,"line_start":253,"quote":"| ArchUnit suite host(boundary branch) 에 3개 rule 등록이 기존 suite 와 충돌 없음 | suite 구조·rule 명명 충돌 가능 | `CleanArchitectureTest` 33 tests (기존 30 + D3 3) — 0 failures | `locally-verified` (2026-06-02) |"},"proof_manifest":null,"rationale":"A07 (WebSocket ban, no over-block) and A09 (registration no-conflict) are distinct verified facets of the D3 suite.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-E83955435337E7ED43DA","evidence_a":{"line_end":251,"line_start":251,"quote":"| `no_websocket_handler` 의 `org.springframework.web.socket..` + `jakarta.websocket..` glob 이 정확히 WebSocket 표면만 차단 (over-block 없음) | 패키지 glob 범위가 vendor 패키지 구조에 의존 | `SpringWebSocketHandlerFixture` (`@EnableWebSocket`), `JakartaWebSocketEndpointFixture` (`@ServerEndpoint`) fixtures → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"proof_manifest":null,"rationale":"A07 (WebSocket surface ban) supplies a concrete rule realizing A11's D3 enforcement; detail under a decision.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-3CFBEA109EA266D2730E","evidence_a":{"line_end":251,"line_start":251,"quote":"| `no_websocket_handler` 의 `org.springframework.web.socket..` + `jakarta.websocket..` glob 이 정확히 WebSocket 표면만 차단 (over-block 없음) | 패키지 glob 범위가 vendor 패키지 구조에 의존 | `SpringWebSocketHandlerFixture` (`@EnableWebSocket`), `JakartaWebSocketEndpointFixture` (`@ServerEndpoint`) fixtures → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":238,"line_start":238,"quote":" - **WebSocket 패키지 glob 과다**: `org.springframework.web.socket..` 전체 차단이 의도치 않은 하위 유틸까지 막을 수 있음. 기대 동작 = WebSocket 미사용이 default 이므로 전체 차단이 안전, 도입 시 rule 해제."},"proof_manifest":null,"rationale":"A07 (verified: glob blocks exactly the WebSocket surface, no over-block of legitimate classes) and A19 (blanket WebSocket-package block is safe since WebSocket is unused by default) reach the same operative outcome; A19's 'sub-util' note concerns WebSocket-package internals that are themselves the intended surface. No conflicting value.","verdict":"CONSISTENT"},{"candidate_id":"SEM-A607497D134EE8457082","evidence_a":{"line_end":251,"line_start":251,"quote":"| `no_websocket_handler` 의 `org.springframework.web.socket..` + `jakarta.websocket..` glob 이 정확히 WebSocket 표면만 차단 (over-block 없음) | 패키지 glob 범위가 vendor 패키지 구조에 의존 | `SpringWebSocketHandlerFixture` (`@EnableWebSocket`), `JakartaWebSocketEndpointFixture` (`@ServerEndpoint`) fixtures → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":218,"line_start":218,"quote":"| `no_websocket_handler` | `org.springframework.web.socket..` (패키지 전체) + `jakarta.websocket..` (패키지 전체) | `dependOnClassesThat().resideInAnyPackage(...)` | spring-websocket(`WebSocketHandler`, `@EnableWebSocket`, `@EnableWebSocketMessageBroker`/STOMP) + Jakarta `@ServerEndpoint` 계열 일괄 차단 (`RFC6455-C1` full-duplex 모델). **WebSocket 표면은 단일 FQN 이 없어 `haveFullyQualifiedName` 대신 `resideInAnyPackage` glob 불가피** (`UNSUPPORTED_IMPL_DECISION③`) |"},"proof_manifest":null,"rationale":"A07 validates no over-block for no_websocket_handler; A27 supplies the resideInAnyPackage glob definition (org.springframework.web.socket.. + jakarta.websocket..). Detail under the validated rule.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-02D3B1FCE33B5683D0BE","evidence_a":{"line_end":251,"line_start":251,"quote":"| `no_websocket_handler` 의 `org.springframework.web.socket..` + `jakarta.websocket..` glob 이 정확히 WebSocket 표면만 차단 (over-block 없음) | 패키지 glob 범위가 vendor 패키지 구조에 의존 | `SpringWebSocketHandlerFixture` (`@EnableWebSocket`), `JakartaWebSocketEndpointFixture` (`@ServerEndpoint`) fixtures → FixtureTest GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A07 (WebSocket surface ban) and A35 (D3 enforcement in scope) are compatible; A07 realizes part of the in-scope enforcement.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-AA592D614F3D40327A28","evidence_a":{"line_end":252,"line_start":252,"quote":"| `StreamingResponseBody` 가 rule 에 걸리지 않아 file-resource D8 다운로드가 정상 build | blanket ban 시 false positive 위험 (핵심 회귀) | `StreamingResponseBodyAllowedFixture` over-block guard → 3개 D3 rule 모두 `hasViolation() == false` — GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":253,"line_start":253,"quote":"| ArchUnit suite host(boundary branch) 에 3개 rule 등록이 기존 suite 와 충돌 없음 | suite 구조·rule 명명 충돌 가능 | `CleanArchitectureTest` 33 tests (기존 30 + D3 3) — 0 failures | `locally-verified` (2026-06-02) |"},"proof_manifest":null,"rationale":"A08 (StreamingResponseBody allowed, over-block guard GREEN) and A09 (rule registration no-conflict) are distinct verified facets.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-3AF87FC3906856813907","evidence_a":{"line_end":252,"line_start":252,"quote":"| `StreamingResponseBody` 가 rule 에 걸리지 않아 file-resource D8 다운로드가 정상 build | blanket ban 시 false positive 위험 (핵심 회귀) | `StreamingResponseBodyAllowedFixture` over-block guard → 3개 D3 rule 모두 `hasViolation() == false` — GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"proof_manifest":null,"rationale":"A08 keeps StreamingResponseBody (download, request-response) allowed; A10 bars SSE/WebSocket server-push. Explicitly distinguished concerns (D1 note: do not confuse with StreamingResponseBody), different targets.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-1D64524A2099A24F8C5C","evidence_a":{"line_end":252,"line_start":252,"quote":"| `StreamingResponseBody` 가 rule 에 걸리지 않아 file-resource D8 다운로드가 정상 build | blanket ban 시 false positive 위험 (핵심 회귀) | `StreamingResponseBodyAllowedFixture` over-block guard → 3개 D3 rule 모두 `hasViolation() == false` — GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":196,"line_start":196,"quote":"> - **(D3 경계, OUT_OF_BRANCH_SCOPE)** `StreamingResponseBody` 는 [[raw/branch-notes/feature-file-resource-handling-contract]] D8 (verified, 다운로드 메커니즘) 소유 → 차단 안 함. blanket ban 시 파일 다운로드 build 실패하므로 명시적 제외."},"proof_manifest":null,"rationale":"A08 and A15 both assert StreamingResponseBody is not blocked because file-resource D8 owns it. Same claim, consistent ownership.","verdict":"CONSISTENT"},{"candidate_id":"SEM-8B7E9F23F1729258919F","evidence_a":{"line_end":252,"line_start":252,"quote":"| `StreamingResponseBody` 가 rule 에 걸리지 않아 file-resource D8 다운로드가 정상 build | blanket ban 시 false positive 위험 (핵심 회귀) | `StreamingResponseBodyAllowedFixture` over-block guard → 3개 D3 rule 모두 `hasViolation() == false` — GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":236,"line_start":236,"quote":" - **false positive — `StreamingResponseBody` 오차단**: rule glob 이 너무 넓으면 file-resource D8 다운로드가 깨짐. 기대 동작 = `StreamingResponseBody` 는 rule 대상 FQN 목록에 *포함하지 않음* (§구현 가이드 명시적 비-차단). 차단되면 안 됨."},"proof_manifest":null,"rationale":"A08 (over-block guard GREEN) and A17 (StreamingResponseBody must not be in the rule FQN list / must not be blocked) assert the same non-blocking guarantee for the same scope (file-resource D8 download).","verdict":"CONSISTENT"},{"candidate_id":"SEM-F7016C9A81661F41DC39","evidence_a":{"line_end":252,"line_start":252,"quote":"| `StreamingResponseBody` 가 rule 에 걸리지 않아 file-resource D8 다운로드가 정상 build | blanket ban 시 false positive 위험 (핵심 회귀) | `StreamingResponseBodyAllowedFixture` over-block guard → 3개 D3 rule 모두 `hasViolation() == false` — GREEN | `locally-verified` (2026-06-02) |"},"evidence_b":{"line_end":243,"line_start":243,"quote":" - [[raw/branch-notes/feature-file-resource-handling-contract]] **D8** 과 경계 공유 — `StreamingResponseBody` 소유권. D8 이 다른 streaming 클래스를 쓰기 시작하면 본 branch 비-차단 목록 재검토."},"proof_manifest":null,"rationale":"A08 (StreamingResponseBody not blocked) and A23 (StreamingResponseBody owned by file-resource D8, boundary shared) are the same claim about the same object.","verdict":"CONSISTENT"},{"candidate_id":"SEM-66F0C6353F85F47349BB","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"proof_manifest":null,"rationale":"A11's D3 ArchUnit import-ban statically enforces A10's D1 non-support decision; enforcement of a decision, no takeover.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-7212CEF2ACD31B9B3BEF","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":190,"line_start":190,"quote":"| D2 | 이벤트 스트리밍 *지원* 계약(매커니즘/envelope/per-event span/timeout/cap/proxy) = 보류 (Deferred) | `WHATWG-SSE-C1~C6`, `RFC6455-C1~C6`, `RFC9112-CHUNK-C1~C5`, `SPRING-ASYNC-C1~C7`, `WOOWA-SSE-C1~C6`, `WOOWA-WS-C1~C5` (재개 시 재조사 불필요하게 보존) | `official-standard` + `official-vendor-doc` + `company-case-study` | 재개 트리거 전까지 dormant. 아래 OPEN 갭(per-event span) 동반 |"},"proof_manifest":null,"rationale":"A10 (D1: not supported now) and A12 (D2: support contract deferred/dormant) are compatible stages of the same feature's lifecycle.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-CE3F3160DCBBEA9D5DBA","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":195,"line_start":195,"quote":"> - **(폴링 대안, 닫힘)** server-push 미지원 시 비동기 응답 우회 = [[raw/branch-notes/feature-api-contract-baseline]] **D17** (verified LRO: 202 + `Location` + polling endpoint + `Retry-After`). webhook 우회는 [[raw/branch-notes/feature-webhook-outbound-contract]] 가 미결정(forward-ref) + 동 branch 가 SSE 대체를 *본 branch* 로 역참조 → 상호 보류."},"proof_manifest":null,"rationale":"A10 (no server-push) and A14 (polling workaround = api-baseline D17 LRO) are compatible; A14 supplies the alternative path detail.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-DAE5AAFA96B29558B508","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":196,"line_start":196,"quote":"> - **(D3 경계, OUT_OF_BRANCH_SCOPE)** `StreamingResponseBody` 는 [[raw/branch-notes/feature-file-resource-handling-contract]] D8 (verified, 다운로드 메커니즘) 소유 → 차단 안 함. blanket ban 시 파일 다운로드 build 실패하므로 명시적 제외."},"proof_manifest":null,"rationale":"A10 bars SSE/WebSocket push; A15 keeps StreamingResponseBody download allowed. Distinguished, different targets.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-3347E971AD4073434507","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":236,"line_start":236,"quote":" - **false positive — `StreamingResponseBody` 오차단**: rule glob 이 너무 넓으면 file-resource D8 다운로드가 깨짐. 기대 동작 = `StreamingResponseBody` 는 rule 대상 FQN 목록에 *포함하지 않음* (§구현 가이드 명시적 비-차단). 차단되면 안 됨."},"proof_manifest":null,"rationale":"A10 (D1 push unsupported) and A17 (StreamingResponseBody false-positive guard) address different classes; A17 protects a legitimately-allowed class, compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-92C6FF19022D9B234E99","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":242,"line_start":242,"quote":" - [[raw/branch-notes/feature-api-contract-baseline]] **D17** consume (미지원 시 비동기 우회 = LRO polling). D17 계약이 바뀌면 본 branch §구현 가이드 §2 대안 경로 갱신 필요."},"proof_manifest":null,"rationale":"A10 (no server-push) and A22 (consumes D17 LRO polling as the async alternative) are compatible; A22 supplies the fallback detail.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-1AE6F9D1089BE461789B","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":243,"line_start":243,"quote":" - [[raw/branch-notes/feature-file-resource-handling-contract]] **D8** 과 경계 공유 — `StreamingResponseBody` 소유권. D8 이 다른 streaming 클래스를 쓰기 시작하면 본 branch 비-차단 목록 재검토."},"proof_manifest":null,"rationale":"A10 (no push) and A23 (StreamingResponseBody owned by D8 boundary) address different classes; compatible.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-E65AB1B9334A52775513","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":216,"line_start":216,"quote":"| `no_sse_emitter` | `org.springframework.web.servlet.mvc.method.annotation.SseEmitter` | `noClasses().should().dependOnClassesThat().haveFullyQualifiedName(...)` | SSE server-push 의 직접 표면 (`SPRING-ASYNC-C4`) |"},"proof_manifest":null,"rationale":"A10 (D1 non-support) and A25 (no_sse_emitter rule) are compatible; A25 is the concrete rule enforcing D1.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-206934F17F21136944A3","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":218,"line_start":218,"quote":"| `no_websocket_handler` | `org.springframework.web.socket..` (패키지 전체) + `jakarta.websocket..` (패키지 전체) | `dependOnClassesThat().resideInAnyPackage(...)` | spring-websocket(`WebSocketHandler`, `@EnableWebSocket`, `@EnableWebSocketMessageBroker`/STOMP) + Jakarta `@ServerEndpoint` 계열 일괄 차단 (`RFC6455-C1` full-duplex 모델). **WebSocket 표면은 단일 FQN 이 없어 `haveFullyQualifiedName` 대신 `resideInAnyPackage` glob 불가피** (`UNSUPPORTED_IMPL_DECISION③`) |"},"proof_manifest":null,"rationale":"A10 (no WebSocket) and A27 (no_websocket_handler rule) are compatible; A27 enforces D1.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-FAD0F1C26827D0D72F5C","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":228,"line_start":228,"quote":"- 비동기 server→client 결과 전달이 필요하면: [[raw/branch-notes/feature-api-contract-baseline]] **D17** LRO 패턴 (202 + `Location` + `GET /operations/{id}` polling + `Retry-After`) 사용."},"proof_manifest":null,"rationale":"A10 (no server-push) and A31 (D17 LRO pattern as async alternative) are compatible; A31 supplies the alternative path.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-89B1F8D400EDDE8F42B0","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":205,"line_start":205,"quote":"> **Trace**: D1 (이벤트/server-push 스트리밍 미지원) → D3 (ArchUnit 정적 강제). 차단 대상 클래스 정의 = `SPRING-ASYNC-C4` (`SseEmitter` = `ResponseBodyEmitter` subclass, W3C SSE 포맷), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit). 메커니즘 선례 = [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (`no_problem_detail_usage` import-level 차단). suite host = boundary branch ArchUnit suite, archunit-junit5 1.3.0 (project §34)."},"proof_manifest":null,"rationale":"A10 (D1 non-support) and A33 (D1->D3 trace) are compatible; A33 supplies the derivation/enforcement rationale.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-415535166B2C33CDBBFB","evidence_a":{"line_end":188,"line_start":188,"quote":"| D1 | 이벤트/server-push 스트리밍(SSE·WebSocket) 미지원 확정 | `SPRING-ASYNC-C4` (SseEmitter=W3C SSE), `WHATWG-SSE-C5` (단방향 push), `RFC6455-C1` (full-duplex) — *무엇을 미지원하는지* 의 클래스 정의 + [[raw/branch-notes/feature-api-contract-baseline]] scope 선언 (request-response only) = `UNSUPPORTED_DECISION` (project-internal consistency 논거 — api-baseline Out of scope 선언과의 정합, 보조 근거) | `official-standard` + `official-vendor-doc` + `cross-branch-consistency` | 실제 push use case 등장 시 D2 로 재개. `StreamingResponseBody`(다운로드)와 혼동 금지 — 별 관심사 |"},"evidence_b":{"line_end":128,"line_start":128,"quote":"- async polling endpoint (LRO) — [[raw/branch-notes/feature-api-contract-baseline]] D17 SSOT"},"proof_manifest":null,"rationale":"A10 (no push) and A40 (async polling LRO delegated to api-baseline D17 SSOT) are compatible; A40 supplies the delegated alternative.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-748D67E4637A161B67C5","evidence_a":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"evidence_b":{"line_end":190,"line_start":190,"quote":"| D2 | 이벤트 스트리밍 *지원* 계약(매커니즘/envelope/per-event span/timeout/cap/proxy) = 보류 (Deferred) | `WHATWG-SSE-C1~C6`, `RFC6455-C1~C6`, `RFC9112-CHUNK-C1~C5`, `SPRING-ASYNC-C1~C7`, `WOOWA-SSE-C1~C6`, `WOOWA-WS-C1~C5` (재개 시 재조사 불필요하게 보존) | `official-standard` + `official-vendor-doc` + `company-case-study` | 재개 트리거 전까지 dormant. 아래 OPEN 갭(per-event span) 동반 |"},"proof_manifest":null,"rationale":"A11 (D3 enforces current non-support) and A12 (D2 deferred future support) are compatible lifecycle stages.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-D1091C5F4DABA55917EB","evidence_a":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"evidence_b":{"line_end":194,"line_start":194,"quote":"> - **(D3 의존, 활성)** ArchUnit suite **host = [[raw/branch-notes/feature-boundary-validation-mapping-contract]]** (D5 import-ban 선례). 본 branch 의 3개 rule 은 그 suite 에 등록. archunit-junit5 1.3.0 (project §34). suite 구조가 바뀌면 본 branch rule 영향."},"proof_manifest":null,"rationale":"A11 (D3 enforcement) and A13 (the boundary-branch suite-host dependency the rules rely on) are compatible; A13 supplies the dependency detail.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-03A00D90A3662FDAEFA7","evidence_a":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"evidence_b":{"line_end":237,"line_start":237,"quote":" - **transitive dependency 차단**: `dependOnClassesThat()` 는 transitive import 도 잡으므로, 제3 라이브러리가 내부적으로 `SseEmitter` 를 참조하면 false positive 가능. 기대 동작 = production source 의 *직접* 의존만 위반으로 본다 (필요 시 `ImportOption` 으로 vendor 패키지 제외 — UNSUPPORTED_IMPL_DECISION). 해소 선례: [[raw/branch-notes/feature-boundary-validation-mapping-contract]] §구현 가이드 §8 `no_problem_detail_usage` 의 import-level 차단 trade-off 참조."},"proof_manifest":null,"rationale":"A11 (D3 enforcement) and A18 (transitive-dependency false-positive caveat) are compatible; A18 adds a risk detail under a different condition.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C70D32EE978FD023C4FE","evidence_a":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"evidence_b":{"line_end":241,"line_start":241,"quote":" - [[raw/branch-notes/feature-boundary-validation-mapping-contract]] **D5 / ArchUnit suite host** 에 의존 — 본 branch 3개 rule 을 그 suite 에 등록. suite 구조·archunit-junit5 버전(project §34, 1.3.0)이 바뀌면 본 branch 영향."},"proof_manifest":null,"rationale":"A11 (D3 enforcement) and A21 (suite-host / archunit-1.3.0 dependency) are compatible; A21 supplies the dependency detail.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-128D135FB3965BF587ED","evidence_a":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"evidence_b":{"line_end":216,"line_start":216,"quote":"| `no_sse_emitter` | `org.springframework.web.servlet.mvc.method.annotation.SseEmitter` | `noClasses().should().dependOnClassesThat().haveFullyQualifiedName(...)` | SSE server-push 의 직접 표면 (`SPRING-ASYNC-C4`) |"},"proof_manifest":null,"rationale":"A11 (D3 enforcement) and A25 (no_sse_emitter FQN detail) describe the decision and one of its concrete rules.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-A67F519D43F2931DE3CC","evidence_a":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"evidence_b":{"line_end":217,"line_start":217,"quote":"| `no_response_body_emitter` | `org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter` | 동일 | SSE 의 base + incremental 객체 emit (`SPRING-ASYNC-C3`). `SseEmitter` 가 이를 상속하므로 함께 차단. **비-SSE JSON object-stream 용도까지 server-push 모델로 간주해 차단** (`UNSUPPORTED_IMPL_DECISION④`) |"},"proof_manifest":null,"rationale":"A11 (D3 enforcement) and A26 (no_response_body_emitter FQN detail) describe the decision and one of its concrete rules.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-F1E8B1ED1522145C92D8","evidence_a":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"evidence_b":{"line_end":218,"line_start":218,"quote":"| `no_websocket_handler` | `org.springframework.web.socket..` (패키지 전체) + `jakarta.websocket..` (패키지 전체) | `dependOnClassesThat().resideInAnyPackage(...)` | spring-websocket(`WebSocketHandler`, `@EnableWebSocket`, `@EnableWebSocketMessageBroker`/STOMP) + Jakarta `@ServerEndpoint` 계열 일괄 차단 (`RFC6455-C1` full-duplex 모델). **WebSocket 표면은 단일 FQN 이 없어 `haveFullyQualifiedName` 대신 `resideInAnyPackage` glob 불가피** (`UNSUPPORTED_IMPL_DECISION③`) |"},"proof_manifest":null,"rationale":"A11 (D3 enforcement) and A27 (no_websocket_handler glob detail) describe the decision and one of its concrete rules.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-0515C24E3AC94C29FAFD","evidence_a":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"evidence_b":{"line_end":205,"line_start":205,"quote":"> **Trace**: D1 (이벤트/server-push 스트리밍 미지원) → D3 (ArchUnit 정적 강제). 차단 대상 클래스 정의 = `SPRING-ASYNC-C4` (`SseEmitter` = `ResponseBodyEmitter` subclass, W3C SSE 포맷), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit). 메커니즘 선례 = [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (`no_problem_detail_usage` import-level 차단). suite host = boundary branch ArchUnit suite, archunit-junit5 1.3.0 (project §34)."},"proof_manifest":null,"rationale":"A11 (D3 IN-SCOPE enforcement) and A33 (D1->D3 trace + SPRING-ASYNC class rationale) are compatible; A33 supplies the derivation rationale for the same enforcement.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-C30633653BCC83E18F1A","evidence_a":{"line_end":189,"line_start":189,"quote":"| D3 | D1 을 ArchUnit import-ban 으로 정적 강제 (IN-SCOPE): `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler` | `SPRING-ASYNC-C4` (`SseEmitter` FQN + 역할), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit) + 선례 [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (import-level 차단 메커니즘) + `project-ssot` ([[raw/project-notes/ca-skeleton-operational-contract]] §34 Stack Commitment — archunit-junit5 1.3.0 lock) | `official-vendor-doc` (차단 대상 클래스) + `cross-branch-SSOT` (ArchUnit suite host = boundary branch) + `project-ssot` | rule 명명 + 차단 메커니즘(import vs reference) = `UNSUPPORTED_IMPL_DECISION` (§구현 가이드). WebFlux 타입은 stack(MVC) 밖이라 미포함 |"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A11 and A35 both state D3 statically enforces D1 via no_sse_emitter/no_response_body_emitter/no_websocket_handler. Same claim, meaning preserved.","verdict":"CONSISTENT"},{"candidate_id":"SEM-4136F0762D9D3A7BC8A2","evidence_a":{"line_end":194,"line_start":194,"quote":"> - **(D3 의존, 활성)** ArchUnit suite **host = [[raw/branch-notes/feature-boundary-validation-mapping-contract]]** (D5 import-ban 선례). 본 branch 의 3개 rule 은 그 suite 에 등록. archunit-junit5 1.3.0 (project §34). suite 구조가 바뀌면 본 branch rule 영향."},"evidence_b":{"line_end":237,"line_start":237,"quote":" - **transitive dependency 차단**: `dependOnClassesThat()` 는 transitive import 도 잡으므로, 제3 라이브러리가 내부적으로 `SseEmitter` 를 참조하면 false positive 가능. 기대 동작 = production source 의 *직접* 의존만 위반으로 본다 (필요 시 `ImportOption` 으로 vendor 패키지 제외 — UNSUPPORTED_IMPL_DECISION). 해소 선례: [[raw/branch-notes/feature-boundary-validation-mapping-contract]] §구현 가이드 §8 `no_problem_detail_usage` 의 import-level 차단 trade-off 참조."},"proof_manifest":null,"rationale":"A13 (boundary suite-host dependency) and A18 (transitive false-positive caveat) are distinct compatible risk/dependency details.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-CA5F34FBB2CC365BA99B","evidence_a":{"line_end":194,"line_start":194,"quote":"> - **(D3 의존, 활성)** ArchUnit suite **host = [[raw/branch-notes/feature-boundary-validation-mapping-contract]]** (D5 import-ban 선례). 본 branch 의 3개 rule 은 그 suite 에 등록. archunit-junit5 1.3.0 (project §34). suite 구조가 바뀌면 본 branch rule 영향."},"evidence_b":{"line_end":241,"line_start":241,"quote":" - [[raw/branch-notes/feature-boundary-validation-mapping-contract]] **D5 / ArchUnit suite host** 에 의존 — 본 branch 3개 rule 을 그 suite 에 등록. suite 구조·archunit-junit5 버전(project §34, 1.3.0)이 바뀌면 본 branch 영향."},"proof_manifest":null,"rationale":"A13 and A21 both state the same cross-branch dependency: ArchUnit suite host = boundary-validation-mapping-contract D5, archunit-junit5 1.3.0 (project §34). Same claim.","verdict":"CONSISTENT"},{"candidate_id":"SEM-FF50E0FBB7C9C212A376","evidence_a":{"line_end":194,"line_start":194,"quote":"> - **(D3 의존, 활성)** ArchUnit suite **host = [[raw/branch-notes/feature-boundary-validation-mapping-contract]]** (D5 import-ban 선례). 본 branch 의 3개 rule 은 그 suite 에 등록. archunit-junit5 1.3.0 (project §34). suite 구조가 바뀌면 본 branch rule 영향."},"evidence_b":{"line_end":205,"line_start":205,"quote":"> **Trace**: D1 (이벤트/server-push 스트리밍 미지원) → D3 (ArchUnit 정적 강제). 차단 대상 클래스 정의 = `SPRING-ASYNC-C4` (`SseEmitter` = `ResponseBodyEmitter` subclass, W3C SSE 포맷), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit). 메커니즘 선례 = [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (`no_problem_detail_usage` import-level 차단). suite host = boundary branch ArchUnit suite, archunit-junit5 1.3.0 (project §34)."},"proof_manifest":null,"rationale":"A13 and A33 both state suite host = boundary branch + archunit-junit5 1.3.0. Consistent restatement, meaning preserved.","verdict":"CONSISTENT"},{"candidate_id":"SEM-E43198AB73301A722C52","evidence_a":{"line_end":195,"line_start":195,"quote":"> - **(폴링 대안, 닫힘)** server-push 미지원 시 비동기 응답 우회 = [[raw/branch-notes/feature-api-contract-baseline]] **D17** (verified LRO: 202 + `Location` + polling endpoint + `Retry-After`). webhook 우회는 [[raw/branch-notes/feature-webhook-outbound-contract]] 가 미결정(forward-ref) + 동 branch 가 SSE 대체를 *본 branch* 로 역참조 → 상호 보류."},"evidence_b":{"line_end":242,"line_start":242,"quote":" - [[raw/branch-notes/feature-api-contract-baseline]] **D17** consume (미지원 시 비동기 우회 = LRO polling). D17 계약이 바뀌면 본 branch §구현 가이드 §2 대안 경로 갱신 필요."},"proof_manifest":null,"rationale":"A14 and A22 both restate api-baseline D17 as the async workaround = LRO polling. Consumer restatement preserves the owner's meaning; no drift.","verdict":"CONSISTENT"},{"candidate_id":"SEM-14076C4101BD7EAF5065","evidence_a":{"line_end":195,"line_start":195,"quote":"> - **(폴링 대안, 닫힘)** server-push 미지원 시 비동기 응답 우회 = [[raw/branch-notes/feature-api-contract-baseline]] **D17** (verified LRO: 202 + `Location` + polling endpoint + `Retry-After`). webhook 우회는 [[raw/branch-notes/feature-webhook-outbound-contract]] 가 미결정(forward-ref) + 동 branch 가 SSE 대체를 *본 branch* 로 역참조 → 상호 보류."},"evidence_b":{"line_end":228,"line_start":228,"quote":"- 비동기 server→client 결과 전달이 필요하면: [[raw/branch-notes/feature-api-contract-baseline]] **D17** LRO 패턴 (202 + `Location` + `GET /operations/{id}` polling + `Retry-After`) 사용."},"proof_manifest":null,"rationale":"A14 and A31 both restate D17 LRO (202 + Location + polling endpoint + Retry-After). Same meaning, consistent.","verdict":"CONSISTENT"},{"candidate_id":"SEM-76330581B45E1AD2BF7B","evidence_a":{"line_end":195,"line_start":195,"quote":"> - **(폴링 대안, 닫힘)** server-push 미지원 시 비동기 응답 우회 = [[raw/branch-notes/feature-api-contract-baseline]] **D17** (verified LRO: 202 + `Location` + polling endpoint + `Retry-After`). webhook 우회는 [[raw/branch-notes/feature-webhook-outbound-contract]] 가 미결정(forward-ref) + 동 branch 가 SSE 대체를 *본 branch* 로 역참조 → 상호 보류."},"evidence_b":{"line_end":229,"line_start":229,"quote":"- 외부 시스템 push 가 필요하면: [[raw/branch-notes/feature-webhook-outbound-contract]] (미결정, forward-ref)."},"proof_manifest":null,"rationale":"A14 (polling alternative via D17) and A32 (external push via webhook-outbound-contract, forward-ref) are distinct compatible fallback routes for different needs.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-30C1902BB2DE94A55A86","evidence_a":{"line_end":195,"line_start":195,"quote":"> - **(폴링 대안, 닫힘)** server-push 미지원 시 비동기 응답 우회 = [[raw/branch-notes/feature-api-contract-baseline]] **D17** (verified LRO: 202 + `Location` + polling endpoint + `Retry-After`). webhook 우회는 [[raw/branch-notes/feature-webhook-outbound-contract]] 가 미결정(forward-ref) + 동 branch 가 SSE 대체를 *본 branch* 로 역참조 → 상호 보류."},"evidence_b":{"line_end":127,"line_start":127,"quote":"- async webhook 발송 — [[raw/branch-notes/feature-webhook-outbound-contract]] SSOT"},"proof_manifest":null,"rationale":"A14 (polling via D17) and A39 (async webhook delegated to webhook-outbound-contract SSOT) are distinct compatible delegations.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-379C85B80982E5253AD1","evidence_a":{"line_end":195,"line_start":195,"quote":"> - **(폴링 대안, 닫힘)** server-push 미지원 시 비동기 응답 우회 = [[raw/branch-notes/feature-api-contract-baseline]] **D17** (verified LRO: 202 + `Location` + polling endpoint + `Retry-After`). webhook 우회는 [[raw/branch-notes/feature-webhook-outbound-contract]] 가 미결정(forward-ref) + 동 branch 가 SSE 대체를 *본 branch* 로 역참조 → 상호 보류."},"evidence_b":{"line_end":128,"line_start":128,"quote":"- async polling endpoint (LRO) — [[raw/branch-notes/feature-api-contract-baseline]] D17 SSOT"},"proof_manifest":null,"rationale":"A14 and A40 both delegate the async/LRO polling path to api-baseline D17. Same claim.","verdict":"CONSISTENT"},{"candidate_id":"SEM-9A546297E23F50E4DFD3","evidence_a":{"line_end":196,"line_start":196,"quote":"> - **(D3 경계, OUT_OF_BRANCH_SCOPE)** `StreamingResponseBody` 는 [[raw/branch-notes/feature-file-resource-handling-contract]] D8 (verified, 다운로드 메커니즘) 소유 → 차단 안 함. blanket ban 시 파일 다운로드 build 실패하므로 명시적 제외."},"evidence_b":{"line_end":236,"line_start":236,"quote":" - **false positive — `StreamingResponseBody` 오차단**: rule glob 이 너무 넓으면 file-resource D8 다운로드가 깨짐. 기대 동작 = `StreamingResponseBody` 는 rule 대상 FQN 목록에 *포함하지 않음* (§구현 가이드 명시적 비-차단). 차단되면 안 됨."},"proof_manifest":null,"rationale":"A15 and A17 both assert StreamingResponseBody must not be blocked (owned by file-resource D8; false-positive guard). Same claim.","verdict":"CONSISTENT"},{"candidate_id":"SEM-B7ED647AA7F4C11387A7","evidence_a":{"line_end":196,"line_start":196,"quote":"> - **(D3 경계, OUT_OF_BRANCH_SCOPE)** `StreamingResponseBody` 는 [[raw/branch-notes/feature-file-resource-handling-contract]] D8 (verified, 다운로드 메커니즘) 소유 → 차단 안 함. blanket ban 시 파일 다운로드 build 실패하므로 명시적 제외."},"evidence_b":{"line_end":243,"line_start":243,"quote":" - [[raw/branch-notes/feature-file-resource-handling-contract]] **D8** 과 경계 공유 — `StreamingResponseBody` 소유권. D8 이 다른 streaming 클래스를 쓰기 시작하면 본 branch 비-차단 목록 재검토."},"proof_manifest":null,"rationale":"A15 and A23 both assign StreamingResponseBody ownership to file-resource D8 and exclude it from blocking. Same claim, single owner.","verdict":"CONSISTENT"},{"candidate_id":"SEM-9402D3872A985573808E","evidence_a":{"line_end":196,"line_start":196,"quote":"> - **(D3 경계, OUT_OF_BRANCH_SCOPE)** `StreamingResponseBody` 는 [[raw/branch-notes/feature-file-resource-handling-contract]] D8 (verified, 다운로드 메커니즘) 소유 → 차단 안 함. blanket ban 시 파일 다운로드 build 실패하므로 명시적 제외."},"evidence_b":{"line_end":221,"line_start":221,"quote":"- `org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody` — **차단하지 않음.** 대용량 다운로드용 응답 body 청크 전송 (`SPRING-ASYNC-C2`: \"for example, for a file download\"), 통신 모델은 request-response 유지. [[raw/branch-notes/feature-file-resource-handling-contract]] D8 (verified) 소유. blanket ban 시 다운로드 build 실패."},"proof_manifest":null,"rationale":"A15 and A28 both state StreamingResponseBody is not blocked because file-resource D8 (verified) owns it. Same claim.","verdict":"CONSISTENT"},{"candidate_id":"SEM-EACCEF5C1AE3D42B77F4","evidence_a":{"line_end":197,"line_start":197,"quote":"> - **(D2 동반 OPEN, 미해결)** per-event trace span: [[raw/branch-notes/feature-distributed-tracing-contract]] D5/D7 은 traceparent 를 *request 단위* 로 전파하나 propagation surface(outbound HTTP/Kafka/Rabbit/scheduler)에 **long-lived streaming connection 없음**. \"한 connection 의 N개 event 에 traceId 를 어떻게\" 는 기존 Decision ID 로 닫히지 않는 진짜 OPEN 갭 — D2 재개 시 tracing branch 와 동시 결정 필요."},"evidence_b":{"line_end":244,"line_start":244,"quote":"- **D2 보류분 OPEN 의존 (재개 시)**: [[raw/branch-notes/feature-distributed-tracing-contract]] D5/D7 — long-lived connection 의 per-event trace span 정책 미존재. 재개 시 동시 결정 필요."},"proof_manifest":null,"rationale":"A16 and A24 both describe the same genuine OPEN gap: per-event trace span vs distributed-tracing D5/D7 (request-level, no long-lived streaming), to be co-decided when D2 resumes. Same claim.","verdict":"CONSISTENT"},{"candidate_id":"SEM-08A72CDFC716E7135CCB","evidence_a":{"line_end":236,"line_start":236,"quote":" - **false positive — `StreamingResponseBody` 오차단**: rule glob 이 너무 넓으면 file-resource D8 다운로드가 깨짐. 기대 동작 = `StreamingResponseBody` 는 rule 대상 FQN 목록에 *포함하지 않음* (§구현 가이드 명시적 비-차단). 차단되면 안 됨."},"evidence_b":{"line_end":243,"line_start":243,"quote":" - [[raw/branch-notes/feature-file-resource-handling-contract]] **D8** 과 경계 공유 — `StreamingResponseBody` 소유권. D8 이 다른 streaming 클래스를 쓰기 시작하면 본 branch 비-차단 목록 재검토."},"proof_manifest":null,"rationale":"A17 (false-positive guard) and A23 (StreamingResponseBody owned by D8) both keep StreamingResponseBody unblocked. Consistent, same owner.","verdict":"CONSISTENT"},{"candidate_id":"SEM-5977BF9D48D78BFC86A2","evidence_a":{"line_end":237,"line_start":237,"quote":" - **transitive dependency 차단**: `dependOnClassesThat()` 는 transitive import 도 잡으므로, 제3 라이브러리가 내부적으로 `SseEmitter` 를 참조하면 false positive 가능. 기대 동작 = production source 의 *직접* 의존만 위반으로 본다 (필요 시 `ImportOption` 으로 vendor 패키지 제외 — UNSUPPORTED_IMPL_DECISION). 해소 선례: [[raw/branch-notes/feature-boundary-validation-mapping-contract]] §구현 가이드 §8 `no_problem_detail_usage` 의 import-level 차단 trade-off 참조."},"evidence_b":{"line_end":241,"line_start":241,"quote":" - [[raw/branch-notes/feature-boundary-validation-mapping-contract]] **D5 / ArchUnit suite host** 에 의존 — 본 branch 3개 rule 을 그 suite 에 등록. suite 구조·archunit-junit5 버전(project §34, 1.3.0)이 바뀌면 본 branch 영향."},"proof_manifest":null,"rationale":"A18 (transitive false-positive caveat) and A21 (suite-host dependency) are distinct compatible details about the same rule set.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-2C0BDAF21C0766C9C7FB","evidence_a":{"line_end":237,"line_start":237,"quote":" - **transitive dependency 차단**: `dependOnClassesThat()` 는 transitive import 도 잡으므로, 제3 라이브러리가 내부적으로 `SseEmitter` 를 참조하면 false positive 가능. 기대 동작 = production source 의 *직접* 의존만 위반으로 본다 (필요 시 `ImportOption` 으로 vendor 패키지 제외 — UNSUPPORTED_IMPL_DECISION). 해소 선례: [[raw/branch-notes/feature-boundary-validation-mapping-contract]] §구현 가이드 §8 `no_problem_detail_usage` 의 import-level 차단 trade-off 참조."},"evidence_b":{"line_end":217,"line_start":217,"quote":"| `no_response_body_emitter` | `org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter` | 동일 | SSE 의 base + incremental 객체 emit (`SPRING-ASYNC-C3`). `SseEmitter` 가 이를 상속하므로 함께 차단. **비-SSE JSON object-stream 용도까지 server-push 모델로 간주해 차단** (`UNSUPPORTED_IMPL_DECISION④`) |"},"proof_manifest":null,"rationale":"A18 (transitive dependency caveat) and A26 (no_response_body_emitter FQN detail) are distinct compatible details.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-5F36972BA719550E4A3E","evidence_a":{"line_end":237,"line_start":237,"quote":" - **transitive dependency 차단**: `dependOnClassesThat()` 는 transitive import 도 잡으므로, 제3 라이브러리가 내부적으로 `SseEmitter` 를 참조하면 false positive 가능. 기대 동작 = production source 의 *직접* 의존만 위반으로 본다 (필요 시 `ImportOption` 으로 vendor 패키지 제외 — UNSUPPORTED_IMPL_DECISION). 해소 선례: [[raw/branch-notes/feature-boundary-validation-mapping-contract]] §구현 가이드 §8 `no_problem_detail_usage` 의 import-level 차단 trade-off 참조."},"evidence_b":{"line_end":205,"line_start":205,"quote":"> **Trace**: D1 (이벤트/server-push 스트리밍 미지원) → D3 (ArchUnit 정적 강제). 차단 대상 클래스 정의 = `SPRING-ASYNC-C4` (`SseEmitter` = `ResponseBodyEmitter` subclass, W3C SSE 포맷), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit). 메커니즘 선례 = [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (`no_problem_detail_usage` import-level 차단). suite host = boundary branch ArchUnit suite, archunit-junit5 1.3.0 (project §34)."},"proof_manifest":null,"rationale":"A18 (transitive caveat) and A33 (D1->D3 trace rationale) are distinct compatible details.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-77325803A5B73AB9B882","evidence_a":{"line_end":238,"line_start":238,"quote":" - **WebSocket 패키지 glob 과다**: `org.springframework.web.socket..` 전체 차단이 의도치 않은 하위 유틸까지 막을 수 있음. 기대 동작 = WebSocket 미사용이 default 이므로 전체 차단이 안전, 도입 시 rule 해제."},"evidence_b":{"line_end":218,"line_start":218,"quote":"| `no_websocket_handler` | `org.springframework.web.socket..` (패키지 전체) + `jakarta.websocket..` (패키지 전체) | `dependOnClassesThat().resideInAnyPackage(...)` | spring-websocket(`WebSocketHandler`, `@EnableWebSocket`, `@EnableWebSocketMessageBroker`/STOMP) + Jakarta `@ServerEndpoint` 계열 일괄 차단 (`RFC6455-C1` full-duplex 모델). **WebSocket 표면은 단일 FQN 이 없어 `haveFullyQualifiedName` 대신 `resideInAnyPackage` glob 불가피** (`UNSUPPORTED_IMPL_DECISION③`) |"},"proof_manifest":null,"rationale":"A19 and A27 both endorse blocking the whole WebSocket package via resideInAnyPackage glob (safe because WebSocket is unused by default). Same claim.","verdict":"CONSISTENT"},{"candidate_id":"SEM-E3A10CA3E887A6C123AA","evidence_a":{"line_end":241,"line_start":241,"quote":" - [[raw/branch-notes/feature-boundary-validation-mapping-contract]] **D5 / ArchUnit suite host** 에 의존 — 본 branch 3개 rule 을 그 suite 에 등록. suite 구조·archunit-junit5 버전(project §34, 1.3.0)이 바뀌면 본 branch 영향."},"evidence_b":{"line_end":205,"line_start":205,"quote":"> **Trace**: D1 (이벤트/server-push 스트리밍 미지원) → D3 (ArchUnit 정적 강제). 차단 대상 클래스 정의 = `SPRING-ASYNC-C4` (`SseEmitter` = `ResponseBodyEmitter` subclass, W3C SSE 포맷), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit). 메커니즘 선례 = [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (`no_problem_detail_usage` import-level 차단). suite host = boundary branch ArchUnit suite, archunit-junit5 1.3.0 (project §34)."},"proof_manifest":null,"rationale":"A21 and A33 both state the same suite-host + archunit-junit5 1.3.0 (project §34) dependency. Consistent restatement.","verdict":"CONSISTENT"},{"candidate_id":"SEM-218D815DB5C622397FCA","evidence_a":{"line_end":242,"line_start":242,"quote":" - [[raw/branch-notes/feature-api-contract-baseline]] **D17** consume (미지원 시 비동기 우회 = LRO polling). D17 계약이 바뀌면 본 branch §구현 가이드 §2 대안 경로 갱신 필요."},"evidence_b":{"line_end":228,"line_start":228,"quote":"- 비동기 server→client 결과 전달이 필요하면: [[raw/branch-notes/feature-api-contract-baseline]] **D17** LRO 패턴 (202 + `Location` + `GET /operations/{id}` polling + `Retry-After`) 사용."},"proof_manifest":null,"rationale":"A22 and A31 both restate api-baseline D17 LRO as the async alternative. Meaning preserved, consistent.","verdict":"CONSISTENT"},{"candidate_id":"SEM-B02E0005DB2E802C681F","evidence_a":{"line_end":242,"line_start":242,"quote":" - [[raw/branch-notes/feature-api-contract-baseline]] **D17** consume (미지원 시 비동기 우회 = LRO polling). D17 계약이 바뀌면 본 branch §구현 가이드 §2 대안 경로 갱신 필요."},"evidence_b":{"line_end":128,"line_start":128,"quote":"- async polling endpoint (LRO) — [[raw/branch-notes/feature-api-contract-baseline]] D17 SSOT"},"proof_manifest":null,"rationale":"A22 and A40 both point the async/LRO polling path to api-baseline D17 SSOT. Same claim.","verdict":"CONSISTENT"},{"candidate_id":"SEM-2BE5364F3E59E14F4D24","evidence_a":{"line_end":243,"line_start":243,"quote":" - [[raw/branch-notes/feature-file-resource-handling-contract]] **D8** 과 경계 공유 — `StreamingResponseBody` 소유권. D8 이 다른 streaming 클래스를 쓰기 시작하면 본 branch 비-차단 목록 재검토."},"evidence_b":{"line_end":221,"line_start":221,"quote":"- `org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody` — **차단하지 않음.** 대용량 다운로드용 응답 body 청크 전송 (`SPRING-ASYNC-C2`: \"for example, for a file download\"), 통신 모델은 request-response 유지. [[raw/branch-notes/feature-file-resource-handling-contract]] D8 (verified) 소유. blanket ban 시 다운로드 build 실패."},"proof_manifest":null,"rationale":"A23 and A28 both assign StreamingResponseBody to file-resource D8 and exclude it from blocking. Same claim, single owner.","verdict":"CONSISTENT"},{"candidate_id":"SEM-2F40C1629564F37BC388","evidence_a":{"line_end":216,"line_start":216,"quote":"| `no_sse_emitter` | `org.springframework.web.servlet.mvc.method.annotation.SseEmitter` | `noClasses().should().dependOnClassesThat().haveFullyQualifiedName(...)` | SSE server-push 의 직접 표면 (`SPRING-ASYNC-C4`) |"},"evidence_b":{"line_end":205,"line_start":205,"quote":"> **Trace**: D1 (이벤트/server-push 스트리밍 미지원) → D3 (ArchUnit 정적 강제). 차단 대상 클래스 정의 = `SPRING-ASYNC-C4` (`SseEmitter` = `ResponseBodyEmitter` subclass, W3C SSE 포맷), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit). 메커니즘 선례 = [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (`no_problem_detail_usage` import-level 차단). suite host = boundary branch ArchUnit suite, archunit-junit5 1.3.0 (project §34)."},"proof_manifest":null,"rationale":"A25 (no_sse_emitter FQN via haveFullyQualifiedName) and A33 (D1->D3 trace + SPRING-ASYNC-C4 class definition rationale) are compatible; A33 supplies the derivation for A25's rule target.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-2E4F016E793AEC4B215E","evidence_a":{"line_end":216,"line_start":216,"quote":"| `no_sse_emitter` | `org.springframework.web.servlet.mvc.method.annotation.SseEmitter` | `noClasses().should().dependOnClassesThat().haveFullyQualifiedName(...)` | SSE server-push 의 직접 표면 (`SPRING-ASYNC-C4`) |"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A25 (no_sse_emitter rule FQN detail) and A35 (D3 enforcement declared in scope) describe a concrete rule and the in-scope decision it implements.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-8B661B783F716E8FC2FE","evidence_a":{"line_end":217,"line_start":217,"quote":"| `no_response_body_emitter` | `org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter` | 동일 | SSE 의 base + incremental 객체 emit (`SPRING-ASYNC-C3`). `SseEmitter` 가 이를 상속하므로 함께 차단. **비-SSE JSON object-stream 용도까지 server-push 모델로 간주해 차단** (`UNSUPPORTED_IMPL_DECISION④`) |"},"evidence_b":{"line_end":205,"line_start":205,"quote":"> **Trace**: D1 (이벤트/server-push 스트리밍 미지원) → D3 (ArchUnit 정적 강제). 차단 대상 클래스 정의 = `SPRING-ASYNC-C4` (`SseEmitter` = `ResponseBodyEmitter` subclass, W3C SSE 포맷), `SPRING-ASYNC-C3` (`ResponseBodyEmitter` = 객체 stream emit). 메커니즘 선례 = [[raw/branch-notes/feature-boundary-validation-mapping-contract]] D5 (`no_problem_detail_usage` import-level 차단). suite host = boundary branch ArchUnit suite, archunit-junit5 1.3.0 (project §34)."},"proof_manifest":null,"rationale":"A26 (no_response_body_emitter FQN detail) and A33 (trace + SPRING-ASYNC-C3 class rationale) are compatible; A33 supplies the derivation for A26's rule target.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-564E5716DE46D0C1E730","evidence_a":{"line_end":217,"line_start":217,"quote":"| `no_response_body_emitter` | `org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter` | 동일 | SSE 의 base + incremental 객체 emit (`SPRING-ASYNC-C3`). `SseEmitter` 가 이를 상속하므로 함께 차단. **비-SSE JSON object-stream 용도까지 server-push 모델로 간주해 차단** (`UNSUPPORTED_IMPL_DECISION④`) |"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A26 (no_response_body_emitter rule detail) and A35 (D3 enforcement in scope) describe a concrete rule and the in-scope decision it implements.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-7D40F6DB6E5BEBA1584D","evidence_a":{"line_end":218,"line_start":218,"quote":"| `no_websocket_handler` | `org.springframework.web.socket..` (패키지 전체) + `jakarta.websocket..` (패키지 전체) | `dependOnClassesThat().resideInAnyPackage(...)` | spring-websocket(`WebSocketHandler`, `@EnableWebSocket`, `@EnableWebSocketMessageBroker`/STOMP) + Jakarta `@ServerEndpoint` 계열 일괄 차단 (`RFC6455-C1` full-duplex 모델). **WebSocket 표면은 단일 FQN 이 없어 `haveFullyQualifiedName` 대신 `resideInAnyPackage` glob 불가피** (`UNSUPPORTED_IMPL_DECISION③`) |"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A27 (no_websocket_handler glob detail) and A35 (D3 enforcement in scope) describe a concrete rule and the in-scope decision it implements.","verdict":"COMPLEMENTARY"},{"candidate_id":"SEM-09A4573242B3E87C3AEF","evidence_a":{"line_end":228,"line_start":228,"quote":"- 비동기 server→client 결과 전달이 필요하면: [[raw/branch-notes/feature-api-contract-baseline]] **D17** LRO 패턴 (202 + `Location` + `GET /operations/{id}` polling + `Retry-After`) 사용."},"evidence_b":{"line_end":128,"line_start":128,"quote":"- async polling endpoint (LRO) — [[raw/branch-notes/feature-api-contract-baseline]] D17 SSOT"},"proof_manifest":null,"rationale":"A31 and A40 both delegate the LRO polling path to api-baseline D17 SSOT. Same claim.","verdict":"CONSISTENT"},{"candidate_id":"SEM-77E32400AEC157801ACF","evidence_a":{"line_end":229,"line_start":229,"quote":"- 외부 시스템 push 가 필요하면: [[raw/branch-notes/feature-webhook-outbound-contract]] (미결정, forward-ref)."},"evidence_b":{"line_end":127,"line_start":127,"quote":"- async webhook 발송 — [[raw/branch-notes/feature-webhook-outbound-contract]] SSOT"},"proof_manifest":null,"rationale":"A32 and A39 both delegate outbound/async webhook (external push) to feature-webhook-outbound-contract as SSOT. Same claim, single owner.","verdict":"CONSISTENT"},{"candidate_id":"SEM-A5A09D2E3896D9A51B57","evidence_a":{"line_end":112,"line_start":112,"quote":"- 이벤트/server-push 스트리밍 지원 여부 결정 → **D1: 미지원 확정**"},"evidence_b":{"line_end":113,"line_start":113,"quote":"- 미지원의 ArchUnit 정적 강제 → **D3: `no_sse_emitter` / `no_response_body_emitter` / `no_websocket_handler`** (§구현 가이드)"},"proof_manifest":null,"rationale":"A34 (D1: event/server-push unsupported) and A35 (D3: ArchUnit static enforcement) are compatible in-scope facets — a scope decision and its enforcement — under the same 포함 범위 scope.","verdict":"COMPLEMENTARY"}]},"auditor":{"contract_version":"semantic-coherence/v1","model_id":"claude-opus-4-8","run_id":"a33f5543661c371ac"},"auditor_contract_sha256":"1cbc67c27e5183a272687f635e3682a26d56785a1cf144da562eb7edd8f6cbce","coverage":{"candidate_pairs":81,"dropped_pairs":0,"eligible_surfaces":6,"processed_pairs":81,"processed_surfaces":6},"document_id":"bf81339af7b1675cacfced0cb921ca3d9ddfcb5a5d3ad20b5643432036d705cb","document_sha256":"0bceff0596ad4407a633b3c73905f8ead3d9260b57a444cb8aa150f15dc8c0bf","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":"0606f732d28f8e01d6c740d45617df8cc86e67cad7678df4f6e0fd9c363822a6","subject":"raw/branch-notes/feature-streaming-response-contract.md","typed_contract_graph_sha256":"481fc3335a494c454ab13ad1d6a6ddccdec99aa8e083f6720ff8886bfa19cc89","verdict":"PASS"}