本文へスキップ
ガイドの目次

コンセプトと設計思想

← ガイド目次

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
okverified_at 以降、scope 内に見るべき変更がない0
stale実装が動いた。文書を見直す必要がある1
broken判定の前提が壊れている (SHA が履歴に無い、scope がどのファイルにも当たらない等)2

これが CI を落とし、MCP 経由で AI にも同じ判定が届く。AI は stale の文書を「参考情報」として扱い、コードのほうを正とする。

なぜコミット SHA なのか

鮮度の基準になりうる候補はいくつかあるが、「コードとの対応が取れる」のは SHA だけだった。

基準問題
文書に書いた最終更新日自己申告。書き忘れる。誤字修正でも更新される。コードの変更とは無関係
ファイルの mtimeチェックアウトで壊れる。CI では全ファイルが同時刻になる
文書の git 最終コミット日時「文書をいつ触ったか」であって「実装と突き合わせたか」ではない
人間による stale 宣言気づいた人しか宣言できない。気づかないのが問題なので循環する
突き合わせ時点のコミット SHAgit 履歴から「その後 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: supersededsuperseded_by を付けて無効化する。「なぜそう決めたか」と「なぜ変えたか」の両方が履歴として残る。書き換えてしまうと、判断の経緯が失われて同じ議論を繰り返す。

進行状態は書かない。 done / doing / TODO チェックボックスは設計書に置かない。それは Issue トラッカーの仕事で、設計書に混ざると「設計書を読む」と「進捗を確認する」が同じ行為になり、どちらも腐る。

判定の原則

status は 4 値固定。 current / draft / stale / superseded のみ。プロジェクトごとに reviewingwip を足せるようにすると、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 参照)

次に読む