Skip to content

cross-review: 再開(RESUMED)時に前ラウンドの未解決 review thread が judge で考慮されず即収束しスイープ依存になる #33

@takemi-ohama

Description

@takemi-ohama

概要

ndf:cross-review中断後に再開 (RESUMED) し、その再開ラウンドで即収束した場合、前回中断ラウンドで投稿された 未解決 (open) review thread が judge の収束判定で一切考慮されず、fix フェーズを経ずに approved になる。最終的には Step 7.5 スイープが拾うため事故にはならないが、「スイープが唯一のセーフティネット」になっている設計フローが docs に明記されていない。関連して result.json.comments_count(その回の投稿数)を PR 上の実 open thread 総数と取り違えやすい点も曖昧。

観測したケース

devbasex/devbase PR #67(docs PR)の cross-review で発生:

  1. 過去に同 PR で cross-review を起動 → round 2 で codex が REQUEST_CHANGESarchitecture.md:70SHORTCUTS 記述が実装と矛盾=実害ある誤記、ほか計3件のインラインコメント)を投稿した状態で中断
  2. 後日 state.py initRESUMED=1(前回中断 state から再開, round=0)で復帰。
  3. 再開後の round 1: codex=APPROVE(0件) / gemini=COMMENT(minor 2件)。judgeこの回の result.json の intent のみを見て「両方 APPROVE 相当。収束」と判定し final=approved
  4. しかし PR 上の open thread は 5 件(前回 round 2 由来の 3 件 + 今回 gemini の 2 件)。前回の REQUEST_CHANGES 由来 3 件は fix を一度も通らず残存。
  5. Step 7.5 スイープが graphql で全 open thread を洗い直して 5 件全て修正・Resolve(remaining_open=0)。スイープのおかげで救われた

問題点

1. judge が再開時の前ラウンド未解決 thread を考慮しない

state.py judge は当該ラウンドの result.json.intent だけで収束判定する。再開ラウンドが即収束すると、前回 REQUEST_CHANGES で投稿された未解決の major 級コメントを残したまま approved になる。Step 7.5 スイープが無ければ実害指摘を放置して終了する設計穴。

  • 期待挙動の候補:
    • (a) init/start-round で「再開時に既存 open thread が N 件ある」ことを検出し、最初の round を強制的に fix 経由にする(あるいは judge で open_thread_count > 0 なら継続)。
    • (b) 最低でも docs に「再開時の前ラウンド未解決 thread は judge では拾えず Step 7.5 スイープが回収する」フローと、スイープが必須である理由(APPROVE ラウンドの minor だけでなく再開引き継ぎ分も対象)を明記する。

2. comments_count と実 open thread 数の乖離が明文化されていない

result.json.comments_count は「その回 AI が新規投稿した件数」であり、PR 上の 実 open thread 総数とは一致しない(再開・複数ラウンド累積で乖離)。

  • docs/02-fix-and-rotation.md の fix サブエージェント起動テンプレは {CODEX_COMMENT_COUNT}件 を埋め込むため、メイン or サブエージェントが「この件数だけ対応すればよい」と誤解すると取りこぼす。
  • スイープ側テンプレ(Step 7.5)は件数を渡さず「全 open review thread を gh api で洗い出し」と正しく書いているが、「件数を信じるな・graphql で実 open thread を必ず洗い直せ」という明示の注意書きがない。fix テンプレ側にも同趣旨の注意が欲しい。

提案

  • docs/01-state-and-review.md## Step 3: 判定 に、再開時の前ラウンド未解決 thread が judge 対象外である旨と、Step 7.5 スイープが回収責任を負う旨を追記。
  • 可能なら judge / start-round に「再開時 open thread 数チェック」を入れて、未解決があれば最初のラウンドを fix 経由にする(設計判断)。
  • fix / スイープ両テンプレに「comments_count は投稿数であり実 open thread 数ではない。必ず graphql で全 open thread を洗い直す」注意を明記。

環境

  • plugin: ndf 4.16.0 (skills/cross-review)
  • 観測: devbasex/devbase PR #67(最終的に approved / open thread 0 で正常終了。スイープ commit 5f7a0c6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions