Skip to content

Refactor: 収束ループの状態管理を段ごとに分ける(cross-refactoring / cross-review) - #136

Merged
takemi-ohama merged 90 commits into
mainfrom
refactor/cross-refactoring-6th-trial
Aug 22, 2026
Merged

Refactor: 収束ループの状態管理を段ごとに分ける(cross-refactoring / cross-review)#136
takemi-ohama merged 90 commits into
mainfrom
refactor/cross-refactoring-6th-trial

Conversation

@takemi-ohama

@takemi-ohamatakemi-ohama commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

何のために

収束ループの状態管理は、1 つの関数に多段の処理が直列で同居している。取り込みの
可否を決める関数は 100〜170 行あり、途中の 1 段だけを読んで正しさを確かめられない。
段ごとに名前を付けて分け、振る舞いを変えずに読める単位にする。

何を変えたか

改善は 12 件で、対象は収束ループの状態管理(cross-refactoring/scripts/refactor.py)と
集計(cross-review/scripts/lib/metrics.py)である。

適用結果の取り込み

対象変更内容
cmd_merge_apply「取り込み済みの判定」「着手前テストの確認」「範囲の確定」「申告の整合性の検証」「項目ごとの検証」「公開」の 6 段を、段ごとの関数へ分けた
_validate_apply_commit_ownership申告されたコミットの所有者の特定、重複と未割当の検出、失敗時の切り戻しを分けた

修正結果の取り込み

対象変更内容
cmd_merge_fix叩き直しの判定、解決スレッドの照合、範囲の検証、状態の反映を段ごとに分けた(2 段階で実施)
verify_fix_commit適用側のコミット検証と同じ 4 手順を重複して持っていたため、共通の検証へ寄せた

修正コミットと適用コミットは同じ基準で見る決まりだが、手順が 2 か所に書かれていると
片方だけが緩む余地が残る。1 か所にまとめた。

レビューと提案の判定

対象変更内容
cmd_judge_review結果の集計と、判定から終了コードを決める分岐を分けた
judge結果の存在確認、判定語彙、投稿の可否、指摘の構造という 4 種の検証を分けた
cmd_merge_proposals各ランタイムの結果ファイルの読み込みと、統合結果から状態を更新する処理を分けた

初期化・取り消し・同期・集計

対象変更内容
cmd_initPull Request のメタデータを取る 3 回の呼び出しを 1 つの関数へまとめた
_drop_items取り消し対象の抽出、積み直しの計画、確認用の出力、実行を段ごとに分けた
_sync_generated同期コマンドの実行と、生成された差分のコミットを分けた
aggregate(集計)実装担当とレビュー担当という別々の集計軸が同じループで更新されていたため、軸ごとに分けた

変えていないこと

公開しているコマンド、終了コード、状態ファイルの構造は変わらない。

対象範囲のテストは着手前 500 件から 502 件になった。増えた 2 件は、取り消しの
振る舞いを固定するために追加したものである。

$ uv run --with pytest python -m pytest \
plugins/ndf-shared/skills/cross-refactoring/tests \
plugins/ndf-shared/skills/cross-review/tests -q
502 passed in 26.17s

配布物(ndf-claude / ndf-codex / ndf-kiro)は scripts/build-runtime-plugins.sh
で生成したもので、編集元と同じ内容である。

どう作られたか

/ndf:cross-refactoring を 3 ラウンド回した。提案は codex / gemini / kiro が並列で行い、
適用は輪番で 1 者、残る 2 者がレビューする。各コミットは 1 手 1 コミットで、コミット
ごとにテストの実行・差分予算・対象範囲の遵守を機械的に検証している。

採用した 14 件のうち 2 件は、実差分が見積を大きく超えたため項目単位で取り消した。
残る 12 件はレビュー担当 2 者の承認を得ている。収束後に Pull Request 全体を
/ndf:cross-review にかけ、codex と gemini の双方が承認した(指摘 0 件)。

試行そのものの記録は #137 にある。

