[Final] Write one ADR plus one threat model for your own stack TODO
Concept
An ADR (Architecture Decision Record) briefly documents a single architectural decision — the context, the alternatives considered, the choice and its rationale, and the resulting consequences and accepted trade-offs; accumulating these records over time preserves why the system looks the way it does today. A threat model draws the assets that need protecting and the trust boundaries around them, then for each boundary lists what an attacker can do and what they're after, along with the mitigations and the residual risk that remains. What the two documents share is that they record the premises and the alternatives, not just the conclusion — which means that when a premise changes, there's an automatic signal that the decision needs to be revisited. What matters more than format is keeping the scope narrow — one decision, one system — so the document actually gets read all the way through.
An undocumented decision gets treated, a few months later, as an arbitrary constraint with no reason behind it and gets quietly reversed — and the threat it was blocking comes back to life along with it.
Code & Formula
# [Final] 내 스택의 ADR + 위협 모델 한 편 쓰기 — 코드 대신, 채워 넣기만 하면 되는
# ADR/위협 모델 템플릿을 구조화된 형태로 출력한다 (범위: 결정 하나, 시스템 하나로 좁힐 것).
ADR_TEMPLATE = {
"title": "결정 제목 (예: '오라클 결과 확정 방식으로 낙관적 제안+이의제기 채택')",
"context": "왜 이 결정이 필요했는가 — 제약, 요구사항, 지금 상태",
"alternatives": ["검토한 대안 1과 기각 이유", "검토한 대안 2와 기각 이유"],
"decision": "실제 선택과 그 근거",
"consequences": "이 결정으로 생기는 결과와 감수하는 트레이드오프",
}
THREAT_MODEL_TEMPLATE = {
"asset": "보호해야 할 자산 (예: 사용자 예치금, 오라클 결과값, 개인키)",
"trust_boundary": "신뢰 경계가 어디인가 (예: 온체인 vs 오프체인, 컨트랙트 vs 오퍼레이터)",
"attacker_capability": "각 경계에서 공격자가 할 수 있는 것 (예: 트랜잭션 순서 조작, 오라클 값 지연)",
"mitigation": "대응책 (예: 이의제기 기간, 다중서명, 타임락)",
"residual_risk": "대응 후에도 남는 위험과, 그 위험을 누가 감수하는가",
}
def print_section(title, template):
print(f"\n== {title} ==")
for key, value in template.items():
if isinstance(value, list):
print(f"- {key}:")
for item in value:
print(f" · {item}")
else:
print(f"- {key}: {value}")
def check_completed(template):
# 빈 칸(placeholder 그대로) 없이 실제로 채워졌는지 확인하는 게이트
missing = [k for k, v in template.items() if not v]
return len(missing) == 0, missing
print_section("ADR 템플릿", ADR_TEMPLATE)
print_section("위협 모델 템플릿", THREAT_MODEL_TEMPLATE)
adr_ok, adr_missing = check_completed(ADR_TEMPLATE)
tm_ok, tm_missing = check_completed(THREAT_MODEL_TEMPLATE)
print(f"\nADR 작성 완료 게이트 통과: {adr_ok} (누락: {adr_missing})")
print(f"위협 모델 작성 완료 게이트 통과: {tm_ok} (누락: {tm_missing})")
print("\n다음 100일 사이클로 넘어가기 전, 실제 값으로 위 두 템플릿을 채운 문서 한 편을 남길 것.")
docs/code/algorithms/algorithms-100.py
Exercise
Pick one decision from your own stack that was actually debated, write one ADR for it, then write one threat model for the same component covering assets, trust boundaries, attacker capabilities, mitigations, and residual risk.
Practical Connection
In a prediction market, trust assumptions concentrate around finalizing the oracle's result and settlement authority, so spelling out in a threat model who can change a result and under what conditions a dispute is possible makes both design discussions and audits much easier.
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/.