Files
DongHyeonkaandClaude Fable 5.1 b25357c48a docs(clean-architecture-backend-template): fold analysis into final and re-select one topic
- analysis/·source-index·state.json 을 final/document.md 제2부·제3부로 접었다. SSOT 는 하나다
- 파일럿 — commit-ambiguity-as-a-result 를 새 기준으로 재선별. 후보 14 → 글감 5
  (PROMOTE 5 · MERGE_INTO 3 · KEEP_IN_SSOT 4 · 보류 2). 기록 5건을 다시 썼고 그림 1개를
  techviz 로 만들었다
- 재선별이 잡은 것: 제1부 §6.2·§11.1 이 자기 §13.2 와 어긋나 있었다(레인을 안 돌렸다 vs
  돌렸다) — 정정. 이미 답이 나와 있던 Question 을 HEAD 재실행 질문으로 다시 세웠다.
  Concept 이 인용한 코드가 SSOT 에 없어 뺐다
- candidateScope·sourceRepository 기록. 나머지 43개 주제는 재선별 대기(PENDING 905)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 12:39:20 +09:00

3.4 KiB

id, kind, slug, title, topic, topicName, project, status, studio, decisionStatus, decidedOn, source, sourceRevision
id kind slug title topic topicName project status studio decisionStatus decidedOn source sourceRevision
PROJECT_DECISION completion-unknown-is-never-retried completion-unknown 은 자동으로도 수동으로도 재시도하지 않는다 commit-ambiguity-as-a-result 커밋 모호성 — 「모른다」를 결과로 유지하기 clean-architecture-backend-template 게시 전 ADOPTED 2026-08-11
final/document.md#10-2
final/document.md#4-1
21234e38cdb9a926cbc92bb97a2aee2e4a7d2916

completion-unknown 은 자동으로도 수동으로도 재시도하지 않는다

커밋 결과를 알 수 없는 실패는 조정으로 넘기고 어느 경로로도 재시도하지 않는다. 이 불변식은 정책이 아니라 생성자가 강제한다.

근거

  • pg_terminate_backend 가 57P01 로 도착하고 커밋 레코드는 이미 WAL 에 있었다 이 결정이 다루는 실패가 실제로 어떤 모습인지 보여 주는 사례다.
  • 모르는 것은 성공도 실패도 아닌 세 번째 결과여야 한다 이 결정이 전제하는 상태 어휘다.
  • 트랜잭션 결과 대수 — 다섯 변형이 각각 답하는 질문 재시도 금지가 어느 변형에 붙는지를 정의한다.

결정문

관측된 단계가 COMMITTING 이고 드라이버가 결과를 말해 주지 못한 실패는 completion-unknown 으로 분류하고, 자동 재시도 정책과 수동 재실행 경로 양쪽에서 제외한다.

판단 이유

이 실패는 일시적인 것이 아니라 인식론적이다. 연결이 커밋 도중에 끊기면 서버는 커밋했을 수도 있고 확인 응답만 유실됐을 수도 있는데, 드라이버는 그 둘을 구별하지 못한다.

커밋됐을 수도 있는 쓰기를 재실행하는 것은 이 플랫폼이 할 수 있는 가장 해로운 동작이다. 재시도가 성공하면 중복이 생기고, 그 중복은 원래 실패보다 알아채기 어렵다.

그래서 정책이 아니라 타입이 그 조합을 막는다. JpaFailureContext 의 생성자는 completionUnknown 과 retryable 이 동시에 참인 컨텍스트를 IllegalArgumentException 으로 거부한다. 그 검사는 트랜잭션 결과 대수 기록의 생성자 절에 코드로 있다.

리뷰 규칙으로 두면 그 조합을 만드는 경로마다 같은 검사가 필요하다. 생성자가 거부하므로 그 조합을 가진 값은 프로그램 안에 존재하지 않는다.

방어는 두 겹 더 있다. TransactionCompletionUnknownException 의 생성자는 forceCompletionUnknown 으로 컨텍스트를 다시 만들어 재구성 경로가 검사를 우회하지 못하게 한다. RetryProfile 은 COMPLETION_UNKNOWN 을 화이트리스트에 넣는 것을 생성자에서 거부한다.

영향

감수하는 것 : 조정 큐가 생기고 그것을 읽는 운영 절차가 필요하다. 자동으로 해소되지 않는 항목이 쌓인다.

감수하는 것 : 실제로는 롤백된 트랜잭션도 조정으로 넘어간다. 드라이버가 말해 주지 않았으므로 구별할 수 없다.

감수하는 것 : 큐가 무의미해지지 않도록 모호성 판정 조건을 좁게 유지해야 한다. 넓히면 평범한 풀 고갈과 서버 재시작이 큐로 밀려들고, 운영자는 큐를 읽지 않고 비우는 습관을 배운다.

얻는 것 : 중복 쓰기가 자동 경로에서 발생하지 않는다.

얻는 것 : 모르는 것이 상태로 남아 나중에 사람이 판단할 재료가 보존된다.