- 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>
3.5 KiB
kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, evidenceCapturedOn, assets, evidence, source, module
| kind | slug | title | topic | project | status | sourceRevision | rootTreeNode | evidenceCapturedOn | assets | evidence | source | module | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| CONCEPT | application-core-c04 | 효과가 없었다고 증명할 수 없으면 자동 재시도 권한을 주지 않는다 | state-machines-and-ownership | clean-architecture-backend-template | 게시 전 | 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 | concept:application-core-c04 | 2026-09-01 |
|
|
|
application-core |
효과가 없었다고 증명할 수 없으면 자동 재시도 권한을 주지 않는다
idempotency V2와 inbox와 outbox 셋이 각각 응답을 잃은 구간을 상태로 보존한다.
관계
- legacy storage/notification compatibility surface의 제거 조건 추적 같은 분석 리프에서 끌어낸 규칙이다.
본문
초기 contract는 scope + request fingerprint로 claim/replay를 제공하고, same key/different fingerprint를 conflict로 분리한다. completed result는 replay하고 in-flight는 bounded poll한다. 이 버전은 "DB operation의 효과가 이미 발생했지만 응답만 잃은 상태"를 충분히 표현하지 못한다.
응답을 잃은 구간을 맡는 세 장치
:::evidence key="application-core-c04-diagram" alt="응답을 잃은 구간에서 멱등 기록과 인박스와 아웃박스 세 상자로 화살표가 나가고 화살표마다 담당 방식이 붙은 구조" caption="응답을 잃은 구간을 맡는 세 장치" zoom="false" :::
V2는 owner-safe CAS handle에 scope/token/attempt/revision/claimOperationId를 넣고 stale owner mutation을 거부한다. processing-start를 durable하게 확인하기 전에는 body를 실행하지 않으며 claim/start/completion의 unknown result는 inspect/reconcile 대상으로 남긴다.
증명할 수 없는 것을 재시도 근거로 쓰지 않는다
processing start 이후 ordinary RuntimeException은 효과가 없다고 증명할 수 없으므로 EFFECT_UNKNOWN_ABANDONED 쪽으로 분류되고 자동 replay 권한을 주지 않는다. 명시적인 RetryableNoEffect만 안전 재시도 근거로 취급한다.
RetryableNoEffect 참조 위치
:::evidence key="application-core-c04" alt="코드베이스에서 RetryableNoEffect 를 검색한 출력 4줄. 이 기록이 세는 참조가 그 출력에 그대로 보인다." caption="RetryableNoEffect 코드베이스 검색 — 4줄 · exit 0" zoom="true" :::
bounded 하게 만든 것들
scope digest는 versioned keyed digest + operation code로 정규화되고 raw identity는 외부 surface에서 제거된다. lease/replay TTL과 owner token grammar도 bounded다.
Historical evidence. V2 contract가 인접한 package에 중복 복제돼 구현체들이 서로 다른 nominal type을 참조한 문제가 있었고, singular contract를 유지하는 regression test가 존재한다.
inbox 상태 모델
Inbox contract는 same-store 처리와 owner-safe receive/process state를 모델링한다. RECEIVED -> PROCESSING -> COMPLETED/RETRYABLE/DEAD 상태를 가지고 ACK는 handler transaction commit 이후에만 가능하다. expired owner가 늦게 결과를 기록하는 것을 owner token/attempt/revision/operation identity로 막는다.