Skip to content

Fix: cross-refactoring の実機検証で見つかった不具合 9 件を修正(v8.2.0) - #119

Merged
takemi-ohama merged 6 commits into
mainfrom
fix/issue-113-cross-refactoring-defects
Aug 16, 2026
Merged

Fix: cross-refactoring の実機検証で見つかった不具合 9 件を修正(v8.2.0)#119
takemi-ohama merged 6 commits into
mainfrom
fix/issue-113-cross-refactoring-defects

Conversation

@takemi-ohama

@takemi-ohamatakemi-ohama commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

概要

/ndf:cross-refactoring の実機検証(PR #118)で見つかった不具合 9 件をすべて修正する。
提案フェーズは設計どおり動いていたが、適用結果の検証で失敗した項目を取り消す経路が破綻し、
進行を続行できない状態だった。うち 6 件が収束ループの続行を妨げていた。

NDF を v8.2.0 へ更新する。cross-review と収束ループの共通層(cross-review/scripts/lib/)は変更していない。

直したこと

#不具合変更
1取り消しが他項目のコミットと競合する範囲を新しい順に全て戻し、残す項目を古い順に積み直す
2取り消し失敗を握り潰して進行する中断を終了コード 4 で表し、「全件失敗」(2)と区別する
3適用結果が状態ファイルへ残らない項目ごとの判定をその都度保存する(rounds[].apply_progress
4検証未通過の変更が公開されたまま残る取り消しへ着手するpending_push を立てる
5範囲外の変更を検証しない--scope を適用・修正の検証にも効かせる
6提案の記録が次ラウンドで上書きされる提案の結果ファイル名にもラウンド番号を入れる
7gemini が配置した手順書を読めない読み取り除外を無効にする設定を作業ディレクトリへ置く
8語彙の許容値をプロンプトが列挙しない検証側が持つ語彙集合をプロンプトへ機械的に列挙する
9初期化が CLI の認証を確認しないinit が参加 CLI の認証状態を確認し、未認証なら中断する

設計判断

取り消しの単位 — 項目単位を保つ(ただし限界がある)

範囲全体を新しい順に戻すのは履歴の逆再生なので競合しない。競合するのは
「一部のコミットだけを飛ばして戻す」ときである。そこで次の順で行う。

flowchart LR
A["範囲 base..HEAD を<br/>新しい順に全て revert"] --> B["残す項目のコミットを<br/>古い順に cherry-pick"]
B -->|成功| C["項目単位の取り消し"]:::ok
B -->|競合| D["着手前 HEAD へ reset<br/>範囲を全て revert"] --> E["ラウンド全件を取り消し"]:::stop
classDef ok fill:#dfd,stroke:#383
classDef stop fill:#fdd,stroke:#933
Loading

実機の git で確かめたところ、同一ファイルの隣接行を触る項目どうしは積み直しでも競合した。
取り消した側の行が消えると、残す側のパッチが前提にしている文脈も消えるためで、git だけでは
決められない。実測(PR #118)では採用 5 件のうち 4 件がその位置関係だったので、
この構成では退避が普通に起こると見込んでおく必要がある。

位置関係結果
別ファイル項目単位
同一ファイルの離れた行項目単位
同一ファイルの隣接行ラウンド全件へ退避

それでもこの案を採る理由は、修正前が進行そのものが止まるのに対し、最悪でも決定的な状態へ
落ちて進行を続けられるためである。退避したことは rounds[].drops[].mode に残る。

配布物同期の責務 — 進行側へ分離

範囲外が変更された原因は「編集元から配布物を生成する」規約に実装担当が従ったことであり、
規約と範囲の指定が衝突していた。責務を分けて解消する。

誰が何を
実装担当--scope の中だけを変更する。生成物の同期はしない
進行側(ホスト)収束後にまとめて生成物を同期する

互換性

対象変更扱い
提案の結果ファイル名<ランタイム>-propose-rf<ID>-r<ラウンド>-result.json破る。進行スクリプトと --stem-template を同時に変更済み
--scope の意味検証にも効く破る。現状固定テストの置き場所も含める必要がある
終了コード中断 = 4 を追加追加のみ。0 / 1 / 2 / 3 の意味は変えない
状態ファイルvocabulary / auth / apply_progress / drops を追加追加のみ。欠けていても読める

--scope にテストの置き場所を含めないと、test_gap が真の項目で「テストを先に足せ」と
「範囲外を触るな」が両立せず必ず失敗する。README・SKILL.md・手順書に明記した。

テストプラン

# 全体テスト
uv run --with pytest python -m pytest \
plugins/ndf-shared/skills/cross-refactoring/tests \
plugins/ndf-shared/skills/cross-review/tests -q
# 静的検査
python3 scripts/check-skill-frontmatter.py
python3 scripts/check-markdown-links.py
bash scripts/validate-runtime-plugins.sh

検証結果

段階コマンド対象範囲実行時刻結果
限定的な検証pytest .../cross-refactoring/tests -qcross-refactoring のみ2026-08-16 05:12292 passed / exit=0
全体テストpytest .../cross-refactoring/tests .../cross-review/tests -q収束ループ 2 Skill2026-08-16 05:13430 passed / exit=0
静的解析python3 scripts/check-skill-frontmatter.pySkill 35 個2026-08-16 05:13エラー 0 / 警告 0 / exit=0
静的解析python3 scripts/check-markdown-links.py全体2026-08-16 05:13valid / exit=0
ビルド・検証bash scripts/validate-runtime-plugins.sh配布物 3 系統 + marketplace2026-08-16 05:13passed / exit=0
結合(CI)GitHub Actions7 チェック(runtime-smoke claude / codex / kiro を含む)2026-08-16 05:20全て pass

着手前は 387 件(23.6 秒)だった。新規テスト 43 件を追加している(うち 9 件は
tests/test_drop_items_git.py実際の git リポジトリを作り、隣接/離れた行/別ファイルの
3 通りで取り消しと積み直しの挙動を確かめる)。

受け入れ条件: 11 項目すべてを満たす(対応は実施計画を参照)。

未検証の項目

  • レビューフェーズ以降の実機動作は依然として未検証である。今回の修正は
    適用フェーズで止まっていた経路を通せるようにするもので、レビュー担当 2 者の並列実行、
    指摘の修正と再レビュー、実装担当の輪番、収束判定、集計値の出力は一度も実行できていない

既存の失敗

  • ruff check --select F,E501refactor.py で 3 件(行長超過)を報告する。
    変更前の版でも同じ 3 件が出るため既存の失敗であり、今回の差分に 100 文字を超える行は無い。
    リポジトリの検証手順に ruff は含まれていない

範囲外と判断したもの

  • 語彙の日本語表記を受理する正規化。報告された修正の方向は「許容値をプロンプトへ機械的に
    列挙する」までであり、受理側を緩めると語彙固定による重複排除が効かなくなる
  • 生成物同期の自動実行。進行側の責務として手順に明記するに留めた

cross-review の結果

/ndf:cross-review 1196 ラウンド回し、codex / gemini の両者が APPROVE で収束した。
未解決のレビュースレッドは 0 件(全 7 件を返信 + Resolve 済み)。

roundcodexgemini直したこと
1REQ (2)APPeval "$(rf ...)"exit 4 が親シェルへ伝わらない / 取り消し失敗後に再実行できない
2REQ (1)APP取り消し完了を push より先に永続化 / 退避時の revert 二重実行
3REQ (1)COMMENT実施計画の状態スキーマ表記が実装と食い違い
4APPREQ (1)--scope ./src が正規化されず全件範囲外になる
5REQ (1)APPabandon-items / merge-fix でも取り消しの再開状態を保存
6APPAPP

ラウンド 1・2・5 の指摘はいずれも今回の修正が持ち込んだ再開時の欠陥であり、
レビューで捕まえられたものである。ラウンド 4 の ./ 正規化は元からの欠陥だった。

次にすること

修正後の再検証を実機で行う。--scope にテストの置き場所を含める点に注意する。

/ndf:cross-refactoring <PR番号> \
--scope plugins/ndf-shared/skills/cross-refactoring/scripts \
plugins/ndf-shared/skills/cross-refactoring/tests \
plugins/ndf-shared/skills/cross-review/scripts/lib \
--baseline-test "uv run --with pytest python -m pytest plugins/ndf-shared/skills/cross-refactoring/tests plugins/ndf-shared/skills/cross-review/tests -q"

🤖 Generated with Claude Code

https://claude.ai/code/session_01GSwBvT9CH8mKfgyFn2JWfS

実機検証(PR #118)で収束ループが適用フェーズから先へ進めなくなった原因を直す。
- 取り消しが他項目のコミットと競合する問題を、範囲の巻き戻しと積み直しで解消
(分離できない位置関係のときはラウンド全件へ退避する)
- 取り消し失敗を中断(終了コード 4)として扱い、「全件失敗」(2)と区別
- 項目ごとの判定を都度保存し、中断しても到達点を状態から読めるようにする
- 取り消しへ着手する前に pending_push を立て、未検証の差分を公開したまま残さない
- --scope を適用・修正の検証にも反映し、生成物の同期を進行側の責務へ分離
- 提案の結果ファイル名にラウンド番号を追加し、次ラウンドでの上書きを防ぐ
- gemini の作業ディレクトリへ読み取り除外を無効にする設定を配置
- 提案プロンプトへ語彙の許容値を機械的に列挙
- init が参加 CLI の認証状態を確認し、未認証なら中断
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GSwBvT9CH8mKfgyFn2JWfS

@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

変更は 9 件の不具合すべてに対する適切な修正と堅牢なテストを含んでおり、既存仕様や競合時の退避などの要件を完全に満たしています。追加の修正提案はありません。

@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 | REQUEST_CHANGES

終了コード 4 の親シェルへの伝播と、取り消し失敗後の再実行状態を修正してください。

Comment threadplugins/ndf-shared/skills/cross-refactoring/SKILL.md
Comment threadplugins/ndf-shared/skills/cross-refactoring/scripts/refactor.py Outdated
- `eval "$(rf ...)"` はコマンド置換のサブシェルで動くため `exit 4` が親へ伝わらない。
出力と終了コードを親シェルで受け取る `rf_eval` を追加し、init / start-round を移す
- 取り消しより先に `merged_at` を立てていたため、取り消しに失敗して中断すると
次の実行が処理済みガードで素通りし、再試行できなかった。`pending_drop` を立てて
から取り消しへ入り、push まで終えてから `merged_at` を立てる
- やり残した取り消しは、処理済みの判定より先に再実行する(push だけ先に流さない)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GSwBvT9CH8mKfgyFn2JWfS

@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 2 | codex | REQUEST_CHANGES

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-review | round 2 | gemini | APPROVE

設計と不具合修正の目的が適切に実装されており、副作用の考慮やエラーハンドリング・冪等性も十分に担保されています。一部、冗長な git 操作があったためインラインで指摘しました。

Comment threadplugins/ndf-shared/skills/cross-refactoring/scripts/refactor.py Outdated
- 取り消しが済んだことを push より先に永続化する。保存せずに push して失敗すると、
次の実行が適用の検証をやり直し、取り消しと積み直しのコミットを「未割当」と
判定してラウンドごと巻き込んでいた
- 積み直しに失敗したときは、着手前ではなく**取り消しが済んだ地点**へ戻す。
着手前まで戻して取り消しをやり直すと、同じ範囲の revert コミットが 2 組できる
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GSwBvT9CH8mKfgyFn2JWfS

@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 3 | codex | REQUEST_CHANGES

状態スキーマの文書表記を実装と統一してください。

Comment threadissues/issue-113-cross-refactoring-defect-fixes.md Outdated
`rounds[].apply.progress` は実装の `rounds[].apply_progress` と食い違っていた。
あわせて退避先(取り消しが済んだ地点)と、`pending_drop` / `merged_at` /
`rf_eval` の記述も実装へ追従させる。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GSwBvT9CH8mKfgyFn2JWfS

@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 4 | codex | APPROVE

修正が必要な新規指摘はありません。

@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 4 | gemini | REQUEST_CHANGES

--scope による範囲外検査のパス正規化に関する修正提案が 1 件あります。

`--scope ./src` はシェル補完で頻出するが、git が出すのは `src/foo.py` なので
そのまま比べると全てのコミットが範囲外になり、適用が必ず失敗していた。
`./` を落としてから突き合わせ、`.` と `./` はリポジトリ全体として扱う。
空の指定は全許可にせず無視する(書き損じで検査が骨抜きにならないように)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GSwBvT9CH8mKfgyFn2JWfS

@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 5 | codex | REQUEST_CHANGES

取り消し処理の中断・再開状態を、適用失敗・見送り・修正失敗の全経路で共通の状態遷移として保存してください。

Comment threadplugins/ndf-shared/skills/cross-refactoring/scripts/refactor.py Outdated

@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 5 | gemini | APPROVE

設計と実装を検証しました。特に取り消しと積み直しのフェーズにおいて、git cherry-pick の失敗による部分的な状態から全件取り消しへ確実に退避できること(_reset_hard と組み合わせた冪等性の担保)、および中断時の pending_drop / pending_push を用いた再開フローが極めて堅牢に実装されている点を確認しました。終了コード 4 (ABORT) と 2 (全件失敗) の分離や、指定範囲外のコミット検査の整合性もテストで網羅されており、懸念点はありません。修正を承認します。

- `_run_drop()` を切り出し、`pending_drop` を立てて取り消しへ入り、戻ったら
すぐ保存する。印は呼び出し側が完了の記録と同じ保存で消す
- `abandon-items` はやり残した取り消しを push の再送より先に片づける。
先に push すると取り消しが途中の HEAD を公開してしまう
- `merge-fix` は取り消し後の起点をその場で保存する。保存前に落ちると、
次の実行が取り消しコミット自体を未申告と判定して取り消しを取り消していた
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GSwBvT9CH8mKfgyFn2JWfS

@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 6 | codex | APPROVE

修正が必要な指摘はありません。

@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 6 | gemini | APPROVE

実機検証で見つかった不具合への対応として、設計・実装ともに非常に堅牢です。

  • 取り消し処理 (_drop_items) での履歴逆再生による競合回避と、失敗時の安全な退避機構が冪等性を伴って正しく実装されています。
  • 終了コード 4 の導入により、進行スクリプトの無言続行(握り潰し)を防ぎ、異常系を安全に停止できています。
  • 範囲検査の厳密な前方一致 (path_in_scope) や、gemini 向けの語彙展開、読み取り除外回避など、ランタイム固有の制約への対処も適切です。

懸念点やバグは見当たらず、単体テストによるカバレッジも要求を満たしています。

@takemi-ohama
takemi-ohama marked this pull request as ready for review August 16, 2026 04:08
@takemi-ohama
takemi-ohama merged commit 26eb4eb into mainAug 16, 2026
7 checks passed
@takemi-ohama
takemi-ohama deleted the fix/issue-113-cross-refactoring-defects branch August 16, 2026 04:12
takemi-ohama added a commit that referenced this pull request Aug 16, 2026
不具合 9 件の修正(#119 / v8.2.0)を実機で確かめた記録を残す。
修正した 9 件はすべて実機で成立し、前回(#118)は到達できなかったレビュー・判定・
実装担当の輪番・集計まで通った。特に本丸だった取り消しの巻き戻しと積み直しは、
前回破綻したのと同じ条件(採用項目の多くが同一ファイルを触る)で成立している。
あわせて新しい不具合を 2 件見つけた(#121 で修正済み)。
- 10: pre-push の同期検査と範囲ルールが両立せず、あらゆる push が落ちる
- 11: 適用で失敗した項目が「対象外」に入らず、同じ提案が再採用される
構造改善の成果 4 項目は取り込まない。#121 が同じ refactor.py を大きく変えており、
手でコンフリクトを解消すると「2 者のレビューを通った内容」という性質が失われる。
指摘の修正と再レビューの繰り返し、上限到達時の項目単位の見送りは依然として未到達。
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