audit-code-complexity について
audit-code-complexity は、既存の挙動を保ちながらコードを簡素化する案を検討するスキルです。コード、呼び出し元、テスト、要件で根拠を確かめ、依頼がない限り編集は行いません。
主な機能
- 01現状、変更、提案の監査範囲を設定
- 02呼び出し元、テスト、要件から複雑さを評価
- 03根拠と具体的な代替案のある問題を報告
- 04依頼がない限りコードを編集しない
活用シーン
- 01モジュールに不要な抽象化がないか確認
- 02変更によって生じた複雑さを評価
- 03挙動を保つコード簡素化を計画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ marcellocurto/ skills --skill audit-code-complexityインストール後、Claude Code で/audit-code-complexityを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
コードの複雑さを監査する
問題が求める以上に理解、変更、検証が難しいコードを見つけ、動作を維持したまま、よりシンプルな形を提案します。シンプルとは、必要な要件をすべて満たしながら、理解や変更がしやすいことです。ファイル数、関数数、行数が少ないだけでは、コードがシンプルになったとは限りません。これは監査です。ユーザーから依頼がない限り、コードは編集しません。
1. 対象範囲を決める
- 現在の状態: 複雑さがいつ生じたかにかかわらず、指定されたコードを現状のまま監査します。
- 変更: 指定されたコミット、ブランチ、プルリクエストで新たに生じた、または悪化した複雑さだけを監査します。背景を把握するため、周辺のコードも読みます。
- 提案: ユーザーが提案する設計やコードを、実装前に、明示された要件に照らして監査します。提案の修正を依頼された場合、変更するのは提案であり、提案が対象とするコードではありません。
ユーザーが変更を指定した場合に限り、変更の範囲を使います。リポジトリに未コミットの作業があることは、範囲を切り替える理由にはなりません。両方を依頼された場合は、分けて報告します。
対象が大きい場合は、利用可能であれば並列の読み取り専用サブエージェントを使ってモジュールごとに分担し、報告前に調査結果を自分で検証します。
2. 複雑さを探す
対象、リポジトリの指示、呼び出し元、テスト、設定を読み、必要な動作を把握するために必要なドキュメントだけを確認します。git log で変更頻度の高いファイルを調べます。そうした箇所の複雑さは、より大きなコストになります。呼び出し元が依存する動作や契約と、誰も求めていない前提やあれば便利なだけの要素を分けます。呼び出し元やユーザーが気づく動作をなくすかどうかはユーザーが判断することなので、勝手に削除するのではなく、提案として示します。
次の点を探します。
- 現在の要件では必要のない間接化、ラッパー、汎用コード、拡張ポイント、依存関係、インフラストラクチャ
- 言語、フレームワーク、既存の依存関係、既存の経路、ヘルパー、型、API がすでに提供している機能を重複して実装するコード
- 局所的なバグに対する全面的な書き換え、単純な状態に対するステートマシン、呼び出し元が1つだけの機能に対するフレームワーク、先回りした移行、内部の利便性のための広範な API 変更
- 絡み合った制御フロー、組み合わせの多いフラグ、暗黙の状態、不正な状態を許す型
- 複数の場所に保存または計算されている同じ情報
- 入口やコントローラーにビジネスルールが置かれている、1つのモジュールが無関係な責務を混在させているなど、適切でない場所に置かれた動作
- 1つの変更に多数のファイルの編集が必要になることや、呼び出し元が呼び出し先に隠させるべき詳細を知る必要があること
- 隠れた副作用、広範な変更、誤解を招く名前、密集した式や巧妙すぎる式
- ガード、フォールバック、互換性のための経路、もう使われていないコード
- テストから呼び出されていることだけを理由に残された古い API
- 動作を見えにくくする、ポリシーを複数箇所に埋め込む、本番コードに間接化を強いるテストのセットアップ、ヘルパー、モック
ラッパーの削除を提案する前に、テストも含めて呼び出し元を確認します。ラッパーが実際の動作を担う、または契約を保護するなら残します。単に呼び出しを転送するだけなら、その呼び出しを、それを所有するモジュールに移すよう提案します。
未使用と判断する前に、生成コード、設定、リフレクション、他のパッケージ、スクリプトも含め、シンボル名と文字列リテラルの両方で利用箇所を検索します。検索結果がないことは証拠にはなりますが、証明ではありません。どこを調べたのかを明記します。
仕組みの削除を提案する前に、その利用箇所、運用や障害対応での役割、代わりに何を使うかを把握します。永続キュー、明示的な状態、リトライ、ドメイン上の区別は、一見重厚でも、必要な場合があります。
問題を確認したら、対象の残りの部分にも同じ問題がないかを調べ、該当箇所をまとめて報告します。対象の一部だけを調査した場合は、どの部分を調べたかを明記します。
3. 実際に問題となる点だけを指摘する
次のすべてに該当する場合に限り、指摘事項として報告してください。
- 具体的なコストがあること:コードの理解、変更、テストが難しくなる、またはバグや運用上の問題のリスクが高まる。
- その主張を裏付けるコード、使用状況、テスト、または要件があること。
- 必要な動作と契約を維持できる、よりシンプルな具体策があること。
- その利点が移行と回帰のリスクを上回り、また、その代替策によって複雑さ、リスク、手作業が呼び出し元や運用側に移らないこと。
行数、ネストの深さ、複雑度の指標、見慣れなさは手掛かりであり、指摘事項ではありません。似たコードがあるだけでは、それが単一の概念を表している場合を除き、共通の抽象化を正当化できません。フォーマッターやリンターで強制される事項は対象外とします。
局所的な変更を優先しますが、より大規模な再構成によって局所的な修正よりもはるかに多くの複雑さを取り除けることを根拠が示している場合は、その再構成を推奨し、移行コストも明記してください。あらゆる代替策で、ドメイン上の区別、データの意味、ID、検証、セキュリティ、アクセシビリティ、互換性、耐久性、復旧、運用上の保証を維持してください。
バグ、セキュリティ上の問題、パフォーマンスの問題は、複雑さがその原因となっている、またはそれを覆い隠している場合に限り、このレポートに含め、別途ラベルを付けてください。テストは複雑さの発生源としてのみ対象にします。テストの価値と網羅性については、test-quality-audit スキルを使用してください。
インターフェースを置き換える場合は、テストを含むすべての利用箇所を特定し、同じ動作を確認しながらテストを新しいインターフェースに移行してください。テストのためだけに古い API を残してはいけません。他の呼び出し元がある場合や段階的な移行が必要な場合は維持し、一時的なアダプターをいつ削除できるかを明記してください。
指摘事項への対応
ユーザーから依頼された場合に限りコードを編集し、その後、確認を求めずに変更を完了して検証してください。リファクタリング前に関連するテストを実行し、その後も同じ保護対象のケースを維持してください。期待される結果を変更してよいのは、契約の変更が承認されている場合、またはテストの誤りが実証されている場合に限ります。また、失敗を隠すような方法でフィクスチャ、モック、テスト対象の選定を変更してはいけません。作業に動作修正が含まれる場合は、利用可能であれば tdd スキルを使用してください。ブロッカーによって作業が止まった場合は、有効な失敗テストをそのまま残し、必要な未決定事項と残作業を報告してください。
4. 報告
以下の形式を使用し、利点とリスクの比率が高い順に指摘事項を並べ、空のセクションは省略してください。
**Verdict:** Needs simplification | Minor opportunities | No material findings. One sentence on why.
**Scope:** what was inspected, and what was not.
### 1. Short title
`path/to/file.ts:42`, plus other locations with the same problem.
- **Cost:** what is harder, and the evidence.
- **Simpler shape:** the concrete alternative.
- **Keep:** behavior and contracts that must not change.
- **Risk:** migration and regression risk, and how to verify the change.
**Justified complexity:** complex-looking code that earns its place, only when a reader would likely question it.
**Order:** which findings to do first, only when the order matters.