Skip to content

cross-review が収束しない(final が max_rounds・oscillation)のに駆動が ok を返し、スプリントの検査の review が止まらない #2143

Closed

Description

@takemi-ohama

何を見つけたか

cross-review の駆動は、final が max_rounds や oscillation(収束しなかった)でも、最終スイープを終えれば status: ok を返す(skills/cross-review/scripts/drive.py の finish → drive_pause.done)。supervise の DriveStep は status が ok かどうかだけで成否を決める(scripts/supervise_lib/worker_steps.py の 187 行付近)。このため、スプリントの検査のプランの review ステップは、収束しなくても成功になる。on_fail: abort は働かず、base-sync・test-all・ready へ進む。

再現(ndf 10.22.0、2026-10-25): CI を持たない一時リポジトリの PR で supervise.py new check --pr N --test-cmd 'true {paths}' --mode light を流した。続けて supervise.py queue <plan> --max 1 を流した。cross-review は final=max_rounds・deferred 8 で終わり、review は exit 0 で、test-all・ready まで進んだ。

10.21.0 でも同じ振る舞いで、#1593 による退行ではない(10.21.0 と 10.22.0 の supervise.py run に疑似の駆動のプランを流して比べた)。

どこで見つけたか

PR #2138(ndf v10.22.0 のリリース)のリリース後テストで、#1593 の受け入れ条件 6 を確かめたとき。条件 6 は「cross-review が収束しない(final が approved 以外)か駆動が stopped を返したときは、review の on_fail: abort のとおり止まる」と書く。stopped は止まった。final が approved 以外の場合は止まらなかった。

なぜこの変更の範囲外なのか

#1593 の条件 6 は「退行しない」の条件で、変更前と同じ振る舞いであることは確かめた。条件の前提(収束しないと止まる)は変更前から成り立っていなかった。直す対象は駆動の結果の契約か supervise の成否の判定で、#1593 の変更の外にある。根拠: MVV 版 3(判断の範囲は目の前の変更に限る)。

直さないと何が起きるか

収束しなかったレビュー(未解決や見送りが残ったもの)が、スプリントの検査を通って開発版・本番の承認ゲート 2 へ進む。承認資料の「レビュー」の行が収束しなかったことを目立たせなければ、人が見落とす。

起票者の推定

由来

PR #2138

受け入れ条件

  • 1. cross-review の駆動(skills/cross-review/scripts/drive.py)が最終スイープを終え、final が max_rounds か oscillation のとき → 駆動の結果 JSON の status は ok 以外で、metrics.final にその値が残る
  • 2. 上と同じ状況で、review ステップ(on_fail: abort)を持つ検査のプランを supervise.py run か supervise.py queue で流すと → review は失敗として記録され、後続の base-sync・test-all・ready は流れない
  • 3. final が approved で最終スイープを終えたとき → 駆動は今と同じく status: ok を返し、review は成功して後続のステップへ進む(退行しない)
  • 4. 駆動が stopped を返したとき → 今と同じく review は失敗し、プランは止まる(退行しない)

修正レイヤー

親 #2227(全工程の結果を統一した JSON レポートにし、失敗・未収束・未記録を ok で返さない)。cross-review/scripts/drive.py の finish は final の値にかかわらず dp.done(status: ok)を返し、supervise_lib/worker_steps.py の DriveStep.drive_loop は ok なら成功とする(supervise_lib に metrics.final を見る箇所は無い)。駆動の結果の契約(収束しなければ ok にしない)を直し、呼び出し側は status だけを見る形のまま残す。cross-refactoring/scripts/drive.py の done も同じ形である。

進行

モード: — / 進め方: auto

  • 要求と受け入れ条件
  • 作業場所の用意 — 2026-10-31 03:59
  • 設計
  • 素材の収集と出典の確定
  • ドキュメント再構成
  • ドキュメントレビュー
  • 計画 — 2026-10-31 03:58
  • 実装 — 2026-10-31 03:59
  • 構造改善 — 2026-10-31 07:37
  • 実装レビュー — 2026-10-31 09:11
  • 完了判定 — 2026-10-31 04:32
  • Pull Request — 2026-10-31 04:44
  • 確定仕様化 — 2026-10-31 10:59
  • 後片付け — 2026-10-31 10:57
  • 配布 — 2026-10-31 10:33
  • 体裁レビュー
  • リリース後テスト — 2026-10-31 10:56
  • 振り返り — 2026-10-31 11:00
  • 棚卸し — 2026-10-31 11:21

振り返り: #2282 (comment)

リリース後テスト(v10.27.2)で残ったこと

条件 1・3・4 は合格、条件 2 は不合格(記録: #2281 (comment) )。

  • 検査のプランの review ステップ(plugins/ndf/scripts/supervise_lib/templates.py の _inspect_steps)が "on_exit": {"6": "base-sync"} を持つ。final が max_rounds・oscillation のとき、駆動は終了コード 6・stopped を返すが、プランは review → base-sync → test-all → ready と後続へ進む
  • この行は PR スプリント m26-1 #2268 の検査のレビューの修正(round 2、コミット f4ffafa)が「全工程の結果を統一した JSON レポートにし、失敗・未収束・未記録を ok で返さない #2227 の決定 1」を根拠に足した。決定 1 は「プランは on_exit で 6 だけを別の行き先へ回せる(未収束を judge へ渡すなど)」と書き、後続へ素通りさせるとは決めていない
  • 直し方の候補: 6 の行き先を judge(未収束の扱いを判断するステップ)にする / on_exit を外して on_fail: abort に戻す。どちらでも条件 2 を満たす

振り返り: #2320 (comment)

Activity

  1. added 2 commits that reference this issue on Oct 31, 2026
  2. takemi-ohama commented on Nov 1, 2026

    @takemi-ohama
    ContributorAuthor

    スプリント(スプリント m26-2の後片付け)を通りました

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions