Context Graph
contextlint は、ファイルを 1 つずつ独立に検証するのではなく、プロジェクト全体のドキュメントを 1 つの依存グラフとして扱います。これが Context Graph です。このページでは、なぜグラフを基盤に据えたのか、グラフがどんな概念を表現しているのかを解説します。
具体的な API インターフェース (buildContextGraph、getImpactSet など) は Graph API カテゴリで扱います。Concepts では 概念モデル に集中します。
なぜグラフが必要か
Section titled “なぜグラフが必要か”ドキュメントは独立したファイルの集まりではなく、互いに参照し合う依存関係のネットワーク を形成しています。
- ある要件 ID が別のファイルで参照される
- 仕様ファイルがリンクで他のファイルを参照する
- ステータスの安定度が依存関係を伝って下流に影響する
- セクションがアンカーで別ファイルから参照される
ファイル単位の lint だけでは、これらの ファイルをまたいだ整合性 は検証できません。例えば次のような問題は、グラフを構築して初めて検出できます。
| 問題 | グラフが必要な理由 |
|---|---|
| 要件 ID をリネームしたが、参照側が古い ID のまま | 定義側と参照側を 同時に 見る必要がある |
requirements.md → design.md → test.md のチェーンが途切れている | 複数ファイルの参照関係を 追跡 する必要がある |
A.md → B.md → C.md → A.md の循環依存 | グラフ全体を見て サイクル を検出する必要がある |
| どこからも参照されていない孤立ドキュメント | 全ファイルの 被参照状況 を集計する必要がある |
contextlint がこれらを扱えるのは、ファイルを node、参照を edge とする 有向グラフ を内部で構築しているからです。
Context Graph が表現するもの
Section titled “Context Graph が表現するもの”Context Graph は、プロジェクト内のドキュメント依存関係を有向グラフとしてモデル化したデータ構造です。
| 構成要素 | 何を表すか |
|---|---|
| node (頂点) | 1 つの Markdown ファイル |
| edge (辺) | あるファイルから別のファイルへの参照 (リンク、ID 参照、アンカー、画像) |
| 方向 | 「参照する側」 → 「参照される側」 |
このモデルにより、contextlint は次のような問いに答えられるようになります。
- このファイルを変更したとき、影響を受けるのはどのファイル?
- このファイルに関連するドキュメントの最小セットは?
- ドキュメント間に循環依存はあるか?
- どこからも参照されていない孤立したドキュメントはあるか?
- 要件 → 仕様 → 設計 → テスト のトレーサビリティチェーンは途切れていないか?
直接的な影響と間接的な影響
Section titled “直接的な影響と間接的な影響”Context Graph は依存関係を辿ることで、変更の影響範囲を 直接 (direct) と 間接 (transitive) に分類できます。
requirements.md ↓ 参照されるspec.md (直接の影響) ↓ 参照されるtest-plan.md (間接の影響)requirements.md を変更したとき、spec.md は直接的に影響を受けますが、test-plan.md は spec.md を経由して 間接的に 影響を受けます。grep だけでは間接的な影響は追跡できません。Context Graph を構築することで、変更の波及範囲 を再帰的に把握できるようになります。
この情報は、リファクタリングや要件変更を行うときに「どのファイルを一緒にレビューすべきか」 を判断する材料になります。
グラフを基盤にすることの意義
Section titled “グラフを基盤にすることの意義”Context Graph は、単に 1 つのルール (例えば GRP-001 / GRP-002 / GRP-003) のための内部データ構造ではありません。contextlint 全体の基盤 として複数の機能を支えています。
| 機能 | グラフをどう使うか |
|---|---|
| ファイル間の参照ルール (REF-*) | ファイル間の edge を辿って参照先の存在を検証 |
| ID トレーサビリティ (REF-002, GRP-001) | 定義と参照を node 上にマッピングして追跡 |
| 循環参照の検出 (GRP-002) | グラフのサイクルを検出 |
| 孤立ドキュメント検出 (GRP-003) | 入次数が 0 の node を検出 |
影響分析 (contextlint impact) | 指定 node から到達可能な node を列挙 |
コンテキストスライス (contextlint slice) | クエリに関連する最小サブグラフを抽出 |
Context Compiler (contextlint compile) | グラフからドキュメントの役割 (entry / hub / leaf / bridge / isolated) を分類 |
これらは個別の機能ですが、同じグラフ表現を共有 することで、出力に一貫性が生まれます。あるルールで「このファイルは A に依存している」 と判定された場合、影響分析でも同じ依存関係が反映されます。
Context Graph の構築は 決定論的 です。同じドキュメント集合からは常に同じグラフが構築されます。
- LLM を使わない
- ファイルの mtime や git のタイムスタンプを参照しない
- ファイル内容のみを入力とする
この性質により、CI で安定した結果が得られ、エディタ・AI ホスト・CI の 3 層フィードバックでも同じグラフが共有されます (詳細は 3 層フィードバックの設計 を参照)。