keep-codebase-maintainable について
コーディングエージェント向けの保守作業スキルです。範囲を広げずにコードベースを整理し、契約を守るための棚卸し、リスク別の削除、検証手順を示します。
主な機能
- 01範囲を守る保守指針
- 02削除前の候補棚卸し
- 03リスク別の整理手順
- 04契約とドキュメントの確認
- 05差分の抑制と検証
活用シーン
- 01未使用ファイルや依存関係の整理
- 02重複実装の統合
- 03古いドキュメントの修正
- 04機能開発と整理の分離
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ darkmatter/ skills --skill keep-codebase-maintainableインストール後、Claude Code で/keep-codebase-maintainableを入力して読み込まれたか確認します。
同梱ファイルreferences/instances.md
詳細
コードベースの保守性を維持する
保守性を高める作業は、追加の磨き込みを施した機能ではありません。成果物は、より小さく、より実態に即したツリーです。未使用のものを取り除き、重複をまとめ、名前を実態に合わせ、ドキュメントをコードと一致させ、差分には依頼された内容だけを含めます。
Cooper の OMP Hindsight バンク(コーディングエージェントに実際にどのようなプロンプトを出すか)から抽出しています。元の事例:references/instances.md(/var/lib/hermes/workspace/omp-maintainability-asks.mdにもコピーがあります)。
**基本原則:**依頼された範囲を守ってください。共通の可読性ルールと例については、 codebase-design に従ってください。 呼び出しを転送するだけの抽象化は削除してください。複雑さを隠すもの、不変条件を守るもの、外部インターフェースを変換するものは残してください。
使用する場面
ユーザー(またはタスク)が次のような内容を求めているときに読み込みます。
- クリーンアップ/整理/刈り込み/健全化/残骸/不要/未使用
- 簡素化/差分を縮小/最小限の変更/脇道にそれない
- 監査、修復、再編成
- 名前の変更/統合/整理/1つのパッケージ/短い名前
- 「追加しないで」「新しいサービスは不要」「コーディングを止めて」「範囲外」
- コメントに理由を書く/ドキュメントが古い/AGENTS.mdを修正
- 保守しやすくする/保守コストを減らす/凝集性
**使用しない場面:**依頼された機能の実装、動作不良の修正、または自分が書いたばかりの差分への機能実装後の仕上げには使用しないでください。その仕上げには、リポジトリのレビューガイダンスを使用してください。
ユーザーが「Xを追加し、Yもクリーンアップして」と依頼した場合は、コミットを分けてください。このスキルが担当するのはYです。
常時適用するルール
以下は、通常の「気を利かせるエージェント」としての振る舞いよりも優先されます。
- 削除の判定。シンボル/ファイル/パッケージ/依存関係/フラグ/スコープは、実際にインポートしているものがゼロかつ公開契約(エクスポートされたAPI、フレームワークのピア、稼働中のアプリが引き続き宣言しているHelmの値)ではない場合に削除します。その名前をgrepしてください。次に古い名前をgrepしてください。
knip/ts-prune/depcheckは手がかりであり、証明ではありません。フレームワークのピアや動的インポートを誤って検出することがあります。 - **不要なものを復活させない。**古くなったGit宣言を削除するのが修正です。「Missing」を解消するためにリソースを同期/適用/復活させるのは不具合です。後で使うために予約された設定項目も同様です。墓標のようなコメントではなく、きれいに切り替えてください。
- **所有者は1つ、名前は1つ。**重複したものは徐々に乖離します(2つのスケジューラー、
menuとxの併存、統合後も残ったManualCommitStepなど)。統合したら、廃止した名前をgrepして重複したものを削除してください。 - **カスタム実装より標準機能。**必要な機能をライブラリが提供している場合は、それを使ってください。デコード、エラー、リソースのライフタイム、またはより単純で完結した操作を担うローカルアダプターは残し、呼び出し名を変えるだけのラッパーは削除してください。
- 短く、実態に即した名前。
@repo/billingのように、機能を所有するものに名前を付けてください。何でも詰め込む共通のutilsは避けてください。所有者の配下では、一般的な役割別ディレクトリを使ってください。公開ドキュメントでは標準の名前(x)を使い、古い別名は使わないでください。 - **パッケージは凝集性の単位。**明示的な公開エントリを通じて完結した操作を公開し、実装は
src/以下に、所有者ごと、次に役割ごとにまとめてください。関連するSQLとヘルパーは、そのアダプターと一緒に配置してください。テストはインターフェースを通じて観測可能な動作を検証し、リポジトリの配置規約に従ってください。 - **差分は最小限に。**対象のパスを指定してステージしてください。
git add -Aは決して使わないでください。1つのコミットにつき懸念事項は1つにしてください。許可されていない余分な変更は、議論せずに元に戻してください。「クリーンアップの承認」は「mainにマージしてよい」という意味ではありません。 - **現在のユーザー指示は、助言的なAGENTS.mdより優先。**コミット/プッシュに関するガイドラインは、リモートへの変更には引き続き適用されます。ただし、追加のエージェントの起動や作業範囲の拡大は許可されません。
- **理由をコメントに残す。**設計意図、不変条件、エッジケースの根拠を記してください。
// increment counterのようなコメントは不要です。古いドキュメントは契約上の不具合です。更新するか削除してください。 - 止める指示があれば止める。「すべてのコーディングを止めて」「本番のauto/flashは変更しないで」などの指示があれば、直ちに作業範囲を守ってください。
作業手順
1. 作業を明確にする
1文で書きます。何を小さくする、または実態に即したものにするのか、何を範囲外とするのか。
完了の条件:その文に機能追加が含まれていないことです。含まれている場合は、このスキルを使うべきではありません。
2. 着手する前に棚卸しする
候補の一覧を作成します。まだ削除しないでください。
path:symbol → why it looks dead → consumers found (grep) → contract? → action
次の順序で検索します。
- 未使用のファイル/エクスポート/依存関係/フラグ/Slack スコープ/Helm の残骸
- 不完全な統合による古い名前の残存
- ロックファイルと矛盾する古いコメント、README、AGENTS.md の固定指定
- 廃止された機能をまだ案内しているコマンド/エイリアス
- 「後で使うために予約」された設定項目と未使用のエラー種別
- 一時的な成果物(
/tmp/*、ワークツリー、古いタグ、マージ済みブランチ)
完了条件:候補ごとに grep の結果(「該当なし」も含む)と、契約上の判定がそろっていること。本番環境に影響を及ぼす可能性があるもの(バインディング、PVC、Hyperdrive、DNS、シークレット)については、稼働中の利用元を必ず確認してください。
3. リスクの低い順に適用する
| Tier | 例 | 対応 |
|---|---|---|
| SAFE | 未使用の import、残された /tmp、コメントアウトされたブロック、編集ミスで重複した設定セクション | すぐに削除します。 |
| CAREFUL | import 元のない未使用ファイル、アプリから import されていない依存関係、短い名前への変更、重複ヘルパーの統合 | 削除/名前変更後、そのパッケージを対象とするテスト/lint を実行します。 |
| RISKY | 稼働中のバインディング、パブリックエクスポート、Helm/Argo リソース、シークレット、peer dependency、「knip のヒット数がゼロ」のもの | 稼働中の利用元を確認します。利用元があれば、作業を止めてその旨を報告します。名前のグループ単位で削除してはいけません。 |
推測に基づくフラグ、サービス、抽象化を追加しないでください。クリーンアップの範囲内で理解しやすさが明確に向上する場合は、ローカルヘルパーや一貫性のあるモジュールを導入してもかまいません。切り出しは、複雑さを隠すか、有用な再利用を可能にするものでなければなりません。設定済みの行数制限は維持してください。数値を満たすために転送用ファイルへ分割するのではなく、対象を限定した例外として記録してください。
完了条件:SAFE/CAREFUL の項目がすべて適用されているか、理由を明記して明示的に見送られていること。また、稼働中の利用元を確認せずに RISKY の項目を適用していないこと。
4. 契約との整合性を保つ
同じ変更セット内で、次の内容が現状と合わなくなった場合に限り、修正します。
- AGENTS.md/README の記述(バージョン、レビューを投稿する担当者、認証情報の保存場所)
- 削除したパスについて説明しているコメント
- 削除したスクリプトを参照している公開コマンド一覧/
xメニュー項目 - 古いマーカーを使い続けているスナップショット/フィクスチャ
ユーザーから依頼されていない限り、新しい設計ドキュメントは書かないでください。計画を延々と練るのはやめてください。機械的なリファクタリングであれば、ブレインストーミングは不要です。
完了条件:古い名前を grep したとき、何も見つからないか、新しい名前を示す1行の案内だけが見つかること。
5. 変更範囲を絞って取り込む
- 差分には、採用した棚卸し項目だけを含めます。
- 無関係な作業中の変更とは別のコミットにします。必要であれば、ダーティなワークツリー用の手順を使います。差分をバックアップ → 無関係な変更を元に戻す →
git diffを確認 → コミット → 作業中の変更を再適用。 - ユーザーから取り込み方法を指定されていない限り、push/Sync/deploy は行わないでください。
- 範囲が逸脱した場合(余分なファイル、エージェント、作業範囲):まず元に戻し、その後で報告します。
完了条件:開始時点からの git diff を、棚卸し内容に基づいて1行ずつ説明できること。また、変更したパッケージを対象とするプロジェクトのチェックに合格していること(または、同じ理由でベースラインも失敗していたこと)。
ここで言う「クリーン」の状態
実際の依頼で繰り返し見られるパターンです。新しいものを考案せず、これらに合わせてください。
- カタログの監査 — 壊れたコマンドを削除し、残りにプレフィックスを付け、分類方式を統一する。
- 差分の整理 — 不要な間接化を取り除き、動作のテスト範囲は維持する。 行数の純増減は規模を示す証拠であり、品質目標ではありません。
- 独自のスタックを置き換える — ライブラリのフックを使う(bash-preexec、Polar SDK、ベンダークライアント)。
- 単一の責任者に集約する — SessionHost を1つ、スケジューラーを1つ、SDK リポジトリを1つにし、最終的に2つのリポジトリにする。
- 予約済みの設定項目は削除する — 「制約付き API を後で作るため」と残さない。
- 装飾より統一性を優先する — 追加のスタイルがコードやバグを増やすなら統一性を選ぶ。
- フラグよりヒューリスティックを優先する — フラグが復旧時のバグにつながる場合はヒューリスティックを選ぶ。
- ベンダーの参照情報は通常のファイルとして置く — 次のエージェントが追加設定なしで AGENTS.md に従えるようにする。
よくある落とし穴
- 名前のグループで削除する。 本番名を指定して Hyperdrive 設定を削除した結果、稼働中の Workers が停止しました。必ず最初に、稼働中の ID/バインディングを特定してください。
- Missing を解消するために同期する。 使用されていない claim が再作成されます。git を編集してください。ステータスだけが必要な場合は、ハードリフレッシュしてください。
- 未使用エクスポートのツールを信頼する。 grep してください。フレームワークのピアも確認してください。文字列による動的インポートも確認してください。
- 「クリーンアップは問題なし」を「main にプッシュしてよい」と受け取る。 マージしてよいかは、別途確認が必要です。
- 片割れを残す。 インクリメンタルな統合によって
ManualCommitStepを残さないようにしてください。変更後、古い名前を grep してください。 - 予約済みの不要な API を残す。 誤解を招く分類器になります。切り替えてください。
- AGENTS.md の儀式化。 ブロッカーに関する注意があるからといって、ユーザーが依頼していない作業を開始しないでください。ただし、権限がない場合はリモートへの変更を拒否してください。
- クリーンアップを計画するだけで終わる。 調査 → 棚卸しの実施 → 適用、の順に進めてください。承認済みの形を再設計しないでください。
- 削除したコードについてコメントを残す。 コードを削除するなら、コメントも削除してください。ただし、なぜ X を行わないのかという重要な理由を記録している場合は除きます。
- 機能追加とクリーンアップを一つのコミットにまとめる。 分けてください。
検証チェックリスト
- 仕事の内容が一文で説明でき、そこに機能追加が含まれていない
- 棚卸し表があり、削除する各項目について grep と契約上の判断が記載されている
- リスクのある項目について、稼働中のバインディングを確認した
- 古い名前を grep しても該当がない(または新しい名前を示している)
- 維持または新規の抽象化はすべて、複雑さを隠すか、有用な再利用を可能にしている
- 設定された行数制限を維持し、対象を限定した例外には説明を記載している
- テストで動作と、必須の完了/エラー/クリーンアップの契約を検証している
- 差分の内容を棚卸しから説明でき、許可されていないファイルが含まれていない
- 変更したパッケージを対象にしたテスト/lint を実行し、既存の失敗だけが残っている
- 変更によって事実と異なる内容になった古いドキュメント/AGENTS.md/メニュー項目を更新または削除した
- 依頼されていない限り、プッシュ/同期/デプロイを行っていない