コンセプトと設計思想
1. 出発点: AI は設計書を疑わない
設計書は書いた瞬間から腐りはじめる。これ自体は昔からある話で、これまでは「人間が読むときに疑う」ことで持ちこたえてきた。
人間は、設計書を開いて数行読むだけで違和感に気づく。「この関数名、もう無いはずだ」「この図、あのリファクタの前だな」。そして手を止めてコードを確認する。設計書を疑うという行為が、無意識のうちに毎回はさまっている。
AI は疑わない。status: current と書いてあれば current として扱う。しかも従順なので、実装のほうを設計書に寄せてくる。
実際に起きる事故は、たとえばこうなる。
- 半年前に廃止した API 名で新機能を書き始める
- 「仕様と違う」と判断して、正しく動いていた実装を古い設計へ書き戻す
- 既に別の方式に置き換えた抽象を、設計書に載っているという理由で再導入する
やっかいなのは、どれも AI が指示に忠実に従った結果だという点。プロンプトを工夫しても直らない。渡している情報が古いことが原因なので、情報の側を直すしかない。
既存のやり方が効かない理由
| 従来の対処 | なぜ足りないか |
|---|---|
| 文書に「最終更新日」を書く | 日付は自己申告。書き忘れるし、「体裁だけ直した」ときも更新される。コードとの対応が取れていない |
| レビューで人間が気づく | AI が設計書を読む頻度と量に、人間のレビューが追いつかない |
| 設計書を捨ててコードだけにする | AI から文脈が消える。毎回コード全体を読ませるのはコストが高く、しかも「なぜそうなっているか」は復元できない |
| 「古いかもしれない」とプロンプトで伝える | 全文書が等しく疑わしくなるだけ。どれが古いのかは分からないままで、結局読まれない |
必要なのは、どの文書が古いのかを機械が判定して、AI に個別に伝えること。
2. 解き方: 鮮度を機械が判定できる形にする
docs-kit は各文書の front matter に 2 つの情報を持たせる。
| フィールド | 意味 |
|---|---|
scope | この文書が責任を持つコード範囲 (グロブ) |
verified_at | 最後に実装と突き合わせたコミットの SHA |
この 2 つがあれば、判定は git に任せられる。
判定結果は 3 段階。
| レベル | 意味 | exit code |
|---|---|---|
ok | verified_at 以降、scope 内に見るべき変更がない | 0 |
stale | 実装が動いた。文書を見直す必要がある | 1 |
broken | 判定の前提が壊れている (SHA が履歴に無い、scope がどのファイルにも当たらない等) | 2 |
これが CI を落とし、MCP 経由で AI にも同じ判定が届く。AI は stale の文書を「参考情報」として扱い、コードのほうを正とする。
なぜコミット SHA なのか
鮮度の基準になりうる候補はいくつかあるが、「コードとの対応が取れる」のは SHA だけだった。
| 基準 | 問題 |
|---|---|
| 文書に書いた最終更新日 | 自己申告。書き忘れる。誤字修正でも更新される。コードの変更とは無関係 |
| ファイルの mtime | チェックアウトで壊れる。CI では全ファイルが同時刻になる |
| 文書の git 最終コミット日時 | 「文書をいつ触ったか」であって「実装と突き合わせたか」ではない |
| 人間による stale 宣言 | 気づいた人しか宣言できない。気づかないのが問題なので循環する |
| 突き合わせ時点のコミット SHA | git 履歴から「その後 scope 内で何が起きたか」を機械が正確に再構成できる |
SHA を基準にすると、判定が「誰かの記憶」ではなく「リポジトリの事実」になる。宣言のコストは docs-kit verify <id> の 1 コマンドで済む。
判定するのは「見直すべきか」だけ
ここは誤解されやすいので明示しておく。docs-kit は**文書の中身が正しいかを判定しない。**判定するのは「実装が動いたので、人間か AI が中身を見直すべきか」だけ。
だから stale は「間違っている」ではなく「未確認」を意味する。見直した結果「まだ正しかった」なら、そのまま docs-kit verify を打てば ok に戻る。
3. 設計原則
保存形式の原則
Markdown が正。 front matter 付きのただの Markdown ファイルで、独自マークアップ拡張は一切足さない。docs-kit が明日消えても、docs/ はエディタでも GitHub でも普通に読める。ロックインしないことが、設計書を安心して書ける条件になる。
4 層に固定する。 文書は adr / spec / arch / plan の 4 層だけ。層を増やせるようにすると、リポジトリごとに置き場所が変わり、AI が「どこを読めばいいか」を毎回学び直すことになる。
| 層 | 役割 | 寿命 |
|---|---|---|
adr/ | 決定記録。なぜそうしたか | 永久 (書き換えない) |
spec/ | 現在の仕様。いまどうなっているか | 実装と同期し続ける |
arch/ | アーキテクチャ。全体の構成と依存方向 | 実装と同期し続ける |
plan/ | 一時的な作業計画 | 使い捨て (マージ時に削除) |
決定は不変。追記のみ。 ADR は書き換えない。方針が変わったら新しい ADR を追加し、古いほうに status: superseded と superseded_by を付けて無効化する。「なぜそう決めたか」と「なぜ変えたか」の両方が履歴として残る。書き換えてしまうと、判断の経緯が失われて同じ議論を繰り返す。
進行状態は書かない。 done / doing / TODO チェックボックスは設計書に置かない。それは Issue トラッカーの仕事で、設計書に混ざると「設計書を読む」と「進捗を確認する」が同じ行為になり、どちらも腐る。
判定の原則
status は 4 値固定。 current / draft / stale / superseded のみ。プロジェクトごとに reviewing や wip を足せるようにすると、AI が「この status は信じていいのか」を判断できなくなる。AI の読み方が変わるものは設定にしない。
誤検出側に倒す。 判定はファイル単位で、行単位の関連付けはしない。scope 内のファイルが変われば、内容にかかわらず「要レビュー」になる。見逃す (古い文書が ok のまま残る) ほうが、余計に引っかかる (stale が出て確認したら問題なかった) より高くつくため。
自動で吸収できる差分だけは吸収する。 ただし「なんでも stale」では運用が回らないので、明らかに仕様に影響しない差分は判定から除外する。テストコードの変更、範囲内で加えて範囲内で打ち消された変更 (net-zero)、内容を伴わない純リネームなど。詳細は ワークフロー。
AI 連携の原則
設定を増やさない。 設定ファイルは docs.config.yaml 1 本、キーは 4 つだけ。層構造・スキーマ・status の値・INDEX の形式・CLAUDE.md に書き込む内容はすべて設定不可。理由は一貫していて、どのリポジトリでも AI の読み書きプロトコルを同一にするため。設定可能にした瞬間、リポジトリごとに AI の振る舞いが変わり、その差分を CLAUDE.md に書く羽目になり、その CLAUDE.md がまた腐る。
MCP は本文を運ばない。 MCP サーバが返すのは絶対パス・メタデータ・200 文字の要約だけで、文書の本文は返さないし書き込まない。本文の読み書きは AI 自身の Read / Edit ツールに任せる。本文を MCP 経由にすると、diff 表示・許可プロンプト・部分編集といったエディタ側の機能をまとめて失う。
実測でも、この設計は狙いどおりに効いている。docs_which を 1 回呼んで 15 文書が返り、実際に本文を読んだのは 4 文書だった。残りはタイトルと要約だけで「今回は関係ない」と判断でき、開かずに済んでいる。
4. 意図的に作っていないもの
ドキュメントツールは機能が際限なく膨らむ。本質的な課題は 鮮度 と 検索性 (選択的に読めること) の 2 つで、それ以外は保守コストだけを残す。以下は「まだ作っていない」ではなく「作らないと決めた」もの。
| 作らないもの | 理由 |
|---|---|
| ドキュメントサイトレンダラ | 閲覧はエディタと GitHub で足りる。Markdown が正である以上、専用ビューアは要らない |
| ベクタ検索 / 意味検索 | グロブによる逆引きが本命。意味検索は逆引きが外れたときの保険として将来検討する |
| 独自マークアップ拡張 | Markdown 互換性を壊す。ロックインしない原則と正面から衝突する |
| 進行管理・タスク管理 | Issue トラッカーの領分 |
| 常駐デーモン / HTTP / ダッシュボード | 設計は残したまま凍結中。CLI と stdio MCP で価値は届いており、無くて失われるのは利便性だけで能力ではない |
機能追加を検討するときは、まず「鮮度か検索性に効くか」を問う。効かないなら作らない。
5. 効くところと効かないところ
効くところ
scopeでコード範囲を切れる文書 (spec / arch)。実装との対応が明確なほど精度が上がる- 複数人 + AI で並行して触るリポジトリ。誰かの変更で他人の設計書が古くなったことを、CI が自動で拾う
- AI に「どの文書を読むべきか」を毎回選ばせたい場面。逆引きで候補が絞れる
効かないところ (設計上のトレードオフとして受け入れている)
scopeを持たない文書には鮮度保証がない。 多くの ADR がこれに当たる。ADR は「過去の決定」なので実装と同期する必要がなく、これ自体は問題ではない。ただし「鮮度が保証されている文書」と「されていない文書」が混在することは意識しておく- 行単位の対応は取らない。 scope 内のファイルが 1 行変わっただけでも stale になる。scope を広く取りすぎると常に stale になって形骸化するので、範囲は絞って書く
- verify コミットに無関係な変更を同居させると見逃す。 実装変更・文書更新・verify を 1 コミットにまとめると、その実装変更は検出されない。運用で「verify コミットには対応する変更だけを入れる」
- マージコミット経由の変更は追わない。 コンフリクト解消でのみ入った変更は判定から落ちる。squash マージ運用を推奨
- 文書の正しさは判定しない。 判定するのは「見直すべきか」だけ (§2 参照)
次に読む
- 実際の運用手順 → ドキュメント管理ワークフロー
- まず動かす → インストール
- 既存の設計書がある → 既存プロジェクトへの導入