Test plan

  • 対象範囲のテストが 502 passed
  • 各ラウンドの適用コミットで同じテストが通ること(進行側が実行済み)
  • /ndf:cross-review による Pull Request 全体のレビューが承認で収束すること

🤖 Generated with Claude Code

https://claude.ai/code/session_01XpZXeYvfEGymigQeCLp1Eh

takemi-ohamaand others added 30 commits August 22, 2026 15:05
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpZXeYvfEGymigQeCLp1Eh
codex sentinel 完了判定を _check_codex_sentinel_done に抽出し、monitor_agent のループ本体は完了ステータスの返却だけに寄せた。
Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
result.json の経過時間 fallback 判定を _check_stale_result_done に抽出し、完了判定の順序を維持した。
Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
cmdline の stale pidfile 判定を _check_cmdline_stale に抽出し、検証済みフラグを戻り値で更新する形にした。
Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
hard timeout 判定を _check_hard_timeout に抽出し、監視ループ内の終了条件を単純化した。
Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
early error の FATAL/WARN 判定を _check_early_error に抽出し、WARN 済み状態を戻り値で保持した。
Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
プロセス終了後の OK/NO_RESULT 判定を _check_process_exited に抽出し、result.json 確認を独立させた。
Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
stall 検知を _check_stall に抽出し、進捗サイズと最終進捗時刻を戻り値で更新する形にした。
Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
…ge_apply
適用結果・baseline・git 範囲を読む段を _load_apply_context に切り出し、cmd_merge_apply の前半を段階化した。
Item-Id: R1-002
Round: 1
Impl-Runtime: codex
Impl-Model: default
…ge_apply
payload の申告項目を _collect_apply_reports に切り出し、ラウンド内申告と未知 ID の収集を独立させた。
Item-Id: R1-002
Round: 1
Impl-Runtime: codex
Impl-Model: default
…ge_apply
コミット所有権の検証とラウンド取り消しを _validate_apply_commit_ownership に切り出した。
Item-Id: R1-002
Round: 1
Impl-Runtime: codex
Impl-Model: default
…ge_apply
項目ごとの commit facts 収集と適用結果検証を _verify_apply_items に切り出し、progress 保存を段として分離した。
Item-Id: R1-002
Round: 1
Impl-Runtime: codex
Impl-Model: default
…view
レビュー判定の集計、記録作成、担当別所要時間の更新を _aggregate_review_results に抽出した。
Item-Id: R1-003
Round: 1
Impl-Runtime: codex
Impl-Model: default
…view
レビュー判定後の invalid/approved/request changes 分岐を _handle_review_verdict に抽出した。
Item-Id: R1-003
Round: 1
Impl-Runtime: codex
Impl-Model: default
実装担当のラウンド集計を _aggregate_impl_round に切り出し、aggregate の走査処理から分離した。
Item-Id: R1-004
Round: 1
Impl-Runtime: codex
Impl-Model: default
レビュー担当ごとの指標更新を _aggregate_reviewer_round に切り出し、担当別集計を独立させた。
Item-Id: R1-004
Round: 1
Impl-Runtime: codex
Impl-Model: default
モデル不一致と auto モデルの unmeasured 追記を _append_model_measurement_warnings に集約した。
Item-Id: R1-004
Round: 1
Impl-Runtime: codex
Impl-Model: default
…g/scripts/refactor.py#cmd_merge_fix
解決済み thread を指摘へ反映する二重ループを _mark_resolved_fix_findings
へ抽出した。cmd_merge_fix は読み込み → 検証 → 記録 → push の流れだけに
なる。振る舞いは変えていない。
Item-Id: R3-004
Round: 3
Impl-Runtime: claude
Impl-Model: default
…efactoring/scripts/refactor.py#verify_fix_commit
verify_fix_commit と verify_apply_item のループが同じ順序で書いていた
exists 確認・トレーラー・範囲・test_status の 4 手順を
_verify_commit_basics へ寄せた。適用と修正で基準が食い違わなくなる。
実体が無いときの理由文は範囲の呼び方が違うため引数で受け取り、
出力は両者とも従来のままにしている。振る舞いは変えていない。
Item-Id: R3-005
Round: 3
Impl-Runtime: claude
Impl-Model: default
…/cross-refactoring/scripts/refactor.py#verify_fix_commit"
This reverts commit bb721ad.
…factoring/scripts/refactor.py#cmd_merge_fix"
This reverts commit 887471c.
…factoring/scripts/refactor.py#cmd_merge_fix"
This reverts commit 8864dc3.
…factoring/scripts/refactor.py#cmd_merge_fix"
This reverts commit af392b3.
…ss-refactoring/scripts/refactor.py#_handle_invalid_review_verdict"
This reverts commit 759a135.
…ss-refactoring/scripts/refactor.py#_handle_invalid_review_verdict"
This reverts commit 369bffa.
…ss-refactoring/scripts/refactor.py#_handle_review_verdict"
This reverts commit 299043c.
…ss-refactoring/scripts/refactor.py#_sync_generated"
This reverts commit beed674.
…ss-refactoring/scripts/refactor.py#_sync_generated"
This reverts commit 6eac882.
…factoring/scripts/refactor.py#cmd_init"
This reverts commit 107be5e.
…g/scripts/refactor.py#cmd_init
cmd_init に直書きしていた GitHub からの Pull Request メタデータ取得
(viewer / author / headRefName / baseRefName の 4 回の gh 呼び出しと
is_own_pr の判定)を _fetch_pr_context として抽出した。cmd_init は
戻り値を受け取るだけになり、他の段階(_ensure_work_worktree など)と
同じ粒度で段階の切れ目が読めるようになる。振る舞いは変えていない。
Item-Id: R3-001
Round: 3
Impl-Runtime: claude
Impl-Model: default
…toring/scripts/refactor.py#_sync_generated
同期コマンドの実行と失敗時の破棄・中断を _run_sync_command として
切り出した。_sync_generated 側は 1 行の呼び出しになり、パイプラインの
段が名前で読めるようになる。振る舞いは変えていない。
Item-Id: R3-002
Round: 3
Impl-Runtime: claude
Impl-Model: default
…toring/scripts/refactor.py#_sync_generated
生成差分の git add / commit と失敗時の破棄を _commit_sync_changes として
切り出した。_sync_generated は command 判定 → 清浄性確認 → 実行 →
差分検出 → コミット の呼び出し列だけになる。振る舞いは変えていない。
Item-Id: R3-002
Round: 3
Impl-Runtime: claude
Impl-Model: default
…g/scripts/refactor.py#cmd_merge_fix
検証を通らない修正ラウンドの取り消しを _revert_invalid_fix_round へ
抽出した。pending_push の印・取り消し・起点の更新・解決の申告を
採らない判断が 1 か所にまとまる。振る舞いは変えていない。
Item-Id: R3-004
Round: 3
Impl-Runtime: claude
Impl-Model: default
…g/scripts/refactor.py#cmd_merge_fix
検証を通った修正コミットを改善項目へ紐づけるループを
_record_accepted_fix_commits へ抽出した。振る舞いは変えていない。
Item-Id: R3-004
Round: 3
Impl-Runtime: claude
Impl-Model: default
…g/scripts/refactor.py#cmd_merge_fix
解決済み thread を指摘へ反映する二重ループを _mark_resolved_fix_findings
へ抽出した。cmd_merge_fix は読み込み → 検証 → 記録 → push の流れだけに
なる。振る舞いは変えていない。
Item-Id: R3-004
Round: 3
Impl-Runtime: claude
Impl-Model: default
…efactoring/scripts/refactor.py#verify_fix_commit
verify_fix_commit と verify_apply_item のループが同じ順序で書いていた
exists 確認・トレーラー・範囲・test_status の 4 手順を
_verify_commit_basics へ寄せた。適用と修正で基準が食い違わなくなる。
実体が無いときの理由文は範囲の呼び方が違うため引数で受け取り、
出力は両者とも従来のままにしている。振る舞いは変えていない。
Item-Id: R3-005
Round: 3
Impl-Runtime: claude
Impl-Model: default
実装担当は対象範囲だけを変更するため、生成物が同期されない。
同期を検査する pre-push を持つリポジトリでも push できるよう、
公開の直前に進行側がまとめて生成する。

