mcpField
P
polish-diff

polish-diff

github.com/jayden-dang開発153 回インストール5 日前に更新
リポジトリ

polish-diff について

開発者向けのコード整理スキルです。指定した diff を再利用、簡素化、効率、実装レイヤーの4つの観点から確認します。動作を維持し、対象範囲内だけを変更して、元のテストスイートを再実行します。

主な機能

  1. 014つの観点から diff を確認
  2. 02動作とテストを変更しない
  3. 03diff の範囲内で指摘を反映
  4. 04変更前後で同じテストを実行
  5. 05見送った指摘と保留債務を報告

活用シーン

  1. 01動作を変えずに変更部分をリファクタリング
  2. 02重複や過剰な複雑さを発見
  3. 03コミット前に diff を確認
  4. 04範囲外の有効な整理課題を記録

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jayden-dang/skills --skill polish-diff

インストール後、Claude Code で/polish-diffを入力して読み込まれたか確認します。

同梱ファイルeval.jsonTESTS.md

詳細

Diff のポリッシュ

4 つのクリーンアップエージェントがそれぞれ異なる観点から diff を読み、その指摘を反映します。成果物は 動作がまったく同じ、よりクリーンなコード です。レポートでも、バグ修正でもありません。

このスキルには 2 つの境界があり、どちらも譲れません。

1. **動作を変更しないこと。** クリーンアップ前に成功していたテストスイートは、クリーンアップ後も成功します。その結果を得るためにテストを編集してはいけません。テストを書き換えないと通らないクリーンアップは、クリーンアップではありません。 2. **正しさに関わるバグは対象外です。** バグを探してはいけません。また、たまたま見つけても修正してはいけません。記録し、ユーザーに実行してもらうために `inspect-change`(すでに壊れている場合は `root-cause`)を案内してください。構造変更と修正の両方を含む diff は、どちらの観点からもレビューできません。

1. diff を確定する — 速やかに失敗させる

git diff @{upstream}...HEAD を実行し、失敗した場合は git diff main...HEAD、それも失敗した場合は git diff HEAD~1 を実行して、レビュー対象の diff を取得します。未コミットの変更がある場合、または範囲指定の diff が空の場合は、git diff HEAD も実行し、作業ツリーの変更を対象に含めます。polish-diff は通常、コミット前に実行されます。引数として PR 番号、ブランチ、またはファイルパスが渡された場合は、これらすべての代わりにそれを使います。diff が空なら、ここで終了してその旨を伝えます。何もない状態を 4 つのエージェントにレビューさせてはいけません。完了条件:diff が空でなく、対象範囲が明示されていること。

2. 成功しているベースラインを記録する

変更されたファイルを対象とするテストスイートを特定して実行し、何も変更する前に結果を記録します。ステップ 6 で再現すべきベースラインは、テストが成功している状態です。ここで失敗した場合、ブランチはすでに壊れています。作業を中止し、root-cause を案内してください。失敗するテストスイートの上にクリーンアップを重ねると、動作を維持できたことを示す唯一の証拠が失われます。完了条件:テストスイートが成功し、それを証明したコマンドが記録されていること。

3. 4 つのクリーンアップエージェントを並行して起動する

4 つすべての指示を1 つのメッセージにまとめて送信し、並行して実行するとともに、互いのコンテキストを汚染させないようにします。各エージェントは読み取り専用です。指摘を報告し、適用するのはあなたです。各指示は 400 語未満にし、先入観を与えてはいけません。「指摘しないで」や、あらかじめ重大度を評価するような表現は禁止です。

各エージェントには diff、リポジトリのパス、以下の観点からちょうど 1 つを渡します。各エージェントは、file:line、1 行の概要、具体的なコスト(重複しているもの、無駄になっているもの、保守しにくくなっているもの。仮定上のクラッシュは不可)、および代替案の名称(使用すべき具体的なヘルパー、より単純な形式、またはよりコストの低い代替手段)を含めて指摘を返します。代替案の名称がない指摘は対応可能ではないため、エージェントは除外します。

再利用

コードベースに既存の実装がある機能を新しいコードが再実装している場合に指摘します。共有モジュールとユーティリティモジュール、および変更箇所に隣接するファイルを grep し、代わりに呼び出す既存のヘルパーを示します。

単純化

diff が追加した不要な複雑さを指摘します。冗長または導出可能な状態、わずかな違いだけのコピペ、深いネスト、残されたデッドコードが対象です。同じ処理を行う、より単純な形式を示します。

効率性

