diff --git a/.claude/commands/auto-refactor.md b/.claude/commands/auto-refactor.md index aa30a15..7555642 100644 --- a/.claude/commands/auto-refactor.md +++ b/.claude/commands/auto-refactor.md @@ -1,36 +1,42 @@ --- name: auto-refactor model: opus -description: "放置中(無人)に自律的に回り続け,空き時間を大規模リファクタリングに充てるループ.テスト保護下の箇所のみを対象に,リファクタ→テスト緑確認→専用ブランチへ自律コミット,を安全な対象が尽きるまで繰り返す." +description: "放置中(無人)に自律的に回り続け,空き時間をコードの大規模リファクタリングとドキュメント同期に充てるループ.テスト保護下のリファクタと,実装を真としたドキュメント追記(矛盾は報告のみ)を,対象が尽きるまで繰り返し,専用ブランチへ自律コミットする." argument-hint: "<対象ディレクトリ/モジュールの絞り込み(省略可)>" --- -あなたは**自律リファクタリングループのオペレーター**です. -ユーザーが席を外している無人時間に,空いた稼働枠を大規模リファクタリングに充てるために起動されました. -GUIDE_04(Git 運用)と GUIDE_05(エージェント運用)を読み,書式・パイプラインのルールを理解した上で,以下の不変条件を厳守してループを回してください. +あなたは**自律リファクタリング&ドキュメント同期ループのオペレーター**です. +ユーザーが席を外している無人時間に,空いた稼働枠を「コードの大規模リファクタリング」と「実装とドキュメントのズレ解消」に充てるために起動されました. +GUIDE_02(ドキュメント作成),GUIDE_04(Git 運用),GUIDE_05(エージェント運用)を読み,書式・規約・パイプラインのルールを理解した上で,以下の不変条件を厳守してループを回してください. + +このループが扱う作業は **2 種類**ある. + +- **コードリファクタ系**:挙動を変えずにコード品質を改善する(安全網=テスト). +- **ドキュメント同期系**:実装を真として `docs/` の記述を実態に近づける.ただし「ドキュメントに無い事項の追記」は自動で行い,「ドキュメントと実装の矛盾」は自動で書き換えず報告のみ(後述). ## このコマンドの位置づけ(重要) - 本コマンドは **CLAUDE.md の「`/commit` 自発実行禁止」ルールに対する,ユーザー承認済みの明示的な例外**である. - - ただし例外が認められるのは **`refactor/` 専用ブランチへのコミットに限る**. + - ただし例外が認められるのは **`refactor/` 専用ブランチへのコミットに限る**(リファクタ・ドキュメント同期いずれの成果もこのブランチに積む). - **`git push`・PR 作成・マージ・`main` への操作は一切行わない**(マージ可否の判断は後で人間が行う). -- 「無人で回り続ける」ことが目的のため,各 Phase での人間確認は挟まない. - - これが許されるのは,**リファクタリングが「挙動を変えない」作業であり,テストが安全網として人間確認の代わりを果たす**から. - - したがって**テストという安全網が無い箇所には絶対に触らない**(後述の不変条件). +- 「無人で回り続ける」ことが目的のため,各 Phase での人間確認は挟まない.これが許される根拠は作業種別ごとに異なる: + - **コードリファクタ系**:リファクタは「挙動を変えない」作業であり,**テストが安全網として人間確認の代わりを果たす**から(テスト無しの箇所には触らない). + - **ドキュメント同期系**:**追記(事実の補完)に限定**し,かつ**矛盾の自動上書きをしない**から.意図的に書かれた記述を壊さず,バグを仕様に固定しない(後述の不変条件 8). ## 不変条件 (Invariants) — 1つでも破れそうなら停止する 1. **挙動を変えない**:リファクタ前後で**検証スイートが完全に緑のまま**であること(検証スイート=テスト+利用可能ならビルド/型チェック/リンタ.後述).赤が1つでも出たら,その変更は破棄(revert/stash)して対象をスキップする. -2. **テスト保護下で着手する**:リファクタは必ず**安全網(緑のテスト)がある状態**で行う.対象にテストが無い場合は,**まず特性化テスト(現状の挙動を固定するテスト)を生成して保護下にしてから**着手する(後述のステップ A2).テストフレームワーク自体が特定できない/生成テストを流せない箇所は対象にしない. +2. **テスト保護下で着手する**:リファクタは必ず**安全網(緑のテスト)がある状態**で行う.対象にテストが無い場合は,**まず特性化テスト(現状の挙動を固定するテスト)を生成して保護下にしてから**着手する(後述のステップ R2).テストフレームワーク自体が特定できない/生成テストを流せない箇所は対象にしない. 3. **専用ブランチのみ**:作業は `refactor/` ブランチ上でのみ行う.`main` には絶対にコミットしない. 4. **push/PR しない**:リモート操作は一切しない. -5. **1リファクタ = 1コミット**:意味のあるまとまり単位でこまめにコミットし,巨大な未コミット差分を溜めない. +5. **1作業 = 1コミット**:意味のあるまとまり(1リファクタ/1ドキュメント更新)単位でこまめにコミットし,巨大な未コミット差分を溜めない. 6. **除外領域に触れない**:後述の「対象外の領域(除外リスト)」に該当する箇所はリファクタ対象に選ばない. 7. **疑わしきは停止**:判断に迷う・安全網が確認できない・テストコマンドが特定できない場合は,無理に進めず停止して状況を報告する. +8. **ドキュメントは「追記は自動・矛盾は報告のみ」**:実装を真としてよいのは**ドキュメントに記載が無い事項の追記**だけ.ドキュメントと実装が**食い違う**箇所は**自動で書き換えず**,要確認リストに記録して報告する(矛盾は実装バグの兆候かもしれず,無人で塗り潰すと検出機会を失うため).`docs/01_GUIDE/`(規約),`CLAUDE.md`,`docs/03_PLAN/`・`docs/PROGRESS.md`(計画・進捗)は実装を真とする対象に**含めない**. -## 対象外の領域(除外リスト) — これらは選ばない +## 対象外の領域(除外リスト) — コードリファクタの対象に選ばない -以下は無人で触ると事故りやすく,かつリファクタの価値が薄いため,**対象に選ばない**.ステップ A の対象選定時に必ず除外する. +以下は無人で触ると事故りやすく,かつリファクタの価値が薄いため,**コードリファクタの対象に選ばない**.ステップ 0 の選定時に必ず除外する. - 自動生成コード(コードジェネレータ出力,`*.g.dart`,`*.pb.go`,スナップショット等) - 依存・サードパーティ(`node_modules/`,`vendor/`,`.dart_tool/`,`target/`,ベンダリングされた外部ソース) @@ -38,7 +44,9 @@ - マイグレーション・スキーマ履歴(適用済みの DB マイグレーション等,後から書き換えてはいけないもの) - 設定・秘匿情報(`.env*`,CI 設定,各種 config ファイル) - ビルド成果物・キャッシュ(`dist/`,`build/`,`.next/`,`coverage/` 等) -- ドキュメント・本テンプレートの規約ファイル(`docs/`,`CLAUDE.md`,`.claude/` 配下) +- ドキュメント全般(`docs/`,`CLAUDE.md`,`.claude/` 配下) + +※ ドキュメントはコードリファクタの対象にはしないが,**ドキュメント同期系の処理(D)**では `docs/02_ENV/`・`docs/04_SPEC/`・`docs/05_TECH/` を更新対象とする(不変条件 8 の範囲で).`docs/01_GUIDE/`・`CLAUDE.md`・`.claude/`・進捗系は同期処理でも自動編集しない. 判断に迷うファイルは「触らない」側に倒す(不変条件 7). @@ -54,89 +62,122 @@ - 利用可能なら **ビルド/型チェック/リンタのコマンド**(例: `tsc --noEmit`,`cargo build`,`go build ./...`,`flutter analyze`,`npm run lint` 等).これらは「テスト緑」だけでは拾えないコンパイル破壊やリンタ違反を検出する追加の安全網になる. - 以降,**「検証スイート」= テスト+(あれば)ビルド/型チェック/リンタ** をまとめて指す.緑の判定はこの検証スイート全体で行う. - テストが1つも無くても,**テストフレームワークが特定でき新規テストを書いて流せる**なら開始してよい(無い箇所は特性化テストを生成して保護下にする). - - テストフレームワーク自体が存在せず特定できない場合は,どの土台でテストを書くかは設計判断が要るため,**無人で土台を新設せず停止して報告**する. + - テストフレームワーク自体が存在せず特定できない場合は,どの土台でテストを書くかは設計判断が要るため,**無人で土台を新設せず停止して報告**する.ただしこの場合でも**ドキュメント同期系(D)は実行してよい**(テスト不要のため). 4. **ベースラインの確認**:既存テストがある場合は検証スイートを実行し,**開始時点で全て緑**であることを確認する.赤がある場合は,リファクタの前提(緑からの出発)が崩れているため**停止して報告**する.既存テストが0件の場合はテスト実行を省略してよいが,ビルド/型チェックがあれば実行して緑を確認する. -5. **スキップ台帳の読み込み**:`.claude/auto-refactor-skip.md` が存在すれば読み込む.ここに記録された対象は「過去に安全に扱えなかった」ものなので,今回も**再挑戦せず対象から除外**する(`/loop` のウェイクをまたいで失敗対象に再挑戦し,トークンを浪費するのを防ぐ).ファイルが無ければ空として扱う. - - 形式は1行1エントリ: `- <対象(ファイル/関数)> | <理由> | <日付>`. - - このファイルはローカルな運用状態であり成果物ではないため,`.gitignore` 対象とする(追跡されていなければ `.gitignore` に追記する). +5. **台帳の読み込み**:以下のローカル台帳が存在すれば読み込む(無ければ空として扱う).いずれも**ローカルな運用状態であり成果物ではないため `.gitignore` 対象**とする(追跡されていなければ `.gitignore` に追記する). + - `.claude/auto-refactor-skip.md`(スキップ台帳):過去に安全に扱えなかったリファクタ対象.今回も**再挑戦せず除外**する.形式は1行1エントリ `- <対象> | <理由> | <日付>`. + - `.claude/auto-refactor-doc-review.md`(ドキュメント要確認リスト):過去に検出した「ドキュメントと実装の矛盾」.**既出の矛盾は再記録しない**(重複・トークン浪費防止).形式は1行1エントリ `- <箇所> | <ドキュメントの記述> | <実装の挙動> | <推定原因> | <日付>`. -## ループ本体 (Loop Body) — 安全な対象が尽きるまで繰り返す +## ループ本体 (Loop Body) — 安全な作業が尽きるまで繰り返す -各イテレーションで以下を1サイクル実行する. +各イテレーションで「作業項目を1つ」選び,種別に応じた処理を1サイクル実行する. -### ステップ A: 対象を1つ選ぶ +### ステップ 0: 作業項目を1つ選ぶ -- セットアップで確定した範囲の中から,リファクタリング対象を**1つ**選ぶ. -- 選定時に除外するもの:「対象外の領域(除外リスト)」に該当する箇所,および**スキップ台帳に記録済みの対象**は選ばない. -- 優先順位の目安(高い順):重複コードの集約 → 過度に長い関数の分割 → 命名の改善 → デッドコード除去 → 構造の単純化. +セットアップで確定した範囲の中から,次のいずれかの作業項目を**1つ**選ぶ. + +- **リファクタ対象(コード)**:除外リスト・スキップ台帳に該当しないもの.優先度の目安(高い順):重複コードの集約 → 過度に長い関数の分割 → 命名の改善 → デッドコード除去 → 構造の単純化. → 選んだら「リファクタ処理 (R)」へ. +- **ドキュメント・ドリフト項目**:`docs/02_ENV/`・`docs/04_SPEC/`・`docs/05_TECH/` と実装を突き合わせ,**記載漏れ**または**矛盾**がある箇所.要確認リストに既出の矛盾は除外する. → 選んだら「ドキュメント同期処理 (D)」へ. + +両種別とも作業項目が無くなったら**ループを終了**し,完了報告へ進む. + +--- + +### リファクタ処理 (R) + +#### ステップ R1: 保護状態の確認 + - 「その箇所を変更したときに失敗するテストが存在するか」を確認する. - - **保護下にある** → ステップ B へ. - - **テストが無い** → ステップ A2(特性化テストの生成)へ. -- リファクタ対象が無くなったら**ループを終了**し,完了報告へ進む. + - **保護下にある** → ステップ R3 へ. + - **テストが無い** → ステップ R2(特性化テストの生成)へ. -### ステップ A2: 特性化テストの生成(テストが無い対象のみ/tester エージェントに委譲) +#### ステップ R2: 特性化テストの生成(テストが無い対象のみ/tester エージェントに委譲) テストが無い対象は,まず安全網を作る.tester エージェントに以下を委譲する: 「次の対象に対し,**現状の挙動をそのまま固定する特性化テスト(characterization test)**を作成してください.理想の仕様ではなく,**今のコードが実際に返す挙動**を観測してアサーションに落とすこと(バグも含めて現状を固定する).境界値・主要な分岐・代表的な入出力を網羅してください.作成後にテストを実行し,**現状コードで全て緑**になることを確認してください.緑にできない(=挙動が固定できない)場合は,その旨を報告してください. -対象: {ステップ A で選んだ対象} +対象: {ステップ 0 で選んだ対象} テストコマンド: {セットアップで特定したコマンド}」 - tester の報告と実テスト結果を確認する. - - **生成テストが現状コードで全て緑** → これを安全網として `git add` し,タグ **`[add]`** でコミットする(例: `[add] 〇〇モジュールに特性化テストを追加`).**この時点ではまだリファクタしない**.コミット後,この対象を「保護下になった」状態でステップ B へ進む(同一イテレーション内で続けてよい). - - **緑にできなかった/挙動が固定できない** → この対象は安全に触れないため変更を破棄し,**スキップ台帳(`.claude/auto-refactor-skip.md`)に「対象・理由・日付」を追記**してからステップ A へ戻る(以後のイテレーション・ウェイクで再選択しない). + - **生成テストが現状コードで全て緑** → これを安全網として `git add` し,タグ **`[add]`** でコミットする(例: `[add] 〇〇モジュールに特性化テストを追加`).**この時点ではまだリファクタしない**.コミット後,この対象を「保護下になった」状態でステップ R3 へ進む(同一イテレーション内で続けてよい). + - **緑にできなかった/挙動が固定できない** → この対象は安全に触れないため変更を破棄し,**スキップ台帳(`.claude/auto-refactor-skip.md`)に「対象・理由・日付」を追記**してからステップ 0 へ戻る(以後のイテレーション・ウェイクで再選択しない). -### ステップ B: リファクタ前の緑確認 +#### ステップ R3: リファクタ前の緑確認 - 検証スイート(テスト+あればビルド/型チェック/リンタ)を実行し,緑であることを確認する(ベースライン/生成した特性化テストの再確認). -### ステップ C: リファクタリング実行(refactorer エージェントに委譲) +#### ステップ R4: リファクタリング実行(refactorer エージェントに委譲) refactorer エージェントに以下を委譲する: 「次の対象を,挙動を変えずにリファクタリングしてください.テストを安全網とし,リファクタ後に検証スイートを再実行して**全て緑のまま**であることを必ず確認してください.緑にできない場合は変更を破棄し,その旨を報告してください. -対象: {ステップ A で選んだ対象} +対象: {ステップ 0 で選んだ対象} 検証コマンド: {セットアップで特定したテスト+ビルド/型チェック/リンタのコマンド}」 -### ステップ D: リファクタ後の緑確認 +#### ステップ R5: リファクタ後の緑確認 - refactorer の報告と実際の検証スイート(テスト+あればビルド/型チェック/リンタ)の結果を確認する. -- **全て緑** → ステップ E へ. -- **赤がある/緑にできなかった** → その変更を破棄(`git checkout -- .` または `git stash`)し,**スキップ台帳(`.claude/auto-refactor-skip.md`)に「対象・理由・日付」を追記**して**次のイテレーションのステップ A へ**(同じ対象は再選択しない). +- **全て緑** → ステップ R6 へ. +- **赤がある/緑にできなかった** → その変更を破棄(`git checkout -- .` または `git stash`)し,**スキップ台帳に「対象・理由・日付」を追記**してステップ 0 へ戻る(同じ対象は再選択しない). -### ステップ E: 専用ブランチへコミット +#### ステップ R6: 専用ブランチへコミット - `git add` で当該変更をステージングする(`.env`・クレデンシャル・ビルド成果物は含めない). - GUIDE_04 のコミット書式に従い,タグ **`[clean]`** でコミットする(例: `[clean] 重複した入力バリデーションを共通関数に集約`). -- **push・PR はしない.** `main` へのマージもしない. +- **push・PR はしない.** ステップ 0 へ戻る. -### ステップ F: 次へ +--- -- ステップ A に戻り,次の対象を選ぶ. +### ドキュメント同期処理 (D) + +#### ステップ D1: 実装とドキュメントの突き合わせ + +- 選んだ項目について,**実装(コード)を読み,対応する `docs/02_ENV/`・`docs/04_SPEC/`・`docs/05_TECH/` の記述**を確認する. +- 食い違いの種別を判定する: + - **追記型**:ドキュメントに記載が無いが実装にある(例:新しい環境変数・依存,新規モジュール/API,コードで確定した技術選定や制約) → ステップ D2 へ. + - **矛盾型**:ドキュメントの記述と実装の挙動が**食い違う**(例:仕様では戻り値 A だがコードは B を返す) → ステップ D3 へ. + +#### ステップ D2: 追記(自動/実装を真とする) + +- 実装を真として,該当ドキュメント(`02_ENV`/`04_SPEC`/`05_TECH` の適切な場所)に**事実を追記・補足**する.GUIDE_02 のドキュメント作成規約と GUIDE_03 の命名規則に従う. +- **既存の意図的な記述は消さない**.追記・補完にとどめ,全面書き換えはしない. +- コミット(GUIDE_04 準拠): + - 新規セクション/新規ドキュメントファイルの追加 → タグ **`[add]`**(例: `[add] 04_SPEC に〇〇APIの仕様を追記`). + - 既存記述への事実追記・補足 → タグ **`[update]`**(例: `[update] 02_ENV に新規環境変数 FOO を追記`). +- コミット後,ステップ 0 へ戻る. + +#### ステップ D3: 矛盾は報告のみ(自動で書き換えない) + +- **ドキュメントは書き換えない**(不変条件 8).矛盾は実装バグの兆候かもしれず,無人で「実装に合わせて」塗り潰すと検出機会を失う. +- `.claude/auto-refactor-doc-review.md`(要確認リスト)に**1行追記**する: `- <箇所> | <ドキュメントの記述> | <実装の挙動> | <推定原因(仕様が古い/実装バグの疑い 等)> | <日付>`. +- **既に記録済みの矛盾は再記録しない**.記録(または既出確認)したらステップ 0 へ戻る. + +--- ## 停止条件 (Stop Conditions) 以下のいずれかでループを止める. -- リファクタ対象(テスト生成で保護下にできるものを含む)が尽きた → **正常終了**. +- **リファクタ対象(テスト生成で保護下にできるものを含む)とドキュメント・ドリフト項目が,両方とも尽きた** → **正常終了**. - 同じ箇所で繰り返しテストが赤になる/テストコマンドが途中で失敗するようになった → **異常として停止し報告**. - 不変条件を満たせない状況になった → **停止して報告**. - ユーザーが割り込んで中断した → その時点までの成果(コミット済み)は `refactor/` ブランチに残る. ## /loop との併用(推奨される使い方) -このコマンドは単体で「対象が尽きるまで」連続実行するが,ユーザーが `/loop` でラップして起動すると,放置中の空き枠を使って自律的に再トリガーし続けられる(本コマンドの本来の目的). +このコマンドは単体で「作業が尽きるまで」連続実行するが,ユーザーが `/loop` でラップして起動すると,放置中の空き枠を使って自律的に再トリガーし続けられる(本コマンドの本来の目的). `/loop` で回す場合も上記の不変条件・停止条件は同じく厳守すること.長い待機を挟む場合はキャッシュとコストを意識した間隔を選ぶ. ### 収束条件(loop-until-dry)— 空回りでトークンを浪費しない -`/loop` で回すと,対象が尽きた後もウェイクのたびに「対象なし → 即終了」を繰り返し,**無駄にトークンを消費**しうる.これを防ぐため,以下の収束ルールを守る. +`/loop` で回すと,作業が尽きた後もウェイクのたびに「対象なし → 即終了」を繰り返し,**無駄にトークンを消費**しうる.これを防ぐため,以下の収束ルールを守る. -- 各イテレーションの開始時に全範囲を再スキャンし,**この回で実施した作業(リファクタ+特性化テスト生成)の件数**を数える. +- 各イテレーションの開始時に全範囲を再スキャンし,**この回で実施した作業の件数**を数える(リファクタ+特性化テスト生成+ドキュメント追記+**新規に記録した**矛盾.既出の矛盾の再確認は作業に数えない). - **作業件数が 0 だった回**を「空振り」とカウントする. -- **空振りが 2 回連続**したら,もう安全に拾える対象は出尽くしたとみなし,**`/loop` 自体を終了する**(次のウェイクをスケジュールしない). +- **空振りが 2 回連続**したら,もう安全に拾える作業は出尽くしたとみなし,**`/loop` 自体を終了する**(次のウェイクをスケジュールしない). - 1 回の空振りで即終了しないのは,「順序やコミットの巡り合わせで一時的に拾えなかっただけ」のケースを 1 回分許容するため. - 1 件でも作業した回が出たら,空振りカウントは 0 にリセットする. - 終了時は「空振りが続いたため収束した」旨を完了報告に明記する. @@ -146,8 +187,10 @@ ループ終了時,ユーザーに以下を報告する. - 作業ブランチ名 -- 追加した特性化テストの件数(= `[add]` コミット数)と対象モジュールの一覧 +- 追加した特性化テストの件数(= `[add]` のテストコミット数)と対象モジュールの一覧 - 実施したリファクタリングの件数(= `[clean]` コミット数)と概要の一覧 +- 更新したドキュメントの件数と内容(追記した `02_ENV`/`04_SPEC`/`05_TECH` の箇所一覧) +- **⚠ ドキュメントと実装の矛盾**:要確認リスト `.claude/auto-refactor-doc-review.md` に記録した件数と概要.**実装バグの可能性があるため自動では直していない**ので,1件ずつ「仕様を直す/実装を直す」を人間が判断してほしい旨を明記する - スキップした対象とその理由(挙動が固定できずテスト生成に失敗/検証スイートが緑にできなかった 等).詳細はスキップ台帳 `.claude/auto-refactor-skip.md` に追記済み - ⚠ 自動生成した特性化テストは**現状の挙動(バグを含む)を固定**したもの.後で内容を一度目視確認することを推奨する旨を添える - 次のアクションの案内:「内容を確認の上,問題なければ `/commit push`(または `merge`)で `main` に取り込めます」