--- id: kind: CONCEPT slug: publish-evidence-and-completion title: 발행 증거와 완료 판정이 따로 있는 이유 topic: commit-ambiguity-as-a-result topicName: 커밋 모호성 — 「모른다」를 결과로 유지하기 project: clean-architecture-backend-template status: 게시 전 studio: "" basisVersion: sourceRevision 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 source: - final/document.md#a19 - final/document.md#3-3 - final/document.md#a19 §3.2 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 --- # 발행 증거와 완료 판정이 따로 있는 이유 실패가 발생했다는 사실과 외부 시스템이 작업을 받아들였다는 사실은 같은 정보가 아니다. 이 프로젝트는 전송·발행 증거를 먼저 기록하고, 그 증거를 바탕으로 완료 상태를 별도로 판정한다. ## 관계 - **증거를 먼저 기록하고 결론은 나중에 고른다** 이 개념을 프로젝트 결정으로 고정한 기록이다. - **트랜잭션 결과 대수 — 다섯 변형이 각각 답하는 질문** 완료를 성공·실패 두 값으로 접지 않는 타입 모델을 설명한다. - **completion-unknown 은 자동으로도 수동으로도 재시도하지 않는다** 완료를 모르는 상태가 재실행 권한으로 바뀌지 않게 한 결정이다. ## 본문 ## 증거와 결론은 서로 다른 질문에 답한다 전송 증거는 프로세스 밖으로 무엇이 나갔는지를 답한다. 완료 판정은 그 증거를 바탕으로 호출자가 무엇을 주장해도 되는지를 답한다. 아무 바이트도 나가지 않은 실패라면 동일 작업을 다시 시도해도 외부 중복을 만들 가능성이 낮다. 반대로 요청이 wire에 올라갔거나 커밋 요청이 전달된 뒤 응답을 잃었다면 같은 예외 타입이라도 결과를 실패로 단정할 수 없다. ## 표현할 수 없는 조합을 타입에서 막는다 SSOT의 `JpaFailureContext`는 completion-unknown과 retryable이 동시에 참인 값을 거부한다. 이 제약은 정책 문구가 아니라 생성 가능한 상태 집합을 제한한다. 이 구조의 목적은 “실패 종류를 더 세밀하게 이름 붙이기”가 아니다. 먼저 관측한 사실을 보존하고, 그 다음 단계가 그 사실보다 강한 결론을 만들지 못하게 하는 것이다. ## 완료 판정은 증거를 소비한다 커밋 요청 전 실패, 커밋 요청 뒤 확인된 롤백, 커밋 확인, 결과 불명은 서로 다른 완료 상태가 된다. 같은 원칙은 메시지 발행에도 적용된다. 전송되지 않음과 전송됐을 가능성을 구분해야 retry나 reconciliation 정책이 사실보다 앞서가지 않는다. ## 이 개념이 보장하지 않는 것 증거를 분리했다고 실제 외부 상태를 자동으로 알아내는 것은 아니다. completion-unknown은 “모른다”를 정확히 표현할 뿐이다. 실제 결과 확인은 reconciliation이나 별도 운영 절차가 맡는다. 현재 머신에는 source repository가 없어 이 sourceRevision의 코드 경로를 다시 실행하지 않았다. 이 기록은 SSOT가 고정한 분석 결과를 설명한다.