@takemi-ohamatakemi-ohama left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-refactoring | round 3 | Reviewer: codex / default | APPROVE

判定: APPROVE

対象コミット(R3-001 / R3-002 / R3-004 / R3-005)を確認しました。抽出・処理連鎖への分解・重複の共通化はいずれも宣言されたスメルと手法の範囲内で、公開インタフェース、例外、状態保存、push 前同期、修正ラウンド取り消しの副作用順序に差し戻しが必要な変更は見つかりませんでした。R3-003 は abandoned / reverted として今回の適用差分に残っていないことを確認しています。

検証:

  • uv run --with pytest python -m pytest plugins/ndf-shared/skills/cross-refactoring/tests plugins/ndf-shared/skills/cross-review/tests -q
  • 結果: 502 passed in 26.29s

@takemi-ohamatakemi-ohama left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-refactoring | round 3 | Reviewer: kiro / claude-sonnet-5 | APPROVE

対象コミット(R3-001, R3-002 ×2, R3-004 ×3, R3-005)を確認しました。すべて extract_method / split_into_pipeline / consolidate_duplication の単純な抽出・集約で、公開インタフェースの入出力・例外種別・副作用の順序は変わっていません。

  • R3-001: _fetch_pr_context への抽出は cmd_init の呼び出し順を変えず、戻り値の型もそのまま。
  • R3-002: _run_sync_command / _commit_sync_changes への分割後も _sync_generated の判定順(command → clean → run → produced → commit)は同一。
  • R3-004: _revert_invalid_fix_round / _record_accepted_fix_commits / _mark_resolved_fix_findings の 3 段抽出は元の分岐構造をそのまま移しており、state の保存順序(pending_push → 取り消し → fix_base_sha 保存)も保持されています。
  • R3-005: _verify_commit_basics への集約は、verify_fix_commitverify_apply_item それぞれの「実体が無いときの理由文」を呼び出し側の引数として残しており、両者の出力差を保ったまま重複を解消しています。

