**『レガシーコード2万行、Claude Codeに丸投げすれば1日で終わるだろう』**──その甘い見積もりが、3日間のロールバック地獄の始まりだった。
結論から
Claude Codeはリファクタリングの強力な武器ですが、「何を任せ、何を人間が握るか」の境界設計を怠ると、修正よりロールバックに時間を使う羽目になります。この記事では、私が実際に踏んだ5つの地雷と、そこから導いた「任せる範囲チェックリスト」「改善後のCLAUDE.md設定」を公開します。
背景:築5年のRailsモノリス2万行をClaude Codeで一掃したかった
対象は社内の業務管理システム。Rails 6で作られ、5年間の機能追加で約2万行にまで膨張したモノリスです。
- Fat Controller / Fat Model が多数
- テストカバレッジは約45%
- 命名規則がファイルごとにバラバラ
- 「触ると壊れる」と誰もが恐れるモジュールが3つ
「Claude Codeにコンテキストを渡せば、一気にきれいにできるのでは?」──そう考えて、金曜夕方に作業を開始しました。
環境・前提条件
| 項目 | 内容 |
|---|---|
| 言語/FW | Ruby 3.2 / Rails 7.0(Rails 6から直前にアップグレード済) |
| コード規模 | 約2万行(app/ 以下) |
| テスト | RSpec、約320 examples |
| Claude Code | 2025年6月時点の最新版 |
| CLAUDE.md | 初回は未設定(これが最大の失敗) |
全体ワークフローと地雷マップ
まず、今回のリファクタリングで辿った流れと、どこで地雷を踏んだかを俯瞰します。
ここから各地雷を詳しく見ていきます。
地雷① 依存関係の暗黙知を読めず、30テストが連鎖Red
何が起きたか
OrderService#calculate_total のシグネチャを (order) → (order, tax_rate:) に変更するよう指示したところ、Claude Codeは呼び出し元をapp/ 以下のみ検索して書き換えました。
しかし実際には、Rakeタスク・Sidekiqジョブ・concerns内のメタプログラミング経由でも呼ばれており、これらは検索から漏れていました。結果、bundle exec rspec で30 examples が一気にRed。
なぜ起きたか
- Railsの
sendやmethod_missing経由の呼び出しは静的解析で拾いにくい - Claude Codeに**「依存関係の全体像」を提示しなかった**
-
grepベースの検索ではメタプログラミングは見つからない
対策
<!-- CLAUDE.md に追記 -->
## リファクタリング制約
- 関数シグネチャの変更前に、必ず `grep -r "メソッド名" .` の結果を提示し、
人間の承認を得ること
- send / method_missing 経由の呼び出しが存在する可能性を常に考慮すること
- シグネチャ変更後は必ず `bundle exec rspec` の全実行結果を確認すること
地雷② CLAUDE.mdに制約を書かなかったら、DBスキーマまで変更された
何が起きたか
「このモデルをリファクタリングして」という曖昧な指示を出したところ、Claude Codeは「正規化が不十分」と判断し、マイグレーションファイルを生成してカラム分割を提案してきました。
開発環境で rails db:migrate を走らせてしまい、既存のseedデータやローカルのテストデータが壊れました。
なぜ起きたか
- 「リファクタリング」のスコープを定義していなかった
- Claude Codeは「コード品質の改善」を広義に解釈し、スキーマ変更も「改善」に含めた
- CLAUDE.mdが空だったため、禁止事項が何もなかった
対策
<!-- CLAUDE.md に追記 -->
## 絶対に変更してはいけないもの
- db/migrate/ 以下のファイル(新規作成も禁止)
- db/schema.rb
- config/database.yml
- Gemfile(gem追加は人間が判断する)
教訓:「やっていいこと」より「やってはいけないこと」を先に書く。
地雷③ トークン上限で文脈が飛び、命名規則が前半と後半で不統一
何が起きたか
2万行のコードベースを1セッションで処理しようとした結果、セッション後半でClaude Codeの文脈窓からコンテキストが溢れました。
- 前半:
calculate_subtotal,calculate_tax(snake_case + 動詞始まり) - 後半:
subtotal_amount,tax_value(名詞始まり)
さらに、前半で定義した共通ヘルパーの存在を後半では「忘れて」おり、同じロジックが2箇所に重複する結果に。
対策:分割戦略の導入
<!-- CLAUDE.md に追記 -->
## 命名規則
- メソッド名: 動詞 + 名詞(例: calculate_total, fetch_user)
- 変数名: 名詞(例: total_amount, user_record)
- 定数: UPPER_SNAKE_CASE
- 1セッションで扱うファイルは最大5ファイル・500行までとする
教訓:1セッション500行ルールを設けると、文脈落ちが激減する。
地雷④ テスト生成を任せたらモックだらけでカバレッジが空洞化
何が起きたか
「このサービスクラスのテストを書いて」と依頼すると、Claude Codeは外部依存をすべて allow(...).to receive(...) でモック化した、見た目は完璧だが本質的に何も検証していないテストを生成しました。
# Claude Codeが生成したテスト(問題あり)
it "calculates total" do
allow(order).to receive(:items).and_return([item1, item2])
allow(item1).to receive(:price).and_return(100)
allow(item2).to receive(:price).and_return(200)
allow(tax_service).to receive(:rate).and_return(0.1)
expect(service.calculate_total(order)).to eq(330)
# ↑ モックの返り値を足し算しているだけで、実際のDBやロジックは一切通っていない
end
カバレッジレポート上は80%に上がりましたが、実際のバグを捕まえる力はゼロでした。
対策
<!-- CLAUDE.md に追記 -->
## テスト方針
- 外部API・メール送信のみモック可。DB・ActiveRecordはFactoryBotで実データを使うこと
- モックを使う場合は、コメントで「なぜモックが必要か」を1行書くこと
- 1テストファイルあたりのモック数が5を超えたら人間にレビューを依頼すること
地雷⑤ PRが巨大すぎてレビュアーが読めない
何が起きたか
Claude Codeの作業成果を1つのPRにまとめたところ、変更ファイル47、差分+1,200行 / -800行という巨大PRが完成。レビュアーから「読めません」と即座に差し戻されました。
対策:プロンプトにPR分割戦略を組み込む
<!-- CLAUDE.md に追記 -->
## PR・コミット戦略
- 1PRあたりの変更は最大10ファイル・300行差分まで
- 以下の粒度でPRを分割すること:
1. リネーム・移動のみ(ロジック変更なし)
2. ロジックの抽出・分離
3. テストの追加・修正
4. 不要コードの削除
- 各コミットメッセージは Conventional Commits 形式で書くこと
学び:改善後のCLAUDE.md全体像
5つの地雷を踏まえて作成した、改善後のCLAUDE.mdの構造を示します。
任せる範囲チェックリスト
実際に運用しているチェックリストを公開します。
| 作業 | Claude Codeに任せる | 人間が握る |
|---|---|---|
| メソッドのリネーム | ✅ | 影響範囲の最終確認 |
| Fat Controllerの分割 | ✅ | 分割先のクラス設計 |
| 関数シグネチャの変更 | ❌ | ✅ 人間が設計し、書き換えのみ委託 |
| DBスキーマ変更 | ❌ | ✅ 完全に人間の領域 |
| テストコード生成 | ✅(制約付き) | モック方針の事前指示 |
| PR作成・分割 | ✅(制約付き) | 分割粒度の事前設計 |
| デッドコード削除 | ✅ | 「本当に使われていないか」の判断 |
| パフォーマンスチューニング | ❌ | ✅ 計測→判断は人間 |
改善後の成果
CLAUDE.mdを整備し、分割戦略を導入した2回目のリファクタリングでは:
- 所要時間: 3日(1回目は3日かけてロールバック。実質ゼロ進捗)
- PR数: 12本(1本あたり平均150行差分)
- テスト: 全グリーンを維持したまま、カバレッジ45% → 68%
- レビュー: 全PRが1日以内に承認
まとめ
- CLAUDE.mdの「禁止事項」は最初に書く。 「やっていいこと」より「やってはいけないこと」を定義することで、想定外の破壊的変更を防げます
- 1セッション500行・1PR300行の上限を設ける。 トークン上限による文脈落ちと、レビュー不能な巨大PRの両方を回避できます
- シグネチャ変更とDB変更は人間の領域。 暗黙の依存関係やメタプログラミングの影響は、現時点のAIでは安全に判断しきれません
AIリファクタリングは「全自動」ではなく「半自動」です。人間が握るべきラインを明確にすることで、初めてClaude Codeは真価を発揮します。