diff が新たに生み出した無駄な処理を指摘します。冗長な計算や繰り返しの I/O、逐次実行されている独立した処理、起動時やホットパスに追加されたブロッキング処理が対象です。また、クロージャーやキャプチャした環境から作られる長寿命オブジェクトも指摘します。これらはオブジェクトの存続期間中、外側のスコープ全体を保持します。そのスコープに大きな値が含まれている場合、メモリーリークになります。必要なフィールドだけをコピーするクラスまたは構造体を使うことを推奨してください。よりコストの低い代替案を示します。

抽象度

変更が適切でない階層で実装されている場合に指摘します。共有インフラに特殊ケースが追加されているのは、修正が十分に深い階層まで行われていない兆候です。特殊ケースを追加するより、基盤となる仕組みを一般化することを推奨します。変更を取り込むべき仕組みを示します。

コメントの整理(コントローラーが適用。簡素化に統合してもかまいません)

ここでも「デフォルトではゼロ」を適用します。差分にコメントが多い場合、またはユーザーから積極的なコメント整理を求められた場合は、実行せずに /no-comments を提示して実行してもらいます。それ以外の場合:

  • 削除または書き換え: 次の行を言い換えているだけのコメント、制御フローを説明するコメント、要件 ID を参照するコメント、「計画/仕様書に従って」と述べるコメント、タスクの内容を言い換えただけの TODO。
  • 残す: コードだけでは分からない、明白でない不変条件、危険性、プロトコル/ワイヤー上の制約、および「なぜ明白な代替案を選ばなかったか」を説明するコメント。

完了条件:4 つのエージェントすべてから報告があること(サブエージェントが 4 つの観点のみを担当する場合、コメント整理はコントローラーが 5 つ目のパスとして行ってもかまいません)。

4. トリアージ

同じ行または同じ根本的な仕組みに関する指摘を重複排除します。4 つの観点から同じ欠陥が 4 通りに見つかることはよくあります。その後、議論せずに次の指摘を除外します。

  • 修正によって観測可能な動作が変わるもの(設計変更にあたるため、amend-feature または reroute-plan に回します)
  • ピン留めされた差分から大きく外れた編集が必要なもの
  • 誤検出だと判断したもの

除外した指摘は、それぞれ理由を 1 行で記録します。何も言わずに破棄した指摘は、受け取らなかった指摘と区別できません。完了条件:すべての指摘が、適用待ちとして登録されるか、理由とともに除外された記録があること。

5. 適用

残った指摘をそれぞれ直接修正します。影響範囲が最小のものから対応します。ピン留めされた差分のファイル内にとどめます。必須サブスキル:test-first を使用してください。このステップには、そのリファクタリングの規律がぴったりです。コードの変更中もテストはそのままにします。完了条件:適用待ちの指摘がすべて適用されるか、理由とともに除外リストへ移されること。

6. 動作が維持されたことを証明

ステップ 2 の正確なコマンドを再実行します。テストがすべて成功し、この整理で git diff に許可されるテストファイルの変更は、以下の 3 条件すべてを満たす削除だけです。それ以外のテストファイルの行を追加または削除した場合は、作業を止めてください。必須サブスキル:prove-claim を使用してください。「安全そうに見える」は証拠になりません。リファクタリングは、確信しているときに限って何かを壊しやすい作業です。テストが失敗したら、その修正をさらに手直しするのではなく、問題の修正を元に戻してください。

許可される削除と、満たすべき 3 つの条件:テストが、簡素化の観点で不要なコードとして削除されたものだけを固定していた場合、そのテストは削除できます。対象がなくなっていること、その動作が別のテストで引き続きカバーされていること(そのテストを明記してください)、そして削除についてステップ 7 のレポートに記載することが条件です。3 条件のうち 1 つでも満たさなければ、そのテストは残します。テストの書き換え、対象の変更、名前の変更、移動は決して行えません。これはルール 1 が禁じるゴールポストの移動です。「同じアサーションを正規の関数に向け直した」は、まさにその移動にあたります。テストを削除できない場合は、古いシンボルを薄いエイリアスとして残し、正規のものに委譲させます。重複したルールが削除され、指摘された問題が解消される一方で、テストスイートには変更が入りません。

完了条件:ステップ 2 で成功したものと同じコマンドでテストスイートが成功し、削除したテストがあれば、その名前と代替となるカバレッジがレポートに記載されていること。

7. 報告

何を修正し、何を、なぜ見送ったのかを述べます。また、エージェントが作業中に気づき、ルール 2 に従って別途報告した正確性のバグがあれば、それも記載します。

