Refactoring Skill
リファクタリングの定義・制約・禁止事項は references/definition.md を参照。 候補記録のテンプレートは references/discovery-template.md を参照。
ワークフロー
1. スコープレベルの確認
2. リファクタリング候補の探索
2a. 探索の分割戦略
2b. 探索の実行
2c. 結果の集約と提案
3. 振る舞い保持の検証(Gate)
3.5 テスト追加後の再開フロー
4. リファクタリングの実施
5. 完了の確認
6. 変更内容のサマリ出力
1. スコープレベルの確認
明示指示がない場合は Level 1(デフォルト)で進める。
| Level | 範囲 | 必要な明示指示 |
|---|---|---|
| 1 | 関数内 / 1ファイル内 | 不要(デフォルト) |
| 2 | 複数ファイル / 依存関係の整理 | 必要 |
| 3 | アーキテクチャ変更 | 必要 |
2. リファクタリング候補の探索
対象が明示されていない場合に実施。「直す価値が高く」「範囲が限定でき」「テストで守れる」箇所を候補化する。対象が指定されている場合は探索を省略し、Step 3 へ進む。
探索結果は refactoring-discoveries/ に記録する。ユーザーが既存候補の場所を指定した場合はその場所を使う。テンプレートは references/discovery-template.md を参照する。
既存の発見結果がある場合
既存候補は現在のソース・呼び出し元・テストと照合し、対象の存在、行範囲、根拠、影響範囲、Gate B 材料を更新する。古いカバレッジ記述やステータスだけで実行可否を決めない。
現状でも有効な候補が依頼範囲を満たす場合は新規探索を省略する。不足分だけ追加探索する。対象が削除済み・改善済みの候補は 対象外 と理由を記録して実行対象から外し、無関係な候補を削除しない。既存候補を確認して実行する依頼では、Gate を満たす候補について再度の選択を求めず進める。
2a. 探索の分割戦略
小規模・局所的な対象は逐次探索する。独立した複数の探索範囲があり並列化の効果が見込める場合は、利用可能なサブエージェント機能と同時実行上限に合わせて分割してよい。特定のツール名や固定のエージェント数を前提としない。並列機能がない場合や起動に失敗した場合は同じ観点を逐次調べる。
- ディレクトリ単位: パッケージや責務で独立するソース範囲を担当に分ける。
- 分析観点単位: 複雑性・重複・依存から、依頼範囲に必要な観点を分ける。
2b. 探索の実行
探索担当はソースを変更せず、次の情報を集約担当に返す。逐次探索ではメインエージェントが両方を担当する。
- 対象のファイルパス・修飾された関数/メソッド名・現在の行範囲
- 問題の根拠、期待効果、影響範囲、推奨アプローチ、必要なスコープレベル
- 関連テストと Gate B のカバー済み/未カバーパス
- 分析観点と、測定できた指標(推定値は推定と明記)
ファイル列挙・テキスト探索は rg --files・rg など利用可能な手段を使う。複雑性は行数・ネスト・分岐、重複は同じ変更を複数箇所に必要とする処理、依存は循環や責務の不整合を調べる。長い関数や重複数だけで変更を正当化せず、具体的な保守上の問題を示す。
必要に応じて git log --oneline --follow -- <file_path> などから変更頻度を確認する。履歴がない場合は未取得とし、数値を捏造しない。コミットメッセージ中の fix/bug は実際の不具合件数とは区別する。
探索担当は共有候補ディレクトリに書き込まない。 返却内容を集約担当が受け取り、次の手順で保存する。
2c. 結果の集約と提案
- 重複排除: 既存候補と探索結果を、ファイルパスと修飾されたシンボル名・対象範囲で照合する。同一対象の複数観点は根拠を統合する。同名関数でも別ファイル・クラスなら別の対象として扱う。
- 保存: 集約担当だけが採番・保存する。既存の番号を保持し、新規候補は使用済み番号とファイル名を確認して未使用番号を割り当てる。既存候補を上書きして別候補に置き換えない。候補ディレクトリの状態更新と完了時の削除も集約担当が行う。
- 優先付け: 保守上の効果、変更頻度、振る舞い保持の検証可能性、変更範囲をもとに順位を決める。未取得の指標で順位を水増ししない。
- 提示: 上位候補(目安5件、ユーザー指定を優先)を、対象・根拠・期待効果・影響範囲・Gate B 材料とともに提示する。
| # | 対象(ファイル:行 / 関数名) | 根拠 | 期待効果 | 影響範囲 | Gate B 材料 |
|---|---|---|---|---|---|
| 001 | foo.ts:42 / parseUser |
条件分岐が重なり入力追加時の変更漏れが起きやすい | 検証条件の見通しを改善 | 呼び出し元3箇所 | 正常系のみカバー |
候補調査のみの依頼では提示して終了する。実施の依頼では指定範囲内の有効な候補を選び Step 3 に進む。ユーザーに選択を委ねる指示がある場合や、範囲を決めるために回答が必要な場合だけ選択を求める。
3. 振る舞い保持の検証(実行前 Gate チェック)
リファクタリングを実行する前に、選択された各候補ごとに以下の2つの Gate を確認する。
Gate A(必須条件): 既存の自動テストがすべて成功すること。
Gate B(十分性チェック): 変更対象の重要パスがテストされていること:
- 正常系(代表入力)
- 境界値(空/0/最大長/上限付近)
- 異常系(例外・エラー条件)
- 副作用(DB更新・外部I/O・キャッシュなど)
Gate A と Gate B を両方満たす候補のみ、リファクタリングを実行する。
いずれかが未達の場合はその候補のリファクタリングを中止し、以下を実施する:
出力(ユーザーへ):
- 未達の条件(A/B のどれか)
- 根拠(カバレッジ値、未テストの重要パスの具体)
- 実行しない理由(仕様保持を客観的に担保できないため)
- 推奨対応(追加すべきテストの概要)
記録(ファイルへ):
- 該当候補 MD ファイルがある場合はステータスを
中止に更新し、中止理由を追記する。対象指定で探索を省略した場合は、以下の中止ログだけでよい - プロジェクトルートの
refactoring-aborted.mdに追記する。ファイルが存在しない場合は新規作成し、先頭に# リファクタリング中止ログヘッダーを付ける
## YYYY-MM-DD | `<対象ファイル:行>` / `<関数名>`
- **未達Gate**: A / B(該当するもの)
- **根拠**: <カバレッジ値・未テストパスの具体>
- **推奨対応**: <追加すべきテストの概要>
3.5 テスト追加後の再開フロー
ユーザーがテストを追加してリファクタリングの再実行を依頼した場合:
- 対象とテストを現状に照合し、Gate A・B を再チェックする
- 両方通過した場合: 該当候補 MD があればステータスを
実行中に更新し、Step 4 へ進む(リファクタリング完了後に Step 5 でrefactoring-aborted.mdのエントリーを削除する) - まだ未達の場合: 残る未達条件と追加対応を案内し、
refactoring-aborted.mdの該当エントリーの「推奨対応」を更新する
4. リファクタリングの実施
既定は逐次実行とする。複数候補でも、依存関係があるものは依存順に扱う。
- 該当候補 MD があれば集約担当がステータスを
実行中に更新する。 - references/definition.md の禁止事項を守り、最小限・段階的に変更する。
- 変更後にテストを再実行する。失敗した場合は今回の変更を調査・修正し、無関係なユーザーの変更を巻き戻さない。
独立した複数候補では、利用可能なサブエージェント機能で並列実行してよい。編集範囲を重複させず、必要なら隔離した作業ツリーを使う。分離できない場合や並列機能がない場合は逐次実行する。既存の実施指示の範囲内なら、並列化だけを理由に再確認しない。
各担当には対象・編集範囲・Gate A/B の根拠を渡す。担当は変更内容とテスト結果を返し、候補ファイルは更新しない。メインエージェントが差分を確認して統合し、統合後のコードでテストを実行する。競合は意図と仕様が明確なら解決し、仕様上の選択が必要な場合に限ってユーザーに確認する。
5. 完了の確認
以下の成功条件をすべて満たすことを確認する:
- 振る舞いが変更されていない(テストが通る)
- コードの理解しやすさが向上している
- 変更の影響範囲が限定されている
- 不要な複雑性が減少している
確認後、以下のクリーンアップを行う:
- 該当候補 MD ファイルがあれば集約担当が削除する。完了した候補の情報は Step 6 のサマリで報告するため、ファイルとして残す必要はない。使用した候補ディレクトリが空になった場合はディレクトリごと削除してよい
refactoring-aborted.mdに対象のエントリーが存在する場合はそのエントリーを削除する。ファイルがヘッダー行のみになった場合はファイルごと削除してよい
6. 変更内容のサマリ出力
完了後、以下を簡潔に報告する:
- 実施したリファクタリングの種類と箇所
- 改善した点(可読性・重複排除など)
- テスト結果(Gate A/B の確認結果)
- 使用した候補ディレクトリ内の残り候補数(ステータス別の件数)