ADR の書き方
このガイドが解く問題: 記録に値する決定があり、
templates/5_adr.mdを目の前にしている。各セクションに何を書くか、何を書か ない か、ADR がよく失敗する典型を避ける方法は? このガイドは MADR v3.0 に特化した深掘りで、汎用の how-to/choose-the-right-template.md を補完します。
これは how-to です ―― すでに ADR が正しい artefact だと決めた前提(未確認なら choose-the-right-template.md §よくある混同 #2 から)。
形式の正本リファレンスは MADR v3.0 です。本ページはその上に 運用ガイダンス を重ねます ―― pentaglyph プロジェクトでフォーマットをどう使いこなすか。
- 1 ADR 1 決定。決定文に「かつ / と」が入っているなら分割
- Status は
Proposedで始める。チームレビュー後にのみAccepted。AcceptedADR の本文を編集してはいけない ―― 新 ADR で supersede する Alternativesセクションは必須。代替案を検討していないなら、アーキテクチャ判断ではなく default を持っているだけ- ファイル名:
arc42/09-decisions/NNNN-<kebab-title>.md。NNNNは次の連番 4 桁、0 埋め - 相互リンク: 決定をトリガした PRD、それを実装する Module DD、ベースまたは supersede 関係の先行 ADR
ステップバイステップ
Section titled “ステップバイステップ”1. 番号を選ぶ
Section titled “1. 番号を選ぶ”arc42/09-decisions/ の中で最大の既存 ADR 番号を探す:
ls docs/arc42/09-decisions/ | grep -E '^[0-9]{4}-' | sort | tail -1次の連番 4 桁を使う。「将来のカテゴリ用」にギャップを予約しないこと ―― 番号は 単なる識別子 で、階層ではありません。番号予約は ADR 連番に紛らわしい穴を作る最頻出の失敗パターンです。
2. テンプレートをコピー
Section titled “2. テンプレートをコピー”cp docs/templates/5_adr.md docs/arc42/09-decisions/NNNN-<kebab-title>.mdあるいは Claude に頼む(prompt-cookbook §3):
docs/templates/5_adr.mdから ADR を書いて、次の決定を記録:<1 文サマリ>。docs/arc42/09-decisions/<next-NNNN>-<kebab-title>.mdに配置。StatusProposed。必須セクションをすべて埋めて。
3. タイトルを書く
Section titled “3. タイトルを書く”タイトルは 決定そのもの であって、トピックではありません。動詞句として書く:
| ✅ Good(決定) | ❌ Bad(トピック) |
|---|---|
| 「主永続化に PostgreSQL を採用」 | 「データベース選定」 |
| 「first-party クライアントに OAuth 2.1 PKCE を使用」 | 「認証」 |
| 「async ジョブを in-process でなく Cloudflare Queues で実行」 | 「ジョブ処理」 |
「〜-tion」「〜選定」名詞で終わるタイトル(Authentication、Selection、Processing)はほぼ常に間違った形です。読者がタイトルから何が決まったか分かりません。
4. Context を書く(何 と なぜ)
Section titled “4. Context を書く(何 と なぜ)”2〜4 文。要素 2 つ:
- forcing function(駆動要因)。コードベース・プロダクト・制約で何が変わってこの決定が必要になったか?「v1 API を Q2 にリリースする必要」/「PoC のデータベースが負荷テストで接続上限を超えた」/「コンプラレビューがログ 90 日保持を要求」
- decision space。決定の瞬間にテーブル上にあった候補アプローチ。選ばれたもの(後で出てくる)ではなく、選んだ space
4 文を超えそうなら、議論を narrate している可能性大。要点に切り詰めて。
アンチパターン: ミーティング議事録のような Context(「Alice が問題を提起、それから Bob が…」)。ADR は永続記録であってチャットログではない。
5. Decision を書く(何を選んだか)
Section titled “5. Decision を書く(何を選んだか)”1〜3 文。選んだオプションを明確に宣言。読者は このセクション単体で実装できる べき。
例:
ユーザー / 注文 / 監査テーブルの主永続化に PostgreSQL 16 を使う。スキーマは
db/migrations/にあり、Alembic でバージョン管理。Read replica はこの決定のスコープ外(ADR-0024 を参照)。
最後の節に注目: スコープ 外 を明示的に印付けすると、将来の読者がこの ADR がカバーしていないものをカバーしていると誤解するのを防げます。
6. Consequences を書く(何が続くか)
Section titled “6. Consequences を書く(何が続くか)”ここで ADR は価値を稼ぎます。3 つのサブセクション:
Positive consequences。どんな良い結果を期待するか? 具体的に:「検索ユースケース向けに pg_vector を解放」が「より良い技術基盤」より優れる。
Negative consequences。何をコストとして受け入れているか?「SQLite に対する運用複雑度の増加 ―― バックアップ・レプリケーション・バージョン更新手順が必要に」。negative セクションがトレードオフを真剣に取った証拠です。
Neutral consequences。良くも悪くもないが続くもの。空でも構いません。
アンチパターン: 空の
Negative consequences。downside を 1 つも挙げられないなら、決定を実際に weigh していない ―― rationalize しているだけ。小さくてもいいので最低 1 つコストを挙げる。
7. Alternatives を書く(何を却下したか、なぜか)
Section titled “7. Alternatives を書く(何を却下したか、なぜか)”最も重要なセクション。真剣に検討した各代替案を、却下の具体的な理由 と共にリストアップ。
代替案ごとの形式:
#### SQLite
検討理由: 低い運用オーバーヘッド、組み込みデプロイ。
却下理由: 負荷テストで同時 ~200 エージェントで接続プール枯渇。500 エージェント目標を下回る。WAL モードで改善するもギャップを埋めず。避けるべき 2 つの失敗モード:
| 失敗 | 例 | 修正 |
|---|---|---|
| わら人形代替案 | 「フラットファイルを検討。遅い」(誰も真剣に提案していない) | 5 分以上真剣に検討された代替案のみリスト |
| 漠然とした却下理由 | 「MongoDB を検討。document store はユースケースに合わない」 | 失格させた 具体的な特性 を挙げる。「スキーマドリフトが migration layer での厳密型付けを妨げる」、ではなく「合わない」では不可 |
本当に代替案がなかったなら(プラットフォームが選択を強制したなど)、それはアーキテクチャ判断ではなく制約です。arc42/09-decisions/ ではなく arc42 §2(Constraints)に記録。
8. front-matter を埋める
Section titled “8. front-matter を埋める”---status: Proposed # → review 後 Accepted → 置換時 Supersededdate: 2026-05-17deciders: ["alice", "bob"] # GitHub handle または名前supersedes: 0007 # この ADR が別の ADR を置換する場合のみsuperseded-by: ~ # 後でこの ADR が supersede されたら埋める---deciders: 3 か月後に「なぜ?」と聞ける人々。チーム全員ではなく、実際にトレードオフを weigh した 2〜4 人supersedes: 古い ADR を置換するときに名指す。次に 古い ADR の front-matter を更新 してsuperseded-by: <this-NNNN>とstatus: Supersededをセット。古い ADR の本文は編集しない
9. 相互リンク
Section titled “9. 相互リンク”双方向リンクを追加:
- PRD から(該当する場合): 「決定は ADR-NNNN に記録」の行を追加
- PRD へ: ADR Context セクションに「[PRD link] によって駆動」の行
- それを実装する Module DD から: 「ADR-NNNN に従い、~~~を使う」の行
- 先行 ADR との間: 特に supersede チェーン
相互リンクが 6 か月後に ADR を findable にする要素です。リンクのない ADR はデッドウェイトです。
10. Accept してもらう
Section titled “10. Accept してもらう”Status flow:
Proposed → Accepted (チームレビューが承認したあと)Proposed → Rejected (チームが提案に反対した場合)Accepted → Superseded (後の ADR が置換する場合)Proposed → Accepted 遷移だけがチーム sign-off を要します。他は事実の記録で、許可を求めていません。
Rejected ADR はディスクに残す。削除しないこと ―― 却下に至った推論は価値があります。status: Rejected をセットし、本文は無傷で残す。
ADR で ない もの
Section titled “ADR で ない もの”最頻出の失敗モードは、ADR ラベルの下に間違った artefact を書くことです:
| ADR に見えるが違うもの | 正しい置き場 |
|---|---|
| 実装詳細付きの小さなデザイン doc | detailed-design/<module>.md |
| チームが従うべき「原則」「ガイドライン」リスト | design-guide/<topic>.md |
| ミーティングサマリ | Slack メッセージか Notion ページ。リポジトリ外 |
| レトロスペクティブの気づき | task-list/YYYY-MM-DD_sprint-NN-retro.md |
| 外部からの制約(規制・プラットフォーム) | arc42 §2 Constraints |
| 関連するから bundle した 3 決定 | 3 つの別 ADR、相互リンク |
迷ったら自問: 「将来の読者が、Decision セクションだけから実装できるか? Alternatives セクションが「でも X は?」という当然の疑問に答えているか?」 YES なら valid な ADR。NO なら上の表のいずれか変装したもの。
ADR はどのくらいの長さであるべきか?
Section titled “ADR はどのくらいの長さであるべきか?”MADR の例と我々の経験は同じ答えに収束します: 半ページから 1 ページ がスイートスポット。
- 100 語未満 は通常、3 か月後に決定を defend するには薄すぎ
- 600 語超 は通常、実装詳細を ADR に引きずり込んでいる。Module DD に移す
長い ADR は「より厳密」ではなく、通常はより load-bearing でないです。規律は どの段落が生き残るか であって、 何段落書いたか ではありません。
Supersede vs amend
Section titled “Supersede vs amend”最終的には決定を変える必要が出てきます。ルール:
| 変更タイプ | やること |
|---|---|
| typo・broken link・欠落した front-matter フィールド | 既存ファイルを直接編集 |
| 決定 そのもの が変わる(PostgreSQL をやめて CockroachDB に) | 新 ADR を supersedes: <old NNNN> 付きで書く。古い本文を編集しない |
| 決定が部分的に obsolete(依然 PostgreSQL だが read replica 追加) | 古い ADR を 拡張 する新 ADR を書く。古いものは Accepted のまま。新 ADR の Context が古いものを引用 |
「Accepted 本文を編集しない」が非交渉なのは、ADR の価値が安定した歴史記録だからです。編集者が過去の決定を書き直せるなら、audit trail は崩壊します。新 ADR を書くコストは 低い(1 ページ)。trail を腐らせるコストは 高い(チームが ADR を信頼しなくなる)。
merge 前のチェックリスト
Section titled “merge 前のチェックリスト”- タイトルは動詞句、名詞ではない
- 1 決定、bundle しない
- Context が forcing function と decision space を名指している
- Decision セクションがそれ単体で実装可能
- Consequences に negative が最低 1 つ含まれる
- Alternatives セクションに具体的な却下理由付きで 2 件以上
- front-matter に
status、date、deciders - PR タイトルと説明が ADR を参照
- 別 ADR を supersede するなら、古い ADR の front-matter が本文編集なしで更新済み
- 長さは 100〜600 語
../../template/docs/templates/5_adr.md— MADR v3.0 テンプレート- MADR v3.0 specification — 正本フォーマットリファレンス
- Y-statements (Olaf Zimmermann) — よりタイトな ADR variant。MADR テンプレと互換
- Michael Nygard の原典 ADR エッセイ (2011) — practice の起源
- how-to/choose-the-right-template.md §よくある混同 #2 — ADR vs Module DD
- how-to/prompt-cookbook.md §8 — ADR を supersede — エージェント駆動 supersede フロー