続いて 4 つ目の枠、記録です。理由が スコープ(固定された差分の範囲外、別のモジュールの問題)である見送りは、誰かが実在すると判断し、意図的に未修正とした指摘であり、今やこの報告以外にはどこにも記録されていません。このような見送りがある場合は、それぞれ以下のブロックを出力します。枠の名前は record-debt の The entry と同じですが、見出しには DEBT-N を付けません(ID は /record-debt が付与します)。コンテキストが閉じる前に実行するよう、ユーザーに /record-debt を伝えます。誤検出として記録された見送りは、その理由ですでに完全に記録されているため、記録枠には決して入れません。

### `<path>` — <one-line finding>

- **Found:** `<YYYY-MM-DD>` · polish-diff on `<branch or range>`
- **Cost:** <what this makes harder or riskier, concretely>
- **Deferred because:** outside the pinned diff
- **Fix shape:** <one line | Unknown>
- **Ticket:** none
- **Status:** open

答えがない枠には Unknown と記載し、行を省略してはいけません。「スコープ外の見送りだけを列挙する」「台帳をでっち上げない」は、これらの枠を省略する理由にはなりません。ここで **DEBT-N** を新たに作ると ID が衝突するため、作成しないでください。

トリアージ後に何も残らなかった場合は、コードはすでにクリーンだったと述べます。これは失敗ではなく、実行が成功したということです。4 つのエージェントが何も見つけなかったことは確かな成果であり、レビューを正当化するために指摘をでっち上げることは、指摘が何もないことよりも悪い唯一の結果です。完了条件:修正/見送り/別途報告/記録のすべてを明記すること。見送りがすべて誤検出の場合、記録欄には「記録対象なし」と記載します。

インラインの代替手順(サブエージェント機能がない場合)

4 つの観点を、1 つのコンテキスト内で「再利用性」「簡素化」「効率性」「視点の高さ」の順に、自分で順番に確認します。次の観点に移る前に、各観点を最後まで確認し、指摘を書き留めます。4 つのコンテキストに分ける価値は、他の観点の結論を見て、それに引きずられることがない点にあります。1 つのコンテキストでそれに近づける唯一の方法は、1 つを終えてから次を始めることです。ステップ 1、2、4〜7 は変更ありません。また、レビューの費用が安く済んだからといって、ステップ 6 を省略することはできません。

レッドフラグ — 禁止事項

  • 整理後のコードがテストを通るように、テストを編集する
  • 「作業中についでに」気づいた正確性のバグを修正する
  • 固定された差分で一度も変更されていないファイルに手を加える
  • 具体的なコストを 1 行で説明できない指摘を適用する
  • ステップ 2 のコマンドを再実行せずに、整理が完了したと報告する
  • 4 つのエージェントが何も返さないのは「おかしい」と考え、指摘をでっち上げる

よくある自己正当化

考え実態
「明らかにバグです。直さずに残すなんてばかげています」それなら、整理のコミットに紛れ込ませた場当たり的な修正ではなく、正式なレビューを受けるべきです。inspect-change に報告してください。構造変更と修正の両方を含む差分は、どちらとしてもレビューできません
「テストが以前の内部実装を検証していたので、更新しました」動作を変更し、その変更を検出するはずだった基準を動かしてしまいました。元に戻してください。テストを本当に変更する必要があるなら、これは polish-diff ではありません
「テストを正規の関数に 向け直しただけ です。同じアサーションなので、カバレッジも失われていません」このルールが破られる最もよくある例で、もっともらしい言い訳でもあります。邪魔だったテストを削除し、新たに別のテストを書いたのです。代わりに、元のシンボルを薄いエイリアスとして残してください。重複したルールはなくなり、テストスイートも変わりません
「この 3 つのファイルにも手を加えたほうが、ずっとすっきりします」固定された差分の範囲外は、スコープ外です。範囲を限定できない整理は、誰にもレビューできない整理です
「テストスイートの実行が遅いので、影響を受けるテストだけで十分です」ステップ 2 で記録したベースラインだけが、あなたの主張を裏付ける唯一の証拠です。対象を絞った再実行で証明できるのは、これから主張しようとしていることより限定的な内容です
「指摘が返ってこなかったので、もっと何か探します」コードがすでにクリーンだと確認すること自体が成果です。指摘をでっち上げると、実際の編集を、存在しないコストに対して行うことになります
「技術的には動作が変わりましたが、確実に改善しています」それは整理を装った設計変更です。amend-feature に回し、変更内容が明らかになるようにしてください

コメント