writing-adrs

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Writing ADRs

撰写ADR

ADRs live in
docs/adr/
and use sequential numbering:
0001-slug.md
,
0002-slug.md
, etc.
Create the
docs/adr/
directory lazily — only when the first ADR is needed.
ADR存储于
docs/adr/
目录,采用连续编号命名:
0001-slug.md
0002-slug.md
等。
仅在需要创建首份ADR时,才按需创建
docs/adr/
目录。

Template

模板

md
undefined
md
undefined

{Short title of the decision}

{决策简短标题}

{1-3 sentences: what's the context, what did we decide, and why.}

That's it. An ADR can be a single paragraph. The value is in recording *that* a decision was made and *why* — not in filling out sections.
{1-3句话:背景信息、我们做出的决策及原因。}

仅此而已。一份ADR可以只是一个段落。其价值在于记录**已做出决策**及**决策原因**,而非填写繁琐的章节。

Optional sections

可选章节

Only include these when they add genuine value. Most ADRs won't need them.
  • Status frontmatter (
    proposed | accepted | deprecated | superseded by ADR-NNNN
    ) — useful when decisions are revisited
  • Considered Options — only when the rejected alternatives are worth remembering
  • Consequences — only when non-obvious downstream effects need to be called out
仅当这些章节能带来实际价值时才添加。大多数ADR无需包含这些内容。
  • 状态前置元数据(
    proposed | accepted | deprecated | superseded by ADR-NNNN
    )——当决策需要重新审视时很有用
  • 备选方案——仅当被否决的替代方案值得留存记录时才添加
  • 影响——仅当存在不明显的后续影响需要明确指出时才添加

Numbering

编号规则

Scan
docs/adr/
for the highest existing number and increment by one.
扫描
docs/adr/
目录,找到现有最高编号,然后递增1即可。

When to write an ADR

何时撰写ADR

All three of these must be true:
  1. Hard to reverse — the cost of changing your mind later is meaningful
  2. Surprising without context — a future reader will look at the code and wonder "why on earth did they do it this way?"
  3. The result of a real trade-off — there were genuine alternatives and you picked one for specific reasons
If a decision is easy to reverse, skip it — you'll just reverse it. If it's not surprising, nobody will wonder why. If there was no real alternative, there's nothing to record beyond "we did the obvious thing."
必须同时满足以下三个条件:
  1. 难以逆转——后续改变决策的成本很高
  2. 缺乏上下文会令人困惑——未来的读者查看代码时会疑惑“他们到底为什么要这么做?”
  3. 是权衡后的结果——存在真正的备选方案,且你因特定原因选择了其中一个
如果决策容易逆转,无需撰写——直接修改即可。如果决策不会让人困惑,没人会问原因。如果没有真正的备选方案,除了“我们做了显而易见的选择”之外,没有什么可记录的。

What qualifies

符合撰写条件的场景

  • Architectural shape. "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres."
  • Integration patterns between contexts. "Ordering and Billing communicate via domain events, not synchronous HTTP."
  • Technology choices that carry lock-in. Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out.
  • Boundary and scope decisions. "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s.
  • Deliberate deviations from the obvious path. "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate.
  • Constraints not visible in the code. "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract."
  • Rejected alternatives when the rejection is non-obvious. If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months.
  • 架构形态:“我们采用单体仓库(monorepo)。”“写模型基于事件溯源,读模型投影至Postgres。”
  • 上下文间的集成模式:“订单与计费模块通过领域事件通信,而非同步HTTP请求。”
  • 存在锁定效应的技术选型:数据库、消息总线、认证提供商、部署目标。并非每个库都需要记录——仅记录那些需要耗时一个季度才能替换的技术。
  • 边界与范围决策:“客户数据归属于客户上下文;其他上下文仅通过ID引用它。”明确的“不做什么”和“做什么”同样有价值。
  • 刻意偏离常规路径的决策:“我们使用手动SQL而非ORM,原因是X。”任何合理读者会做出相反假设的情况。这些记录能防止后续工程师“修复”那些刻意设计的内容。
  • 代码中不可见的约束:“因合规要求,我们无法使用AWS。”“因合作方API协议,响应时间必须控制在200ms以内。”
  • 非显而易见的否决备选方案:如果你考虑过GraphQL但因微妙原因选择了REST,请记录下来——否则半年后会有人再次提议使用GraphQL。