差分予算(見積 × 抽出系倍率 3)に対しても全項目が範囲内です(R3-001: 37/120、R3-002: 76/180、R3-004: 91/255、R3-005: 52/75)。R3-003 は放棄・取り消しが確認でき、コード上に残骸はありません。

uv run --with pytest python -m pytest plugins/ndf-shared/skills/cross-refactoring/tests plugins/ndf-shared/skills/cross-review/tests -q を実行し、502 passed(exit=0)を確認しました。

@takemi-ohamatakemi-ohama left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 1 | codex | APPROVE

差し戻しが必要な指摘はありません。対象テストは uv run --with pytest python -m pytest plugins/ndf-shared/skills/cross-refactoring/tests plugins/ndf-shared/skills/cross-review/tests -q で 502 passed です。

@takemi-ohamatakemi-ohama left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 1 | gemini | APPROVE

全 3 ラウンドでの 12 件の構造改善を確認しました。抽出されたヘルパー関数は副作用の順序やバリデーションの責務を正確に維持しており、verify_apply_itemverify_fix_commit の共通化 (_verify_commit_basics) もそれぞれの固有要件を損なわずに実装されています。現状固定テストも変更意図通りに維持されており、ラウンドを跨いだ整合性に問題は見られませんでした。

@takemi-ohama
takemi-ohama marked this pull request as ready for review August 22, 2026 16:47
@takemi-ohamatakemi-ohama changed the title Refactor: cross-refactoring 6 回目の実機試行(v8.5.2〜v8.5.4 の修正確認)Refactor: 収束ループの状態管理を段ごとに分ける(cross-refactoring / cross-review)Aug 22, 2026
@takemi-ohama
takemi-ohama merged commit 1db43c0 into mainAug 22, 2026
7 checks passed
@takemi-ohama
takemi-ohama deleted the refactor/cross-refactoring-6th-trial branch August 22, 2026 19:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@takemi-ohama