Upkeep の仕組み
July 7, 2026 · View on GitHub
課題
リポジトリにはドリフトが蓄積していきます。関数がリファクタリングされてもドキュメントは古いまま残ります。仕様は3スプリント前に変更された振る舞いを説明し続けます。翻訳版 README は英語の原文より1バージョン遅れます。アイコンファイルが差し替えられても古いファイルがコミットされたままになります。これらはいずれも CI を壊しません — ただ、記録されているすべての情報の信頼性を静かに侵食していくだけです。
定期的な人手によるレビューは一部を拾い上げられますが、すべてのアーティファクトの完全なコンテキストを頭の中で同時に把握し続ける必要があります。それはまさに、専任の AI レビュアーチームが得意とする領域です。
パイプライン: ファンアウト → 統合 → レポート
Upkeep には同一のエンジンを共有する3つの統合パスがあります。CI 用の再利用可能な workflow_call workflow、おなじみの step 構文を使いたい場合向けの Marketplace composite action(- uses: wei18/upkeep@v2。エンジンと入力は同じですが、reviewer は並列ではなく順番に実行されます)、そしてローカルで実行する Claude Code skill / plugin(あるいは単なるスクリプト)です。いずれの場合もパイプラインは同じ5つのステージです。Discovery、Consolidate、Report は決定論的(LLM なし)であり、並列の reviewers と Synthesis が LLM 駆動のステージです。
1. ディスカバリー
ディスカバリーステップがリポジトリを走査し、構造化されたファイルインベントリを生成します。インベントリにはソースファイル、ドキュメント、仕様、ダイアグラム、画像、アイコン、ロケールファイル、規約ファイル(CLAUDE.md、.claude/skills、workflow 定義)が含まれます。このインベントリがすべてのレビュアーへの共通入力となります。
2. 並列レビュアー(ファンアウト)
有効化された各レビュアーは隔離されて実行されます — CI では独立した matrix job として、ローカルでは並列の claude -p サブプロセスとして実行されます。並列実行され、フォールトトレラントです — 1つのレビュアーが失敗しても他の処理はブロックされません。各レビュアーはファイルインベントリと担当するマンデートを受け取り、結果を構造化された出力として書き出します。
3. 統合(Synthesis)
単一の統合ステップがすべてのレビュアーの結果を読み込み、横断的なテーマを特定します。たとえば、特定のディレクトリに集中した規約ドリフトのパターンや、複数のレビュアーが異なる理由で同じファイルを独立してフラグしたケースなどです。レビュアーごとの詳細と合わせてエグゼクティブサマリーを生成します。
4. 集約(Consolidate)
決定論的なステップが、複数のレビュアーが同一ファイルに対して挙げた重複する findings をマージし、重大度が最も高い代表項目を残し、reviewers と関連ファイルを和集合にまとめ、重大度順にソートします。LLM は介在しません。
5. レポート
決定論的なレポートステップが、すべての内容を独立した HTML ファイル(外部依存なし)にレンダリングします。CI では加えて単一の GitHub トラッキング issue を upsert し、複数回の実行をまたいで再利用するため issue トラッカーを整理した状態に保てます。ローカル実行時は代わりにサマリーをターミナル/chat に出力し、GitHub には一切触れません。
レビュアー
| レビュアー | チェック内容 |
|---|---|
docs_staleness | 対象コードから乖離したドキュメント、ベース言語バージョンと同期が取れていない多言語 README・翻訳ドキュメント |
code_hygiene | デッドコードパス、未使用エクスポート、永続的にコメントアウトされたブロック |
spec_flow | 実際の実装と内容が一致しなくなった仕様・アーキテクチャダイアグラム・フローチャート |
visual_icon | 古くなった、不一致、または現在の UI やブランドと整合していない画像・アイコン |
duplicate_orphan | 重複ファイル(異なるパス名で同一または酷似した内容)およびコミットされているが参照されていない孤立アセット |
convention | リポジトリ独自の宣言された規約からの逸脱 — CLAUDE.md のルール、.claude/skills パターン、workflow 標準 |
i18n | ロケール・翻訳ファイル間の整合性(デフォルト無効。.claude/audit.yml でオプトイン) |
正解を事前に決めない
2つのアーティファクトが矛盾する場合 — 仕様が振る舞い X を記述しているがコードは振る舞い Y を実装しているような場合 — Upkeep はどちらかを自動的に「古い」と断定しません。どちらのアーティファクトが時代遅れである可能性もあります。代わりに、裏付けとなる証拠とともに乖離を報告します。各ファイルの git 更新日時、他のファイルで見つかったクロスリファレンス、存在する明示的なバージョン情報を提示します。何を修正するかは人間が判断します。
レポートのみ、編集は行わない
Upkeep はリポジトリのコンテンツに対する書き込みアクセスを持ちません。ファイルの読み取りと、単一の GitHub issue の作成・更新のみを行います。リポジトリ内のいかなるファイルも変更・リネーム・削除することはありません。
出力
HTML レポート — CI では毎回の実行で report-html workflow artifact としてアップロードされます。ローカルでは指定したパス(デフォルト ./upkeep-report.html)に書き出されます。独立したファイルのため、サーバー不要でローカルで開けます。エグゼクティブサマリー、レビュアーごとの結果、各結果の根拠となる証拠が含まれます。
GitHub トラッキング issue(CI のみ)— 初回実行時に作成され、以降の実行ごとに更新(upsert)されます。デフォルトで audit ラベルが付与されます。重複エントリで issue トラッカーを汚染することなく、現在のリポジトリ健全性の永続的でリンク可能な記録を提供します。ローカル実行時はこのステップはスキップされ、代わりにサマリーが出力されます。