melech-tidy について
melech-tidyは、AIを使ったコーディングで生じた差分を監査し、縮小するスキルです。検出内容を4種類に分類して根拠を示し、承認後にのみ変更します。
主な機能
- 01指定範囲の差分監査
- 02検出内容を4種類に分類
- 03根拠と整理案の提示
- 04変更前の承認確認
- 05テストによる変更の検証
活用シーン
- 01作業差分から未参照コードを削除
- 02重複するプロンプト指示の削減
- 03見た目だけの変更を元に戻す
- 04まれなケースへの対応を検討
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ adird/ agent-shell-hamelech --skill melech-tidyインストール後、Claude Code で/melech-tidyを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
evals/.gitattributesevals.jsonevals/fixtures/edge-case-trade.diffformatter-sweep.difffour-lanes.difflockfile.diffmarkdown.diffmoved-lines.diffreferences/lane-1-dead-code.mdlane-2-prompt-shake.mdlane-3-diff-noise.mdlane-4-edge-case-trade.md詳細
Tidy
AI エージェントでコーディングを終えたばかりです。機能は動作し、テストも通るかもしれませんが、git status を見ると差分が散らかっています。以前のプロンプトで追加されたまま残っているヘルパー、使われていない型、肥大化したプロンプトの指示、本来の変更を見えにくくする見た目だけの変更、あるいはほとんど起きない状況のための再試行や特別処理などです。
melech-tidy は、汎用的で適応性のある差分削減エンジンです。
差分にデッドコード、プロンプトの肥大化、見た目だけのノイズ、あるいは得られるメリット以上にコストがかかる稀なケースへの対応が含まれているかをユーザーに診断させるのではなく、melech-tidy は差分を監査し、検出事項を相互排他的な4つの削減レーンに分類し、具体的な根拠を示す表を提示して、承認を得てからピンポイントで整理します。各レーンは提案のみを行い、何を整理するかはユーザーが選択します。
Tidy は差し引くものであり、コードを別の境界に移したり、アーキテクチャを再設計したりするものではありません。
相互排他的な4つの削減レーン
エージェントは依頼された成果と周辺コードを読み取り、差分を検出事項に分解し、削減可能な各検出事項を、厳密に区分された1つのエンジンで評価します。変更されたすべての箇所に提案が必要なわけではありません。
Incoming Working Diff
│
Decompose into isolated findings
(semantic edits absorb inseparable
cosmetic surroundings)
│
┌───────────────────┴───────────────────┐
▼ ▼
Canonical artifact unchanged? Semantic change
│ │
▼ ┌─────────────┴─────────────┐
Diff noise [Code / Config] [Prompt / Rules]
(Cosmetic-only churn) │ │
Does deleting it change ▼
observable behavior in any case? Prompt bloat
┌──────────┴──────────┐
▼ no ▼ yes, a rare case
Dead code Edge-case trade
レーンは、コードの見た目ではなく、提案されたアクションが変更する内容によって相互排他的に分類されます。
| 提案されたアクション | レーン |
|---|---|
| 表現を元に戻す。正規の成果物は変更されない | 差分ノイズ |
| コードを削除または統合する。観測可能な変化はない | デッドコード |
| プロンプトまたは指示文を編集する | プロンプトの肥大化 |
| コードを削除または簡略化し、稀なケースで動作が変わる | エッジケースのトレードオフ |
同じ行に対して2種類のアクションが可能な場合(手書きのコードを、稀なケースで動作が異なる兄弟ヘルパーに置き換える場合など)、推奨するアクションのレーンに検出事項を1つだけ報告し、根拠の中で代替案に触れます。
ユーザー向けのラベル(必ずこれらのラベルを最初に使用してください。レポート、承認オプション、要約では「Lane 1/2/3」と表記しないでください)。
| 短いラベル | 正式名称 |
|---|---|
| デッドコード | デッドコードと AI の残骸 |
| プロンプトの肥大化 | 指示文とプロンプトの肥大化 |
| 差分ノイズ | 見た目だけの差分ノイズ |
| エッジケースのトレードオフ | エッジケースのトレードオフ(80/20) |
以下のレーン番号は内部のセクションアンカーとしてのみ使用されます。
Lane 1:デッドコードと AI の残骸(ガベージコレクション)
- 対象:AI による反復作業中に追加または変更された、呼び出されていない、孤立している、または不要なコード。
- 基本理念:立証責任の逆転。追加されたシンボルは、無実であると証明されるまでは有罪(残骸/デッドコード)とみなします。
- 4つの証拠による立証:
- 到達可能性の立証:実行時に、アクティブなエントリーポイント(ルート、UI コンポーネント、CLI コマンド、エクスポート、イベントハンドラー)から実際に到達できますか?できない場合 → 削除。
- 要件の立証:どの明示的なユーザープロンプトでこれが必要とされましたか?答えが 「後で必要になるかもしれないから」 なら → YAGNI に従って削除。
- 重複していないことの立証:既存のヘルパー、兄弟機能、標準ライブラリのユーティリティ、または依存関係のオプションですでに同じことができませんか?名前だけでなく、目的で検索してください。また、依存関係がすでに処理している可能性のある問題を分岐で回避している場合は、依存関係のソースコードを読んでください。すでに対応されている場合 → 統合。
- 破損の立証:今すぐ削除した場合、テストや動作に問題が起きますか?何も失敗せず、動作にも変化がない場合 → 削除。
- アクション:削除のみ(使用されていない関数、型、プロパティ、インポート、ゾンビチェーンを削除します)。
- 詳細な手引き:
references/lane-1-dead-code.md— 立証責任の逆転、4段階の残骸分類、呼び出しグラフ/ゾンビチェーンの追跡について説明します。
レーン 2:指示とプロンプトの肥大化(プロンプトの引き締め)
- 対象:システムプロンプト、スキルファイル(
SKILL.md)、ルール指示(.cursorrules、AGENTS.md)、および差分内の Markdown プロンプト文書です。 - 基本理念:必要な範囲を満たす最小限の内容が、最大限の内容に勝ります。すべての行は、重要な役割を果たしていると証明されるまでは削除対象です。再設計ではなく、削除します。
- プロンプトに対する5つの証明:
- 網羅性:削除すると、実際に必要なケースが対応できなくなりますか? そうでなければ → 削除。
- 重複性:この内容は指示の別の箇所ですでに述べられていますか? そうであれば → 統合。
- 包含性:このルールは、すでにあるより広範なルールに含まれていますか? そうであれば → 組み込む。
- 既定の知識:適切なモデルなら、促されなくてもこれを実行できますか? そうであれば → 削除。
- 重要性:この行がなくなると、エージェントの出力は実際に劣化しますか? そうでなければ → 削除。
- アクション:差分の範囲内で削除します(埋め草、重複するエッジケース、過剰な説明を取り除きます)。
- 詳細なプレイブック:
references/lane-2-prompt-shake.md— 対象となる項目、5つの証明の完全版、そして簡潔さと情報損失を混同しないためのガードレールを説明します。
レーン 3:見た目だけの差分ノイズ(正規表現の等価性に基づく整理)
- 対象:表現は変わっていても、正規化後の成果物と意図された意味が変わっていない、単独で見た目だけの指摘事項です。
- 基本理念:まずコンテキストを確認し、証明できなければ維持します。行が移動したからといって、それだけでノイズとは限りません。要件と周辺コードを読み、リポジトリに適したツールを使って正規化後の等価性を証明します。証明できない場合や、変更に意味上の編集が混在する場合は、このレーンでは扱いません。
- 証拠に基づく4つの証明:
- 意図の証明:この変更は、必要な動作や指示の効果と無関係ですか? スコープ、タイミング、順序を修正するために宣言を移動した場合は意味上の変更であり、対象外です。
- 正規化後の等価性の証明:安全な正規化だけを行った後、変更前後の成果物は構造的に同一ですか(たとえば、解析後のコード構造、指示文を含む Markdown の構造、解決済みの依存関係グラフが同一である場合)?
- 重要性の証明:変更された空白、順序、改行コード、メタデータは、この言語とリポジトリにおいて影響のないものですか? インポート、インデント、ファイルモード、コメント、スナップショット、生成された出力が見た目だけの変更だと決めつけないでください。
- 復元安全性の証明:必須のフォーマッター、ジェネレーター、ビルド、テストのチェックをすべて成功させたまま、見た目だけの差分をベースの表現に戻せますか?
- アクション:表現だけを復元します(見た目だけの差分を元に戻すか、リポジトリで想定されるツールを使って再生成します)。このレーンでは、意味を書き換えたり、生成された出力を手作業で編集したりしないでください。
- 詳細なプレイブック:
references/lane-3-diff-noise.md— 指摘事項の分解、成果物の種類ごとの正規化証明、混在した差分の扱い、フェイルクローズの落とし穴を説明します。
レーン 4:エッジケースの処理(80/20)
- 対象:まれなケースへの対応だけを目的とする、コード/設定ファイル内の実際に機能するコード。まれな競合状態へのリトライ、特殊なエラーメッセージ、復旧可能な手順を囲む防御的な try/catch、リポジトリ内の前例より厳格なガードが該当します。
- 基本理念:損失を明示してから、ユーザーに選択してもらいます。まれなケースを受け入れれば削除できるコードを見つけ、効果が最も小さい箇所で差分を縮小します。トレードオフを同等の選択肢として提示してはいけません。
- トレードオフを裏付ける5つの証明(すべて満たす必要があります):
- 頻度:何がこのケースを引き起こし、どれほどまれなのか。不明な頻度はリスクを高めます。
- 結果:対応をなくした場合、ユーザーには回復可能なエラーが見えるのか。結果が黙って誤ること、データ損失、二重請求、情報漏洩はトレードオフの対象になりません。
- 復旧:再試行や再度貼り付けるなど、簡単な対処方法はあるのか。
- 前例:同じケースを、類似機能はどのように処理しているのか。前例を上回る対応はトレードオフの対象ですが、前例を下回る対応は対象になりません。また、リポジトリのルールで必須とされる対応は維持します。
- 削減効果:どの行、テスト、定数、ヘルパー、概念を削除できるのか。実際の損失を伴うのに削減効果が小さい場合は、推奨する価値がありません。
- 絶対に下回ってはいけない基準:セキュリティと認証、テナントまたはユーザーの分離、データの整合性、金銭、プライバシーに関する対応は、リポジトリの前例までしか削減できず、それを下回ってはいけません。また、この指摘ではセキュリティレビュー担当者による確認が必要であることを明記します。
- 対応:損失を明示したうえで、トレードオフを推奨します。承認されたら、対応と、それだけに使われていたものをすべて削除し、削除したケースを説明するドキュメントを更新します。
- 詳細なプレイブック:
references/lane-4-edge-case-trade.md— 対象、5つの証明、絶対に下回ってはいけない基準、行の例。
ワークフロー
1. Resolve Scope ──► 2. Adaptive Diagnosis ──► 3. Present Evidence ──► 4. Ask Approval ──► 5. Tidy & Verify
(Prompt or Flag) (Route by lane name) Unified Table (ask_question) (Tests green)
ステップ 1:範囲の確認
監査の前に差分の範囲を確認します。指定がない場合は、デフォルトで未コミットの変更を対象とします。
- 未コミットの作業ツリー(ステージ済み+未ステージの git diff)— デフォルト
- ブランチとベースの比較(例:
origin/main...HEADまたはmain...HEAD) - 直近 N 件のコミット(例:
HEAD~2..HEAD) - 特定のファイルまたはパス
対象が曖昧な場合は、ask_question でユーザーに確認します。
ステップ 2:適応的な診断とレーンの振り分け
依頼された成果、周辺のコンテキスト、差分を調べます。ファイルを機械的に振り分けるのではなく、削減可能な指摘を振り分けます。
- 差分を分解する:
git diffのハンクを入力として使い、安全であれば独立した指摘に分けます。- 見た目だけの行を意味上の編集から分離できない場合は、その指摘全体を意味上のレーンで扱います。
- 整理された推奨を無理に作り出すことなく、意図的で必要かつ適切に配置された変更は残します。
- すべてのファイル種別で、単独の見た目上の候補を確認する:
- リポジトリに適したパーサー、フォーマッター、または正規化表現を使って、ベースと変更後の成果物を比較します。
- 4つの証明をすべて満たす場合に限り、差分ノイズに振り分けます。証明が1つでもなければ、このレーンには含めません。
- コード/設定ファイル(
.ts、.py、.go、.rsなど)の意味上の変更について:- 呼び出し元を見つけるため、コールグラフを上流にたどります。参照されていないシンボルやゾンビチェーンは、デッドコードとして指摘します。
- 新しいコードが再実装しているものがないか、目的ごとに類似機能、標準ライブラリ、依存関係の選択肢を検索します。重複はデッドコードとして指摘します。
- 各分岐、catch、リトライ、フォールバック、特殊なメッセージ、追加チェックが、どのケースに対応するために存在するのかを列挙します。5つのトレードオフの証明を確認し、手放す価値のあるまれなケースへの対応をエッジケースの処理として指摘します。トレードオフをユーザーが求めていない場合でも、整頓のたびにこのレーンを実行します。
- プロンプト/指示ファイル(
.md、.prompt、.cursorrulesなど)の意味上の変更について:- プロンプトの肥大化に関する5つの証明に照らして、変更行を監査します。
Step 3: 統合した証拠・診断テーブルを提示する
コードを変更する前に、レーンごとにまとめた、見やすく一覧性の高いテーブルを出力します。Lane 列では、短いラベル(Dead code、Prompt bloat、Diff noise、Edge-case trade)を使用し、レーン番号は使用しません。What we lose は、Edge-case trade 以外のすべてのレーンで — とし、Edge-case trade ではユーザー側で失われるケースを記載します。
### 🧹 Tidy Audit Results (Scope: uncommitted diff)
| Lane | Target | Issue / Evidence | Proposed Action | What we lose | Risk |
|---|---|---|---|---|---|
| **Dead code** | `src/utils/date.ts:L40` (`formatDateV2`) | **Reachability**: 0 callers across repo. | Delete dead helper | — | Low |
| **Dead code** | `src/types/user.ts:L15` (`DraftRole`) | **Breakage**: Unreferenced enum variant. | Delete variant | — | Low |
| **Prompt bloat** | `skills/deploy/SKILL.md:L18` | **Default Knowledge**: Explains how git commit works to the model. | Cut line | — | Low |
| **Diff noise** | `src/routes/admin.ts:L20-L45` | **Canonical equivalence**: Formatter-only delta; parsed structure is unchanged and format check passes after restore. | Restore base formatting | — | Low |
| **Edge-case trade** | `src/connect/service.ts:L120-L134` (retry on 400) | **Frequency**: only when two users connect the same site within a second. **Recovery**: connecting again succeeds. **Precedent**: no other connector retries. | Drop retry, `RETRY_DELAY_MS`, `delay()`, and its test | One of two simultaneous connects fails and must be retried | Low |
5 つのトレード検証を通過するまれなケースの処理がない場合は、そのレーンを黙って省略するのではなく、テーブルの下に 1 行でその旨を記載します。
Step 4: ユーザーに明示的な承認を求める
人間の承認なしに、ファイルを変更したりコードを削除したりしてはいけません。
ask_question を使ってユーザーに尋ねます。
- Question: "tidy の推奨事項にどのように対応しますか?"
- Options:
(Recommended) すべての推奨事項を適用する(dead code、prompt bloat、diff noise、edge-case trade)動作を維持するクリーンアップのみ適用する(dead code + prompt bloat + diff noise。edge-case trade はスキップ)テーブルから適用する項目を選ぶキャンセル(作業ツリーを変更しない)
edge-case trade がない場合は、オプション 2 を省略します。
Step 5: 的を絞った整理と検証
承認されたら、次の手順を実行します。
- Diff noise を適用する:承認された見た目だけに関する指摘を元の表現に戻します。生成ファイルは手動で編集せず、想定されているジェネレーターやフォーマッターを使用します。
- Dead code を適用する:デッド関数、型、参照されていないインポートを削除します。
- Prompt bloat を適用する:差分の範囲内にあるプロンプト/指示ドキュメントから冗長な部分を削除します。
- Edge-case trade を適用する:承認された処理と、それだけに使用されていたもの(定数、ヘルパー、インポート、テスト)をすべて削除します。メインパスが引き続き動作することを確認するテストは残し、削除したケースに言及しているドキュメントやコメントを更新します。
- 重要なコンテキストを維持する:重要なコメントや意図を説明する注記はそのまま残します。
- 検証を実行する:
- テストを実行します(
npm test、pytest、cargo test、go test)。 - 型チェック/ビルドを実行します(
tsc、mypy、cargo check)。 - テストが失敗した場合は、ただちに修正するか、問題のある変更を元に戻します。
- テストを実行します(
- 概要を報告する(番号ではなくレーン名から始めます):
- Dead code、Prompt bloat、Diff noise、Edge-case trade での変更内容
- 適用した各トレードについて、コードが処理しなくなったケース
- 削除/追加した行数
- 整理したファイル、またはクリーンな状態に戻したファイル
- 検証状況(例:
36 件すべてのテストが成功)
Do / Don't
- Do:デッドコードの削除(Dead code)、プロンプトの簡素化(Prompt bloat)、見た目上の変更の復元(Diff noise)、まれなケースとのトレード(Edge-case trade)を、それぞれ区別された、相互に排他的な作業として扱います。
- Don't:動作しているアーキテクチャを書き換えないでください。整理とは、不要なものを取り除く作業です。
- Do:コードがデッドだと判断する前に、具体的な呼び出しグラフで到達可能性を証明します。
- Don't:呼び出し元と要件を挙げずに、「不要そうです」と言わないでください。
- Do:リポジトリですでに解決済みの問題に対応する新しいコードを残す前に、目的が同じ関連機能を検索します。
- Don't:Edge-case trade 以外で動作を削除したり、トレードを同等または「最小化した」と表現したりしないでください。どのトレードでも、失われるものを明示します。
- Don't:セキュリティ、分離、データ整合性、金銭、プライバシーを、リポジトリの従来の水準より低下させるトレードを行わないでください。
- Do:ある行が移動した理由を確認し、見た目上の変更と判断する前に正規の状態と同等であることを証明します。
- Don't:インポート、宣言の移動、空白、生成ファイル、ファイルモードを、見た目だけでノイズと分類しないでください。
- Do:不確かな見た目上の変更候補は差分に残し、Diff noise には含めないという、保守的な判断をします。
- Do:コードを変更する前に、
ask_questionを介して人間から明示的な承認を得ます。