record-a-decision について
record-a-decisionは、プロジェクトのdecisions/ディレクトリにアーキテクチャ決定レコード(ADR)を作成するスキルです。決定の確定を確認し、背景、代替案、結果、関連レコードへのリンクを記録する手順を示します。
主な機能
- 01決定が確定済みか確認
- 02既存レコードを検索して矛盾を確認
- 03テンプレートから番号付きADRを作成
- 04背景、選択、結果を記録
- 05置き換え関係を管理して検証
活用シーン
- 01承認済みの技術選択を記録
- 02旧決定を置き換え、履歴を保持
- 03ADRを提案や実装仕様にリンク
MCP 対応
Markdown操作にはプラットフォームの/open-knowledgeスキルを利用し、そのsearch、exec、write、edit、links、auditツールでADRを作成・検証します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ inkeep/ open-knowledge-skills --skill record-a-decisionインストール後、Claude Code で/record-a-decisionを入力して読み込まれたか確認します。
詳細
決定を記録する — decisions/ に ADR を作成する
プラットフォームの /open-knowledge スキルは、ここでのすべての Markdown 操作(根拠の提示、リンク付け、対象範囲内の Markdown は OK の MCP ツールが管理するというルール)にも引き続き適用されます。このスキルは、その上に ADR の作成方法を加えます。
アーキテクチャ決定記録(ADR)は、1 つの決定、その決定が必要になった要因、そしてチームが今後受け入れなければならないことを記録する、日付入りの簡潔な確定文書です。その価値は年月とともに積み重なります。3 年後に加わった読者も、何を決めたかだけでなく、そもそもなぜ検討課題になったのかを理解できるはずです。ADR は承認後に凍結されます。考えが変わっても書き換えず、新しい記録で置き換え、古い記録は履歴として残します。この置き換えの連鎖が、誠実な意思決定ログと古い意見の寄せ集めを分けます。
ファイル名は NNNN-title.md(4 桁のゼロ埋め連番 + ケバブケースのタイトル)です。ステータスの語彙は proposed / accepted / deprecated / superseded です。テンプレート ID は decision、本文のセクションは ## Context、## Decision、## Consequences の順で、これ以外は使用しません。
ステップ 0 — 実際に決定が下されたことを確認する(必須ゲート)
ADR は決定を記録するものであり、決定を下すものではありません。 何よりも先に、選択が確定していることを確認してください。
- ユーザーがまだ選択肢を検討している、アプローチを比較している、または「X と Y のどちらにすべきか」と尋ねている場合、まだ決定には至っていません。そこで作業を止め、
/frame-a-proposalスキルに案内してください。 提案書では選択肢を検討し、議論します。ADR では確定した結論を記録します。ユーザーが下していない決定を記録すると、後の読者を誤解させる偽の記録になります。 - ユーザーが「X に決めた」と言っても、何を退けたのか、またはなぜそうしたのかがわからない場合は、1 つ質問してください。「どんな代替案があり、何が決め手となってこれを選びましたか?」却下した選択肢の記載がない ADR は、記録ではなく広報文です。
- 問題となっているのが設計そのものの妥当性であり、その記録方法ではない場合は、
/review-a-designに引き継いでください。このスキルでは決定が妥当であることを前提とし、その内容を記録します。
ユーザーが具体的な決定を確認するまで、このゲートを通過してはいけません。決定内容を 1 文でユーザーに言い返し、同意を得てください。
ステップ 1 — 既存の記録を調べる(作成前に置き換え候補を提示する)
承認済みの記録にひそかに矛盾する新しい ADR を作ると、意思決定ログは劣化していきます。番号を割り当てる前に、既存の記録を探してください。
search({ query: "<subsystem or topic of the decision>" })— 意思決定、提案、仕様を対象に、関連する記録を意味的に幅広く検索します。exec("ls -A decisions/")— 既存の連番とタイトルを確認します。exec("grep -rln <subsystem-keyword> decisions/")— 同じサブシステム、インターフェース、制約に関わる記録を探します。- 有望な結果ごとに、
exec("cat decisions/NNNN-x.md")— Decision と Status を読みます。
その後、作成前に次のように分類し、ユーザーに提示してください。
- 承認済みの記録と矛盾する → 新しい決定は、それを覆すか置き換えます。
supersedes:の候補としてパスを示してください。「これは現在acceptedの 0007-use-rest-api を置き換えるように見えます。確認していただければ、ステップ 7 で置き換えの連鎖を設定します。」矛盾する記録を黙って作成してはいけません。 - 矛盾せずに拡張する → 関連する記録として示します。置き換えずにリンクします。
- 実際に新しい決定である → 先に進みます。
決定が proposals/ の承認済み提案から確定した場合は、ここでその提案を特定してください(exec("grep -rln <topic> proposals/"))。ステップ 4 で親としてリンクします。
ステップ 2 — 次の番号を割り当て、テンプレートから作成する
連番を推測してはいけません。 フォルダーを一覧表示し、次の整数を使います。
exec("ls -A decisions/")— 既存の最も大きいNNNNを確認します。- 次の番号 = 最も大きい番号 + 1。4 桁になるようにゼロ埋めします。初めての決定は
0001です。 - 決定の内容を表す短いケバブケースのタイトルを付けます。トピックではありません。例:
0012-adopt-event-sourcing-for-orders。0012-ordersではありません。 - テンプレートから作成します。
write({ document: { path: "decisions/0012-adopt-event-sourcing-for-orders.md", template: "decision" } })
テンプレートには、フロントマターのひな形と 3 つの H2 セクションが用意されています。ここでフロントマターを埋めます。
type: decision
description: "One line: the decision, active voice."
status: proposed # proposed until the deciders accept; then accepted
date: YYYY-MM-DD # today
deciders: [<user>] # who owns this decision
supersedes: [] # fill in Step 7 if this replaces an earlier record
tags: [decision]
作成中は status: proposed のままにします。承認者が承認したとき(ステップ 8)にのみ accepted になります。誰も合意していないのに accepted で公開する ADR は、日付をさかのぼって記録することになります。
ステップ 3 — コンテキスト:関係する要因(ここに時間をかける)
## Context は、最も長く価値を保つセクションです。3 年後に読む人が、会議やスレッド、あなたの記憶に頼らずとも、そもそもなぜこれが問題になったのかを理解できるように書きます。以下を含めてください。
- 決定を迫られた時点でのシステムの状態 — 何があり、何に無理が生じているか。
- 今、選択が必要になった理由 — 新たな要件、限界に達したスケーリング、非推奨になった依存関係、期限など、先送りできなくなった理由。
- 選択肢を制限した制約 — チームの規模、既存技術、レイテンシの予算、コンプライアンス、厳守すべき日付など。
- 相反する要因 — これが明白な選択ではなく、決定である理由です。競合する圧力がなければ、記録することもありません。
中立かつ事実に基づいて書きます。ここで決定を正当化してはいけません。それはステップ 4 の役割です。コンテキストでは問題を余すところなく説明し、決定がそれに対する妥当な対応として読めるようにします。コンテキストを読み終えても、なぜ選択が必要だったのかが分からないなら、このセクションは不十分です。書き直してください。
システムに関する事実は、確認可能な情報に基づかせます。記憶に頼って断言するのではなく、提案書、仕様書、または過去の決定へのリンクを記載します。
ステップ 4 — 決定:能動態で、1 段落に、明確に
## Decision では、現在形または未来形の能動態で、実施する内容を述べます。**「私たちは……します」**と書きます。明確な 1 段落にまとめます。読者が読み終えたとき、曖昧さが一切なく、何を選択したのかを正確に理解できなければなりません。
続けて、簡潔に以下を記載します。
- 検討した選択肢と、他の選択肢を採用しなかった理由を示します。 不採用となった選択肢ごとに 2、3 文で十分です。「X も検討しましたが、レイテンシの予算を満たせませんでした。Y はよりシンプルでしたが、単一ベンダーへの依存が生じます。」これが記録の要です。確認可能な代替案が示されていない決定は検証できません。
- 決定が親提案から発展した場合は、その提案にリンクします。 例:「この決定では 0004-orders-rearchitecture-proposal を採用します。」通常の相対パス付き Markdown リンクを使用します。バッククォートで囲んだり、HTML アンカーを使用したりしてはいけません。
実装の詳細を「決定」に含めてはいけません。どのように構築するかは仕様書に記載し、ADR には記載しません。「決定」では何を選び、なぜ選んだかを述べ、移行手順は記載しません。
ステップ 5 — 結果:良い面も悪い面も、正直に
## Consequences には、チームが今後受け入れていくことを記録します — 良い面も悪い面もです。良い面しかない Consequences セクションは、ADR ではなくマーケティング資料です。状況に合った分類で、次の内容を取り上げてください。
- 何が容易になるか — この選択を後押しした利点。
- 何が難しくなるか — コスト、新たな複雑さ、以前より扱いにくくなること。
- チームにどんな新しい責任が生じるか — 継続的なメンテナンス、新たに採用が必要なスキル、追跡すべき依存関係、誰かが維持しなければならない不変条件。
- 何が選べなくなるか — もはや低コストでは選べない選択肢、閉ざされる道。
- 中立的な結果 — 利点でも欠点でもないものの、将来の読者が知っておく必要のある事実。
本当の欠点を少なくとも 1 つ、新たな責任を少なくとも 1 つ、必ず書いてください。見つからないなら、まだ十分に考えられていません — 現実の決定には、必ず何らかの代償が伴います。欠点は記録の中で最も価値のある部分です。決定がつらくなり始めたとき、将来のチームが確認するのはそこです。
ステップ 6 — 妥当性のセルフチェック(コミット前に批判的な視点で確認)
決定に反対する懐疑的な立場から、ドラフトを読んでください。それぞれに正直に答え、問題があれば修正してください。
- 一方通行の決定ですか、それとも元に戻せますか? この決定を元に戻せるかどうかが明記されていますか? 一方通行の決定(取り消しが困難、または高コストなもの)なら、Consequences に明示してください — これは、将来の読者がこの決定を引き継ぐ前に知っておくべき最も重要なことです。
- Context は本当に Decision の根拠になっていますか? それとも、Decision が突然現れ、Context に書かれた要因がその選択を支持していませんか? 2 つのセクションにつながりがなければ、どちらかが間違っています。
- この決定に反対する読者の懸念に、きちんと対処できていますか? 最も有力な反論は、却下した選択肢か、明示した結果の中に記載する必要があります。明らかな反論が抜けていたら、追加してください。
- 都合が悪いために隠している結果はありませんか? 書きたくないコストこそ、記録に残すべきものです。
この確認で、記録の質ではなく、設計そのもの — 決定が正しいかどうか — が問題だと分かった場合は、そこで作業を止めて /review-a-design に引き継いでください。このスキルは妥当な決定を記録するものであり、決定を再び議論する場所ではありません。
ステップ 7 — Supersedes チェーン(両方向がそろっていなければ破綻)
この記録が以前の記録に取って代わる場合、ログが一方の側から事実と異なるものにならないよう、チェーンを両方向につなぐ必要があります。
- 新しい記録側の順方向: 古いパスを
supersedes:frontmatter に追加します。
edit({ document: { path: "decisions/0012-adopt-event-sourcing-for-orders.md",
frontmatter: { supersedes: ["decisions/0007-use-rest-api.md"] } } })
- 古い記録側の逆方向: ステータスを変更し、古い決定にたどり着いた読者を新しい決定へ誘導する順方向リンクを追加します。
edit({ document: { path: "decisions/0007-use-rest-api.md",
frontmatter: { status: "superseded" } } })
次に、古い記録の Context の冒頭付近に、次の行を追加するか、短い > Superseded by ... の注記を追加します:Superseded by [0012-adopt-event-sourcing-for-orders](./decisions/0012-adopt-event-sourcing-for-orders.md).
古い記録の Context、Decision、Consequences の本文は決して編集しないでください。 ADR は凍結されています — 古い決定は、決定された時点では正しく、その後も歴史として記録に残ります。追加するのはステータスの変更と順方向ポインターです。記述内容を書き換えてはいけません。両方の編集を反映してください。そうしなければチェーンは一方の方向で途切れ、ログの信頼性が損なわれます。
ステップ 8 — リンクと検証
- バックリンク: 親の提案からこの決定へリンクされていること、また、この決定を 実装する 仕様からこの決定へ戻るリンクがあることを確認します。
links({ kind: "backlinks", document: "decisions/0012-adopt-event-sourcing-for-orders" })で、このドキュメントを参照しているものを確認し、記録を見つけやすくするために不足しているリンクを追加します。 - 検証:
audit({ path: "decisions/0012-adopt-event-sourcing-for-orders.md" })の結果がクリーンであること(すべての lint 違反と壊れた内部リンクがないこと)を確認します。検出事項はすべて修正します。置き換えられた記録へのリンク切れがあると、つながり全体が崩れます。 - フロントマターの完全性:
type、description、status、date、deciders、supersedes、tagsがすべて存在し、正しいことを確認します。 - ステータスが実態を反映していること: 決定者が承認している場合は、
status: proposed→acceptedに切り替えます。まだ承認されていない場合はproposedのままにし、承認待ちであることをユーザーに伝えます。ユーザーに代わって決定をacceptedにしてはいけません。 - 本文の構成:
## Context、## Decision、## Consequencesの順で、これらちょうど 3 つにします。ほかのトップレベルセクションは追加しません。この 3 つに収まらない詳細は、リンク先の仕様に記載します。
ステップ 9 — ユーザーへの要約
会話の最後に、次の 3 点を伝えます。
- 決定を一文で — 「私たちは……する」という一文。
- 最大の影響 — 特に後戻りできない決定の場合、チームが最も覚えておくべきコストまたは義務を 1 つ。
- 置き換えた記録 — 古い ADR の名前を挙げ、リンクのつながりが双方向に設定されていることを確認します。
続けて、status が accepted(決定者が承認済み)か proposed(承認待ち)かを伝え、未決事項がある場合はユーザーが把握できるようにします。
対象外
- ユーザーに代わって決定しないでください。 まだ決定されていない場合は
/frame-a-proposalに案内します。このスキルは記録を作成するものであり、選択するものではありません。 - 承認済みの記録を書き換えないでください。 ADR は確定した記録です。過去の決定を変更するには、ステップ 7 で新しい記録に置き換え、古い記録はそのまま残します。古い記録の Context/Decision/Consequences の本文は決して編集しないでください。
- 実装の詳細を ADR に含めないでください。 移行計画、API の形、展開手順は仕様(
/write-a-spec)に記載します。ADR に記録するのは何を、なぜ行うかであり、どのように行うかではありません。 - Consequences セクションのない決定を記録しないでください。 メリットだけの記録、またはコストも新たな義務もない記録は ADR ではなく、宣伝文句です。実際の決定には必ず何らかのコストが伴います。それを見つけて書き留めてください。
- ここで設計の妥当性を判断しないでください。 問いが、決定が適切に記録されているかではなく、決定が 正しい かどうかであれば、
/review-a-designに案内します。