[Review] The Habit of Writing Down Failure Model and Trust Assumptions First TODO
Concept
In distributed systems design, what any given algorithm guarantees is always a function of its assumptions, so the first line of a design doc should be its failure model and trust assumptions. Failure models range from crash-stop (a node halts and stays halted), to crash-recovery (it halts and later comes back), to omission (it drops messages), to Byzantine (it can lie arbitrarily) — and the required quorum size and cost both grow as you move further down that list. Timing models split into synchronous, partially synchronous, and asynchronous; it's a known result that deterministic consensus is impossible in a fully asynchronous model with even a single crash failure. Trust assumptions cover things like the fraction of honest nodes, the existence of authenticated channels and signatures, bounds on clock skew, and which parties are considered trustworthy at all. Without stating these explicitly, there's no way to discuss what safety or liveness gets sacrificed and when, and no way to attribute an incident's cause to a violated assumption after the fact.
Most real outages aren't code bugs — they're an undocumented assumption quietly breaking. If the assumption was never written down, there was never a way for review to catch its violation in the first place.
Code & Formula
# [복습] 장애 모델과 신뢰 가정을 먼저 쓰는 습관 — 컴포넌트별 장애 모델·타이밍 모델·정족수를 명시하고 위반 시 무엇이 무너지는지 판정한다.
# 가정을 표로 적어두면 "안전성 vs 활성 중 무엇을 먼저 잃는가"를 코드 없이도 기계적으로 도출할 수 있다.
components = [
{"name": "체인 합의", "failure_model": "byzantine", "timing": "partial-sync", "quorum_desc": "2f+1 of 3f+1"},
{"name": "오라클", "failure_model": "crash-recovery", "timing": "async", "quorum_desc": "1-of-N 정직한 리포터"},
{"name": "시퀀서", "failure_model": "crash-stop", "timing": "sync", "quorum_desc": "단일 운영자(정족수 없음)"},
]
def assess(c):
if "단일" in c["quorum_desc"]:
return "활성 취약: 운영자 장애 시 서비스 정지 / 안전성은 유지"
if c["failure_model"] == "byzantine":
return "안전성: 악의 노드 < 1/3이면 유지 / 활성: partial-sync 가정이 깨지면 정지"
if c["timing"] == "async":
return "안전성 유지 가능 / 활성: 메시지 지연이 무한하면 정지 보장 불가"
return "안전성: 장애 수 < 정족수면 유지 / 활성: 정족수 확보 시 유지"
for c in components:
print(f"[{c['name']}] 장애모델={c['failure_model']}, 타이밍모델={c['timing']}, 정족수={c['quorum_desc']}")
print(f" -> 판정: {assess(c)}")
docs/code/algorithms/algorithms-68.py
Exercise
Pick one component of the system you're currently working on and write one line each for its failure model, timing model, trusted parties, and quorum assumptions, then table out which of safety or liveness breaks first when each assumption is violated.
Practical Connection
A prediction market has the chain, the oracle, the sequencer, and its own backend each carrying a different failure model and trust level, so writing this out on one page makes it immediately clear what needs defending during a settlement dispute or an oracle delay.
Where it lands in Jayverse
- Verex: write a one-page failure-model doc per component — chain, oracle, sequencer/Devnet, backend — listing failure model, timing model, and trusted parties, and table which of safety or liveness breaks first for each. Required before any settlement-dispute runbook exists.
- Auditor: use that one-page doc as what gets checked during an incident — was the component's stated failure model actually the one that broke, or was an undocumented assumption violated instead.
- Rabbit: give session-key mandate execution (bundler/relayer) its own failure-model line — crash-stop, omission, or Byzantine — since a mandate's safety guarantee depends on which one actually holds.
Key expressions
| Expression | 뜻 · 쓰이는 자리 |
|---|---|
| crash-stop | 정지 후 고장(크래시-스탑) 모델 · 한 번 멈추면 영원히 멈추는 장애 모델. "crash-stop (a node halts and stays halted)" |
| attribute ... to | (원인을) ~탓으로 돌리다, 귀속시키다 · 장애 원인을 특정 가정 위반으로 지목하는 것. "attribute an incident's cause to a violated assumption" |
| quietly breaking | 조용히(눈에 안 띄게) 깨지다 · 아무도 모르는 사이에 가정이 위반되는 상황. "an undocumented assumption quietly breaking" |
| the first line of | ~에서 가장 먼저 적어야 할 것 · 설계 문서에서 최우선으로 명시할 항목을 강조. "the first line of a design doc should be" |
| sacrifice (동사) | (안전성·생존성을) 희생시키다, 포기하다 · 트레이드오프에서 어느 속성을 내주는지 가리킴. "what safety or liveness gets sacrificed" |
| known result | 이미 증명된 사실, 정설 · 학계에서 입증되어 통용되는 결론을 가리킴. "it's a known result that deterministic consensus is impossible" |
| carry (a failure model) | (장애 모델·신뢰 수준을) 지니다, 내포하다 · 시스템 구성요소마다 서로 다른 전제를 갖고 있음을 표현. "carrying a different failure model and trust level" |
| crash-recovery | 정지 후 복구 장애 모델 · 노드가 멈췄다가 나중에 다시 살아나는 것을 가정하는 모델. "crash-recovery (it halts and later comes back)" |
| omission | 메시지 누락 장애 모델 · 노드가 일부 메시지를 그냥 흘려버리는(전달 실패) 장애 유형. "omission (it drops messages)" |
| Byzantine | 비잔틴(임의 고장, 악의적 행동) · 노드가 임의로 거짓말할 수 있다고 가정하는 가장 강한 장애 모델. "Byzantine (it can lie arbitrarily)" |
| quorum | 정족수 · 결정을 내리기 위해 필요한 최소 노드 동의 수. "the required quorum size and cost both grow" |
| liveness | 생존성 · 시스템이 결국 진전(응답)한다는 보장, 안전성(safety)과 짝을 이루는 속성. "what safety or liveness gets sacrificed" |
If you study this on a given day, add a note link and a ✅ to this line in the source curriculum (docs/knowledge/dev-100-curriculum.md) and this spot will lead straight to the note body. You can also write directly on this page — but regenerating overwrites it, so it's safer to keep anything you want to save as markdown under docs/algorithms/.