refactor-loop

Installation
SKILL.md

Refactor Loop

unilyze メトリクスの CodeHealth スコアを収束条件として、リファクタリングを反復実行する。

Quick Reference

unilyze metrics   # メトリクス定義、CodeSmell 閾値一覧
unilyze schema    # JSON 出力の全フィールドリファレンス

Usage

/refactor-loop [path] [--target <score>] [--max-rounds N]
  • path: プロジェクトルート (省略時: カレントディレクトリ)
  • --target: 目標 CodeHealth (省略時: 8.0)
  • --max-rounds: 最大ラウンド数 (省略時: 5)

Workflow

snapshot = get_or_create_baseline(path)
hotspots = unilyze_hotspot(path)    # git 履歴があれば churn x complexity で優先順位付け
targets = identify_worst_types(snapshot, hotspots, threshold=target)
# hotspots が取得できない場合 (非 git / 履歴不足) は CodeHealth 順にフォールバック

for round in range(1, max_rounds + 1):
    type_to_fix = pick_worst(targets)
    refactor(type_to_fix)           # コード修正
    run_tests()                     # テスト通過を確認
    diff = unilyze_diff(snapshot)   # 定量比較
    report_round(round, diff)

    if all_above_target(diff):
        break
    if has_degradation(diff):
        fix_degradation()           # 悪化を修正してから次へ

    snapshot = update_snapshot()

print_final_summary()

Step 1: ベースライン取得 & hotspot 分析

スナップショットはリポジトリルートの .unilyze/ に保存する。

UNILYZE_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.unilyze"
mkdir -p "$UNILYZE_DIR"

# /quality-audit で作成済みなら再利用
if [ -f "$UNILYZE_DIR/quality-audit.json" ]; then
  cp "$UNILYZE_DIR/quality-audit.json" "$UNILYZE_DIR/refactor-before.json"
else
  # --prefix または -a で自前コードに絞る (サードパーティ除外)
  unilyze -p <path> --prefix "App." -f json -o "$UNILYZE_DIR/refactor-before.json"
fi

hotspot を取得して優先順位を決定する (ループ開始時に1回だけ実行)。 git 履歴が十分にある場合のみ有効。非 git リポジトリや作りたてのリポジトリではスキップし、CodeHealth 順で進める。

# git 履歴があれば hotspot を取得 (失敗しても続行)
unilyze hotspot -p <path> 2>&1 || echo "hotspot unavailable, using CodeHealth order"

hotspot が取得できた場合、「変更頻度が高い かつ CodeHealth が低い」型を優先的にリファクタリング対象とする。 CodeHealth だけで順位付けすると、滅多に変更しないコードに労力を使ってしまう。

ワースト型を抽出:

jq --argjson t 8.0 '[.typeMetrics[] | select(.codeHealth != null and .codeHealth < $t)] | sort_by(.codeHealth) | .[0]' "$UNILYZE_DIR/refactor-before.json"

partial class や static 拡張メソッドクラスが GodClass 判定されている場合、 計測特性によるものであり改善対象から除外してよい (詳細: quality-audit/references/blind-spots.md)。

Step 2: リファクタリング実施

ワースト型のソースを読み、CodeSmell と メトリクスに基づいてリファクタリングする。

改善戦略の選択基準:

CodeSmell / Metric Strategy
GodClass (lines > 500) 責務ごとにクラス分割
LongMethod (lines > 60) メソッド抽出
HighComplexity (CogCC > 25) 条件分岐の整理、早期 return、ストラテジーパターン
DeepNesting (depth > 4) ガード節、メソッド抽出
HighCoupling (CBO > 14) インターフェース導入、依存逆転
ExcessiveParameters (> 5) パラメータオブジェクト導入
LowCohesion (LCOM > 0.8) 関連メソッド+フィールドを別クラスへ
BoxingAllocation struct に override (ToString, GetHashCode)、ジェネリック制約、Span 活用
ClosureCapture static ラムダ化、ローカル変数をパラメータ渡し、closureless overload
ParamsArrayAllocation 配列を事前作成して渡す、Span-based overload
CatchAllException 具象例外型で catch、必要なら rethrow
MissingInnerException throw new X("msg", e) で inner exception を渡す
ThrowingSystemException ArgumentNullException 等の具象例外に変更

1つのラウンドで1つの型に集中する。複数の型を同時に変更しない。

Goodhart's Law に注意: メトリクス値を下げるためだけの変更(関数の過度な分割、boxing回避のために可読性を犠牲にする等)は行わない。変更後に「全体の可読性・保守性が改善したか」を定性的にも確認する。

CycCC が高い箇所はテスタビリティの問題。CogCC が高い箇所は可読性の問題。改善戦略が異なるので区別する。

Step 3: テスト実行

リファクタリング後、テストを実行して既存動作を壊していないことを確認する。

dotnet test  # or project-specific test command

テストが失敗した場合、修正してからStep 4へ進む。

Step 4: 定量比較

unilyze -p <path> -f json -o "$UNILYZE_DIR/refactor-after.json"
unilyze diff "$UNILYZE_DIR/refactor-before.json" "$UNILYZE_DIR/refactor-after.json" 2>&1

判定ロジック:

  • Degraded = 0 かつ対象型の CodeHealth >= target → 成功、次の型へ
  • Degraded = 0 かつ CodeHealth < target → 改善不十分、同じ型で続行
  • Degraded > 0 → 悪化を修正してから再計測

Step 5: ラウンドレポート

## Round N

| Type | Before | After | Delta |
|------|--------|-------|-------|
| Namespace.TypeName | 5.2 | 7.8 | +2.6 |

Changes: {変更内容の要約}
Status: Improved / Degraded / Insufficient

Step 6: 収束判定

以下のいずれかで終了:

  • 全対象型が目標 CodeHealth に到達
  • 最大ラウンド数に到達
  • ユーザーが終了を指示

Step 7: 最終サマリー

## Refactor Loop Summary

| Round | Target Type | Before | After | Status |
|-------|-------------|--------|-------|--------|
| 1 | TypeAnalyzer | 5.2 | 7.8 | Improved |
| 2 | CodeSmellDetector | 6.1 | 8.5 | Target reached |
| 3 | DiffCalculator | 6.5 | 8.2 | Target reached |

Overall: N types improved, M reached target, K remaining

スナップショットを更新:

cp "$UNILYZE_DIR/refactor-after.json" "$UNILYZE_DIR/quality-audit.json"

Notes

  • 1ラウンド1型に集中し、変更のスコープを限定する
  • テスト通過を必ず確認してから次のラウンドへ
  • /quality-audit のスナップショットをベースラインとして再利用可能
  • 悪化が発生した場合は次のラウンドに進まず、まず悪化を修正する
  • hotspot はループ開始時に1回取得すれば十分。git churn はループ中に大きく変わらない
  • hotspot は git 履歴が必要。非 git リポジトリや履歴が少ない場合は CodeHealth 順にフォールバックする
Related skills
Installs
2
First Seen
Apr 9, 2026
Security Audits