計画承認→実装→セルフレビュー是正→マージ:移行案件を「記録駆動」で回す開発ループ
概要
レガシーシステムの移行・是正案件では、1週間で十数個の修正PRが並行して流れることがある。テナントフィルタの横断是正、ロールガードの追加、2リポジトリにまたがる仕様の食い違い——粒度もリスクもバラバラなタスクを、抜けなく・後から追跡できる形で捌く必要がある。
本稿では、そうした現場で有効だった「記録駆動の開発ループ」を、特定のプロダクトに依存しない一般化した手順としてまとめる。要点は3つ。
- すべてのタスクを「計画承認 → 実装 → セルフレビュー是正 → マージ」の同じループに乗せ、各段階を必ず記録に残す
- 大きな横断是正は「Stage / PR A・B・C」に分割し、1PR1関心に保つ
- 「原典忠実移植」と「是正」を意識的に切り分ける(見た目のバグを勝手に直さない)
発生した問題
移行・是正案件で典型的に起きる困りごとは、機能の難しさそのものより「進め方」に起因する。
- タスクの粒度がバラバラ:1行のロールガード追加から、5段階に分けないと安全に直せない横断是正まで混在する
- 重複起票と手戻り:別々に切ったチケットが実は同一原因、という取り下げが頻繁に起きる
- 「バグに見えるが仕様」問題:移行元の挙動(例:ある例外を握り潰している)を「バグ」と判断して直すと、移行の忠実性が壊れる
- 結論が後から覆る:コードを読んだだけの判断が、履歴や本番実データで再調査すると間違っていた、というケース
これらは「あとで説明できない変更」を量産し、レビュー負荷と信頼低下を招く。
原因
根本原因は「判断の履歴が残らないこと」に集約される。なぜこの修正をしたのか(計画)、自分で気づいて直した点(セルフレビュー是正)、なぜ直さなかったのか(忠実移植の意図的スキップ)、結論を覆した根拠(履歴・本番データ)——これらが残らないと、同じ調査を何度もやり直し、重複起票が起き、レビュアーは差分の意図を推測するしかなくなる。
対応方法
すべてのチケットを、粒度に関係なく同じ4段階ループに乗せる。
[1] 計画承認 … 何を・どこまで直すか範囲を確定し、承認を記録
↓
[2] 実装 … 変更箇所を列挙してから着手(push 前に自己点検)
↓
[3] セルフレビュー是正 … 自分で見つけた指摘を「是正記録」として残す
↓
[4] マージ … PR番号と結論を記録。派生課題があれば起票
ステップ1:計画承認で「範囲」を先に確定する
着手前に、修正範囲を1行で確定させる。「フィルタの横断是正」「Stage 1+2 に範囲確定」のように、どこまでやるか/やらないかを明示する。これが後の分割とレビューの基準になる。
ステップ2:大きい是正は Stage / PR に分割する
横断的な是正(例:あるフィルタ条件を全画面・全エンドポイントに適用し直す)は、一括PRにすると差分が膨れてレビューできない。「Stage 1+2 → 3 → 4 → 5」や「PR A → B → C」のように、レビュー可能な単位に割る。
分割の基準:
- 1PRは1つの関心事だけを扱う
- 各Stageが単体でマージ可能(前段がマージされても壊れない)
- Stageの区切りは「レビュアーが一息で読める差分量」
ステップ3:セルフレビュー是正を「記録」する
PRを出す前に自分で1周レビューし、見つけた指摘を分類して残す。粒度は Critical / Minor 程度で十分。
F-XX セルフレビュー是正 - C-1: ロールガードが1エンドポイントに欠けていた → 追加 - Minor-1: 静的解析(PHPStan)に関するコメント記述が不正確 → 訂正
セルフレビューを記録に残すと、レビュアーは「作者が既に気づいて直した点」を再指摘せずに済み、レビューが本質的な論点に集中する。
ステップ4:忠実移植と是正を切り分ける
移行案件で最も事故りやすいのが、「移行元のバグに見える挙動を、良かれと思って直してしまう」こと。
// 移行元がこの例外を握り潰していたとする
try {
$this->handleInquiry($payload);
} catch (SomeException $e) {
// 移行元では意図的に無視されている
// → 忠実移植フェーズでは「直さない」と決めて記録する
}
判断ルール:
- 移行フェーズ:挙動の等価性が最優先。見た目のバグでも直さず「原典忠実移植のため是正しない」と結論を記録する
- 是正フェーズ:改善は別チケットとして切り、移行完了後に扱う
「直さなかった理由」まで残すと、後任が同じ箇所を再度「バグ」として起票する無駄がなくなる。
ステップ5:結論はコードだけで確定しない
コードを読んだだけの結論は覆ることがある。あるスコープが「存在しない」と判断したが実は存在した——というような訂正は珍しくない。
- 疑わしい結論は 履歴 + 本番実データ で裏を取ってから確定する
- 覆ったら、覆した事実と根拠を記録に残す(「再調査により結論を訂正」)
実装例:チケット記録のテンプレート
チケットごとに、次のような追記式の記録を残すだけでよい。特別なツールは不要で、Markdownで十分。
## F-XX フィルタ横断是正 ### 計画(承認済み) - 範囲: 一覧・詳細・エクスポートの3経路にフィルタを適用 - 非対象: 管理者用画面(別チケットで扱う) ### 分割 - PR A: 一覧(#114 マージ済) - PR B: 詳細(#116 マージ済/PHPStan記述をMinorで訂正) - PR C: エクスポート(#117 マージ済) ### セルフレビュー是正 - C-1: 詳細でロールガードが未適用 → 追加 ### 忠実移植メモ - 例外の握り潰しは移行元準拠のため今回は是正しない ### 派生 - F-YY を起票(管理者画面の同種是正)
このテンプレートの効きどころは「追記式」であること。計画→分割→是正→派生を時系列で積むだけで、後から誰が見ても判断の流れを追える。
確認方法
ループが機能しているかは、次で確認できる。
- 重複起票の取り下げが記録されているか:「F-XX は F-YY の重複起票と判明したため取り下げ」のような取り下げが残っていれば、記録が調査の重複を防いでいる証拠
- PRの差分が一息で読めるか:Stage分割が効いていれば、各PRは単一の関心事に収まる
- 「直さなかった理由」が残っているか:忠実移植の判断が記録に現れているか
- 自動実行系の網羅率:定型処理(バッチ・ジョブ)を移行する場合、「対応済み種別 / 全種別」を数えて進捗を可視化する
注意点
- 記録は完璧を目指さない。1チケット数行で十分。重いフォーマットは続かない
- セルフレビューの分類は粗くてよい。C/Minor の2段階で運用が回る
- 忠実移植の判断は必ず言語化する。「なんとなく直さなかった」は後で「直し忘れ」と区別できない
- 結論の訂正を恥じない。覆した記録こそ、後任にとって最も価値がある
まとめ
移行・是正案件を安全に速く回す鍵は、機能の難易度ではなく「判断を記録に残すこと」にある。全タスクを「計画承認 → 実装 → セルフレビュー是正 → マージ」の同じループに乗せ、横断是正は Stage / PR に分割して1PR1関心に保ち、「忠実移植で直さない」判断と「結論の訂正」まで記録する。記録駆動にすると、重複調査・重複起票・意図不明な差分が減り、レビューが本質に集中する。ツールは要らない。Markdownの追記だけで始められる。
