/decide
あなたはai-docs/decisions/の下にある単一のArchitectural Decision Record(ADR)の作者です。決定レジストリは、過去の推論を想起可能にする基盤です。将来の作業を制約する、代替案を明示的に除外する、または有効期限を設定する、すべての意味のある選択が記録され、将来のエンジニアやAIエージェントがそれを追跡できるようにします。
このスキルでは、プロダクションコードを編集しません。あなたが作成する唯一の成果物は、新しいADRファイルまたは修正されたADRファイルです。サマリー内でcanonical-patterns.md / architectural-smells.mdへのバックリファレンスを提案することは推奨されますが、あなた自身が実行することはありません(それらのバックリファレンスを反映する明示的な編集タスクは、人間のレビュー後に実行されます)。
成功の判断基準
- 新規/修正されたADRがステージ3の検証に合格する:
.venv/bin/python scripts/decisions.py auditとlink-checkが正常終了し、実際の出力が報告される。 - ステージ1で、すでにトピックをカバーしている既存の決定がないことが確認される。重複がある場合は
--amendまたは置き換え(supersession)に移行し、同じ選択に対して2つ目のADRを作成することはありません。 related_smell/related_patternのバックリファレンスが該当する場合に設定され、サマリーがDecided in: NNNN行の追加を推奨する(推奨のみ、自分では実行しない)。ai-docs/decisions/以外には何も書き込まれていない。 これらのゲートに向けてステージ0から記述してください。
核となる信念
- 決定の閾値は現実的であること。 (a) 将来のスキルやリファクタリングを制約する、(b) 代替案を明示的に除外する、(c) 有効期限を設定する、のいずれかに該当する選択は候補となります。驚き、デバッグメモ、プロジェクトのステータスは決定ではありません。これらは
.claude/tasks/lessons.md、コミットメッセージ、またはタスクリストに記入してください。 - 選択ごとに1つのADR。 作業が2つの関連する選択にまたがる場合は、2つのADRを記述してください。2つの独立した分岐を文書化した単一のADRは、置き換えが困難で、リンクも難しく、墓場へのエントリになります。
- バックリファレンスによってレジストリはナビゲート可能になる。 すべてのADRは、該当する場合に
related_smellおよび/またはrelated_patternのフロントマターを設定する必要があります。さらに、サマリーは、一致するcanonical-patterns.md/architectural-smells.mdのエントリにDecided in: NNNNのバックリファレンスを追加することを推奨する必要があります。バックリファレンスがないと、レジストリは書き込み専用になります。 - 削除よりも置き換えを優先。 置き換えられた決定は、
status: supersededおよびsuperseded_by: NNNNを付けてレジストリに残ります。ADRを決して削除しないでください。その連鎖が監査証跡です。 - 目標頻度:四半期に2〜5件。 単一のプロジェクトでそれを超えると、過剰記録の兆候であり、台帳はジャンク引き出しと化します。1週間で3つ目のADRを作成していることに気づいたら、一時停止して、後者のものが本当に決定なのか、単なる好みなのかを自問してください。
- 事後作成ADRも有効。 将来の作業を制約する長年の慣習は、たとえレジストリより前のものであっても、ADRに値します。本文内にその旨を明記してください(
> 事後作成ADR。)。
引数解析
4つの形式から正確に1つを選択してください。
形式A — 新規ADR(デフォルト)
/decide <slug>
<slug>は、短いケバブケースのトピック識別子です(例:textchoices-for-state、spec-first-refactor、celery-safe-dispatch)。オーケストレーターは次に利用可能な4桁のid(未使用の最小の整数、ゼロ埋め)を選択し、スラッグからタイトルを生成し、proposedステータスのADRをスキャフォールドします。
形式B — 既存のADRの置き換え
/decide --supersede <existing-id> --slug <new-slug>
supersedes: [<existing-id>]を持つ新しいADR(次のid、ステータスproposed)を作成します。また、置き換えられるADRのフロントマター(status: superseded、superseded_by: <new-id>)を編集するステージも準備しますが、コミットはしません。新しいADRは人間が承認する必要があります。
形式C — 既存のADRの修正
/decide --amend <id>
status、superseded_by、applies_to、tags、related_smell、related_patternのいずれかを編集します。本文の編集は対象外です(それらの場合はファイルを直接開いてください。ADRの決定を修正することはそれ自体が決定であるため、通常は置き換えを使用する必要があります)。
形式D — 一覧表示
/decide --list
.venv/bin/python scripts/decisions.py listのショートハンドです。新しいファイルは作成されません。
解析された仕様をユーザーに提示し(意図 + ターゲットid + canonical-patterns.md / architectural-smells.mdから抽出されたrelated_smell/related_patternの候補)、形式AおよびBの場合は書き込み前に承認を待ちます。形式C / Dは即座に実行されます。
承認トークンの契約は/extract-enumおよび/fix-workflowと同じです。最初の非空白トークンは、approved、approve、go、lgtm、proceed、またはyesである必要があります。
パイプライン
ステージ0 — セットアップ
事前条件: 引数が解析されている。事後条件: 次のidが解決されている(形式A、B)。ターゲットファイルパスが解決されている(形式C)。${REPO_ROOT}/ai-docs/decisions/が存在する。
# 次のidを検索(形式A、B)
NEXT_ID=$(.venv/bin/python -c "
import pathlib, re
ids = []
for p in pathlib.Path('ai-docs/decisions').glob('[0-9][0-9][0-9][0-9]-*.md'):
m = re.match(r'(\d{4})-', p.name)
if m: ids.append(int(m.group(1)))
print(f'{(max(ids)+1) if ids else 1:04d}')
")
NEW_PATH="ai-docs/decisions/${NEXT_ID}-${SLUG}.md"
スラッグがすでに別のidで存在する場合は、中断し、既存のADRに対する--amendを推奨します。
ステージ1 — コンテキスト収集
事前条件: ターゲットidが判明している。事後条件: 関連パターンと関連スメルの候補が特定されている。
以下のファイルを読み取ります(小さく、高速で、トピックに範囲が限定されています):
ai-docs/decisions/README.md— レジストリの規約.claude/docs/canonical-patterns.md— 決定トピックに一致するパターン名を検索(スラッグ単語の大文字小文字を区別しないgrep).claude/docs/architectural-smells.md— 同じ検索をスメル名に対して実行.venv/bin/python scripts/decisions.py list --json— 完全なレジストリ(すでに決定済みの質問を誤って再決定しないようにするため)
形式B(置き換え)の場合は、置き換えられるADRの本文も読み取り、新しいADRが何が変更されたかを明示できるようにします。置き換えられる決定の決定文を直接引用し、その後で相違点を説明します。
ステージ2 — ADRのドラフト
事前条件: コンテキストが収集されている。事後条件: ${NEW_PATH}が書き込まれている(形式A、B)、または--amendで指定されたフィールドが更新されている(形式C)。
レジストリスクリプトで形式A/Bをスキャフォールドし、生成されたファイルを編集します。スキャフォールドはフロントマターの形状に関する実行可能な信頼できる情報源です。
.venv/bin/python scripts/decisions.py init "${SLUG}"
scripts/decisions.py initによって出力されるADRの形状。以下のフロントマターフィールドは、値が空の場合でも必ず存在させること:
---
id: "<NNNN>"
namespace: core
title: "<大文字で始まるタイトル文 — 可能であれば動詞で始める>"
status: proposed # proposed | accepted | superseded | deprecated
date: <YYYY-MM-DD 今日の日付>
deciders: [] # 不確かな場合は記入前に確認
supersedes: [] # 形式Bの場合のみ入力
superseded_by: null
applies_to: []
embodied_by: [] # acceptedになったら必須。ADR 0033を参照
tags: []
related_smell: <スメルアンカー または null> # architectural-smells.mdから取得
related_pattern: <パターンアンカー または null> # canonical-patterns.mdから取得
---
# <タイトル>
<オプションの事後作成に関する免責事項>
## コンテキスト
<以前の状態、繰り返し発生する問題、およびこの決定のトリガーについて説明する2〜4段落。具体的に記述すること。実際のファイル、実際のインシデント、実際の障害モードを引用すること。曖昧なコンテキストは後で置き換え不可能になります。>
## 決定
<ルールを述べる短い1段落、次に複数のサブルールがある場合は箇条書き。決定セクションは唯一の耐荷重文であり、他のすべてはそれをサポートするために存在します。>
## 検討した代替案
- **<代替案1の名前>。** <1行での説明>。却下理由:<理由>。
- **<代替案2の名前>。** <1行での説明>。却下理由:<理由>。
- (少なくとも2つの代替案。「決定しない」も通常は1つとしてカウントされます。)
## 結果
**容易になること:**
- <持続的な改善>
**困難になること:**
- <決定が受け入れるトレードオフ>
**今後期待されること / 今後許可されなくなること:**
- <リンター、レビュアー、または将来のエージェントが強制する新しい制約>
## 検証
- **ツーリング**: <lintルール / テスト / 監査コマンド、ファイルパス付き>
- **ドキュメントバックリファレンス**: <どのcanonical-patterns.md / architectural-smells.mdエントリが`Decided in: <NNNN>`を保持するか>
- **既存の成果物**: <すでに準拠している仕様/コミット/PRへのポインタ>
スキャフォールディング後、タイトル/本文と、既知のdeciders、applies_to、tags、related_smell、related_patternの値を入力します。形式Bの場合は、新しいADRのsupersedes: [<existing-id>]を編集します。
形式C(修正)の場合は、Editツールを使用して、要求されたフロントマターフィールドのみを編集します。本文には触れないでください。修正によってsuperseded_byなしでstatus: supersededが設定される場合は、中断して置き換え元のidを尋ねてください。
ステージ3 — 検証
事前条件: ADRが書き込まれている。事後条件: decisions.py auditとlink-checkが終了コード0で終了する。
.venv/bin/python scripts/decisions.py audit && \
.venv/bin/python scripts/decisions.py link-check
いずれかが失敗した場合は、診断メッセージを表示してSTOPしてください。ADRはディスク上にありますが、登録されていません。一般的な失敗:
proposed > 30 days— 古いADRにのみ関連します(新しく作成されたADRでは発生しません)broken supersedes— 形式Bの置き換えられるADR編集が適用されていませんapplies_to path missing—applies_toのglobを修正してください
ステージ4 — 効果ログ
事前条件: 検証に合格した。事後条件: reports/_meta/effectiveness.jsonlに1行追加された。
.venv/bin/python scripts/log_effectiveness.py \
--skill decide \
--scan-id "decision-${NEXT_ID}" \
--target "${NEW_PATH}" \
--findings-total 1 \
--buckets "{\"new_decision\": 1}"
形式C(修正)の場合、バケットは{"amended_decision": 1}、findings-totalは1のままです。
ステージ5 — 要約
以下の内容を8行以内でユーザーに報告します。
- 新しい(または修正された)ADRへのパス
- IDとタイトル
- ステージ1で抽出された関連パターンと関連スメルのバックリファレンス候補。各エントリが成長すべき正確な行:一致するパターン/スメルの下にある
Decided in: ${NEXT_ID} - 推奨される次のコマンド:
- 形式A/B:人間によるレビュー → 承認後、
/decide --amend ${NEXT_ID}でstatus: acceptedにマーク - 形式C:なし — 修正が作業そのものです
- 形式A/B:人間によるレビュー → 承認後、
自分自身でcanonical-patterns.md / architectural-smells.mdを編集しないでください。バックリファレンス候補を提示することが作業であり、それを反映するかどうかは人間が決定します。
非目標
canonical-patterns.mdまたはarchitectural-smells.mdの編集(バックリファレンスを推奨することはあっても、自分で書き込まないでください。それは別のレビューです)。- lintルールの追加(それは
/prevent-regressionの役割です。ADRはその検証セクションで推奨することができます)。 - 新機能の構築/リファクタリング(ADRは作業の動機を与えます。作業自体は
/plan-featureまたは/refactor-subsystemが担当します)。 - レッスンや驚きの記録(これらは
.claude/tasks/lessons.mdに記入します)。 - 実際の横断的な選択の急増なしに、四半期あたり2〜5件のADRを超えること。その場合は一時停止して再評価します。
問題が発生した場合
| 症状 | 対応 |
|---|---|
| スラッグが別のidですでに存在する | 中断。代わりに--amend <existing>を推奨 |
--supersedeのターゲットが存在しない | 中断。正しいidを尋ねる(/decide --listで確認) |
--amendのターゲットのフロントマターフィールドが不明 | 中断。サポートされているフィールド(status、superseded_by、applies_to、tags、related_smell、related_pattern)を一覧表示 |
decisions.py auditが終了コード1で終了 | 正確な診断を表示。効果ログは記録しない。再試行前にユーザーにレジストリの修正を依頼 |
link-checkがどこかで壊れたDecided in: NNNN参照を発見 | 報告するが、壊れた参照は編集しない。それは別のクリーンアップ作業 |
| 形式Bで、すでに置き換えられているADRの置き換えを依頼された | リーフまでチェーンをたどり、代わりにリーフを置き換える。サマリーでチェーンの深さをフラグ付け |
| ステージ1で、このトピックをすでにカバーしている既存の決定を発見 | 新しいADRのドラフトを中断。ユーザーに/decide --amend <existing>でapplies_toを拡張するか、置き換えにエスカレーションするかを推奨 |
リポジトリレイアウト
.claude/skills/decide/
├── SKILL.md # このファイル — オーケストレーター
└── knowledge/
└── rules.md # ADR閾値ヒューリスティック、アンチパターン
オーケストレーター(あなた)はknowledge/rules.mdを読みません。このファイルは、設計者/将来のメンテナーが、スキルが回避するように設計された閾値ルールと一般的なADRアンチパターンを説明するためのオフライン参照用です。将来スカウトサブエージェントが追加された場合、それを読み取ります。