Skip to content

cross-review: 参加する CLI が 1 者でも使えないと収束ループを開始できず、再開で渡した引数が黙って無視される → 使える者だけで開始し、毎ラウンド 2 席を確保し、渡した引数は反映されるか反映しないと知らされる(P6: 共通層と cross-review) - #793

Merged
takemi-ohama merged 48 commits into
developfrom
feat/issue-727-participants
Sep 22, 2026

Conversation

@takemi-ohama

@takemi-ohama takemi-ohama commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

cross-review / cross-refactoring: 参加する CLI が 1 者でも使えないと収束ループを開始できず、再開で渡した引数が黙って無視される → 使える者だけで開始し、cross-review は毎ラウンド 2 席を確保し、再開で渡した引数は反映されるか反映しないと知らされる(実装 P6: 共通層と cross-review / #727 #687 #478 #648)

Summary

参加する CLI のどれか 1 者が導入・認証されていないと、収束ループの初期化が止まって開始できなかった。中断したループを進め方を変えて再開しても、渡した引数が黙って捨てられていた。

この Pull Request は、使える者の決定・席の埋め方・再開の反映の 3 つの規則を両方の収束ループが共有する層へ 1 か所ずつ置き、cross-review をその層へ載せ替える。cross-review の初期化は確認の失敗を記録して使える者で続け、各ラウンドに 2 席を確保する(使える者 → ホスト → 同じランタイムの 2 つ目)。再開では明示的に渡した引数を反映し、反映しない引数は理由とともに知らせる。

2 本に分けた 1 本目である。 2 本目(cross-refactoring 側と、呼び手を失う旧関数の削除、リポジトリの規約の文書)は、この Pull Request のマージの後に出す。そのため旧関数(check_auth / impl_pool / review_assign / assign)はここでは残す。

変えたこと

層 何が変わったか
共通層 止めない確認(probe_auth)、使える者の解決(resolve_participants と参加者の記録 Participants)、席の埋め方(review_seats)と席の名前(SEAT_PATTERN / seat_runtime)、適用の輪番(impl_assign)、cross-refactoring の母集合の既定(refactor_pool)、再開の反映(apply_resume_args / ResumeField)を足した
cross-review の初期化 共通層を呼び、参加者の記録と再開で変えた値の記録を状態ファイルへ書く。確認の失敗は記録して続け、全員を要する指定(--require-all)でだけ従来どおり止まる。1 者指定を渡して使える者が 0 者になったときは終了コード 1 で止まる
cross-review の担当 ラウンドの記録 → 1 者指定 → 参加者 → ホストの輪番 → 従来の 2 者の順で決める。前のラウンドの検査も、そのラウンドの担当を読む
cross-review の再開 渡した引数を反映し、反映しない引数を知らせる。担当に関わる引数を渡したときだけ確認し直して参加者を作り直す
席の名前 結果の受け口・起動スクリプト 2 本・監視・計測が、ランタイム名に 2〜9 の接尾辞が付いた名前を受け取れる。監視の上限と担当別の環境変数は、席の名前をランタイム名へ直してから引く
完了報告 「参加した者」の節(母集合・使える者・外した者・足した者・確認を通らなかった者・席の埋め合わせ・再開で変えた値)
手順書と文書 引数 3 つを足し、骨組みは値のある引数だけを初期化へ渡す。担当はラウンドの開始が返す席を使う

既定の振る舞いが 2 点変わる。 cross-review の初期化は「確認の失敗が 1 者でもあれば止める」から「使える者で回す」へ変わる(従来の形は --require-all)。使える者が 2 者に満たないとき、ホスト、次に同じランタイムの 2 つ目で席を埋める。

やらないこと

  • cross-refactoring 側の変更と、旧関数の削除、リポジトリの規約の文書(2 本目の Pull Request)
  • 起動した後に分かる使えなさで担当を自動的に外す仕組み(設計の決定 18)

Test plan

いずれも実行済み。判定は終了コードで見る。実行は 2026-09-22 03:08〜03:12 UTC、対象は head 7af3b787。

受け入れ条件の合否

対象 35 件(AC1〜AC6、AC8〜AC30、AC44〜AC46、AC48〜AC50)のうち 32 件が合格、3 件が未検証、不合格 0 件。条件ごとの検証手段と結果は、条件を 1 つずつ絞って実行して確かめた。

未検証の 3 件は、いずれも手元では作れない状態(生きた Pull Request、中断した実行の状態、認証が失効した CLI)を要する。

条件 なぜ手元で確かめられないか 代わりに確かめたこと
AC45 初期化の全体が、生きた Pull Request の取得と作業ツリーの同期を伴う 使える者の解決の層だけを実際の確認コマンドで再現し、exit=0 で参加者が 2 者に解決されることを確かめた
AC46 中断した実行の状態と、再開が触る外部の経路が要る 同じ振る舞い(1 者指定を渡した再開で次のラウンドが 1 席になる)を AC27 の 2 節点が exit=0 で確かめている
AC48 「認証の確認は通るが言語モデルを引けない CLI」を用意できない 確認コマンドの表がこの変更で差し替わっていないことを差分で確かめた

構造改善

工程の構造改善(cross-refactoring)を 6 ラウンド通した。対象の範囲は共通層と cross-review の実装・テストの 4 つの置き場所、判定は全体テストの合否である。

区分 件数
採用した改善項目 27
適用して検証を通ったもの 14
収束せず項目の単位で取り消したもの 13
見送った提案 23

終了は提案ラウンドの上限(4)による。最終ゲート(全体テスト)は exit=0 で通過した。取り消しの内訳と見送りの理由は改修計画(issues/refactoring-plan-rf793.md)にある。

実装レビュー

レビューの収束ループ(cross-review)を 4 ラウンド通し、承認で収束した。未解決の指摘は 0 件である。

ラウンド レビュー 対応
1 修正の要望 2 件 / 意見 1 件 3 件を修正(51724669)
2 修正の要望 1 件 / 承認 1 件 1 件を修正(b9888cef)
3 修正の要望 1 件 / 承認 1 件 1 件を却下(理由は下記)
4 承認 2 件 収束

却下した指摘が 1 件ある。 構造改善の成果をこの Pull Request から別の Pull Request へ分ける提案で、次の 3 点から分けない判断をした。構造改善は工程表の 1 行としてこの Pull Request を対象に通す工程であること、改修の計画はその工程が残す成果物であること、指摘の対象が実行時に指定した範囲の内側であることによる。切り分けと差し戻しは、1 改善項目 = 1 コミットの規約で項目の単位で行える。

develop の取り込みで決めたこと

#791 と #790 が先に develop へ入ったため、5 ファイルで競合を解いた。判断は次のとおりで、どちらの振る舞いも変えていない。

ファイル 解き方
認証の確認 止めない確認と走らせる部分を共有する形(この Pull Request)を採り、1 件用の関数を捨てた
監視 利用上限と致命を分ける形(#791)を採り、その中の CLI 固有の判定に席の名前の解釈を通した
手順書 完了判定の罠の表(#791)を採った
状態の部品 再開の経路の分割(#791)と、再開で渡した引数の反映(この Pull Request)を両方残した
手順書の検査のテスト 1 者指定のシェル変数で絞らない検査(この Pull Request)と未反証の区分の検査(#790)は別の対象を見るため、両方を残した

再開で渡した引数の扱いの節は、手順書ではなく契約の文書に置く。 手順書が行数の上限(500 行。この手順書は検査が 420 行で固定している)に達しているためで、手順書には同じ名前の節への案内を残した。同じ表を 2 か所へ置くと片方が古くなるため、正本を契約の文書に決めている。受け入れ条件 AC44 は、この置き場所に合わせて書き換えた(7af3b787)。

残リスク

  • ホストが席に入ったとき、自分の Pull Request への投稿の扱いが既存の規則で足りるかは実機で確かめていない。設計文書の「未確認のまま残ること」に運用で確かめる項目として残した
  • 同じランタイムの 2 席が、別のランタイムの 2 席より指摘を見落とすかは測っていない(同じ表に残した)
  • 受け入れ条件 3 件(AC45・AC46・AC48)は手元で作れない状態を要するため未検証である。配布の後に実機で確かめる(リリース後テストへ引き継ぐ)

文書の検査

この持ち場で新しく書いた文書の行(issues/issue-727-687-478-664-648-requirements.md / cross-review の手順書 / 契約の文書 / 母集合の文書)に対するセルフチェックの結果。コードブロックとインラインの記法を除いた本文 15 行が対象。

検査 当たった行
識別子と略語の混入 0
検討痕跡・変更履歴の混入 0
強い否定語の混入 0
過剰な装飾語の混入 0
根拠の曖昧な断定の混入 0
多義語の混入(5 回以上) 0

改修計画(issues/refactoring-plan-rf793.md)は対象から外した。 提案した実行主体の文言をそのまま載せる生成物で、対象を識別子で指し示すことがその文書の用途であるためである。

Closes #478
Closes #687

親 #727 と #648 は 2 本目の Pull Request(cross-refactoring 側と旧関数の削除)で閉じる。#648 の再開の反映は cross-refactoring 側が残り、#727 の完了条件(片方にだけ古い形が残らない)は 2 本目のマージで満たす。

🤖 Generated with Claude Code

https://claude.ai/code/session_01MGCedPTy818Zw7VYdmE4GB

takemi-ohama and others added 30 commits September 19, 2026 19:57
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- lib/auth.py: probe_auth(止めない確認)。check_auth と走らせる部分を共有する
- lib/assignment.py: refactor_pool / Participants / resolve_participants / SEAT_PATTERN /
  seat_runtime / review_seats / impl_assign。旧関数は別の Pull Request で消す
- lib/statefile.py: ResumeField / apply_resume_args(再開の反映)
- テスト: test_lib_participants.py / test_lib_resume_args.py を新設、
  test_auth_probe.py / test_lib_assignment.py / cross-refactoring の test_assignment.py に追記

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- 新規の初期化: 使える者の解決と止めない確認を呼び、participants と resume_changes を書く。
  使える者が 2 者に満たなければホスト、次に同じランタイムの 2 つ目で席を埋める
- 担当の読み出し: ラウンドの記録 → 1 者指定 → 参加者 → ホストの輪番 → 従来の 2 者の順へ。
  前ラウンドの検査もそのラウンドの担当を読む
- 再開: 明示的に渡した引数を反映し、反映しない引数を知らせる。担当に関わる引数を渡した
  ときだけ確認し直して参加者を作り直す
- 完了報告: 「参加した者」の節を足す
- 結果の受け口: 担当の引数を席の名前の形の検査へ
- テスト 48 件(test_state_resume_args.py / test_seat_names.py を新設)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 起動スクリプト 2 本: 席の名前を受け、CLI はランタイム名で選ぶ。結果ファイルは席の名前
- 監視: 席の名前からランタイムを引いて CLI 固有の検査を選ぶ。位置引数を席の形の検査へ
- 計測: ラウンドの記録の鍵のうち席の形に一致するものを数える
- SKILL.md / docs 01・04・05: 引数 3 つ、席の規則、状態ファイルの 2 項目、
  再開で渡した引数の扱い。骨組みは値のある引数だけを渡し、担当はラウンドの開始が返す席を使う
- テスト 14 件(席の受け口と手順書の検査)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ticipants

競合 4 ファイルを解いた。

- 認証の確認: 両方の切り出しのうち、止めない確認と共有する形(#727)を採り、
  1 件用の関数を捨てた。振る舞いは同じ
- 監視: 利用上限と致命を分ける形(#729)を採り、その中の CLI 固有の判定に
  席の名前の解釈を通した
- 手順書: 完了判定の罠の表(#729)を採った。再開で渡した引数の扱いは
  行数の上限に収めるため契約の文書へ移し、案内を残した
- 状態の部品: 再開の経路の分割(#729)と、再開で渡した引数の反映(#727)を
  両方残し、最新化の関数へ引数を通した

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MGCedPTy818Zw7VYdmE4GB
…ticipants

手順書の検査のテストで競合した。1 者指定のシェル変数で絞らない検査(#727)と
未反証の区分の検査(#732)は別の対象を見るため、両方を残した。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MGCedPTy818Zw7VYdmE4GB
明示指定、環境変数の優先順、推定不能時の例外を共通層の単体テストで固定する。

Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
3者以上の輪番、2者の固定、1者時のfallback/第二席補填、0者時のfallback/例外送出、不正なラウンド番号の拒絶を共通層の単体テストで固定する。

Item-Id: R1-002
Round: 1
Impl-Runtime: agy
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
…signment.py#review_seats

available=[] かつ fallback=[] で公開入口 review_seats を round_no=1 で呼ぶと
AssignmentError が送出されることを固定する。例外の利用者向け理由から、使える者と
席の埋め合わせ候補がともに無いことを示す要点だけを確認する。対象コードは変更しない。

Item-Id: R1-003
Round: 1
Impl-Runtime: kiro
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
….py#seat_runtime

SEAT_PATTERN の境界(接尾辞は -2〜-9 のみ、区切りはハイフン 1 つ)と、
ALL_RUNTIMES 外の名前が AssignmentError になることを単体で固定する。
対象のコードは変更していない。

Item-Id: R1-004
Round: 1
Impl-Runtime: claude
Impl-Model: default

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
基底席と副席からランタイム名を抽出する正常系を固定する。

Item-Id: R1-005
Round: 1
Impl-Runtime: codex
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
R2-001: assign で round_no < 1 の場合に AssignmentError が送出されるエラー経路を固定
R2-002: resolve_participants で母集合の全メンバーを exclude に指定した下限境界の振る舞いを固定

Item-Id: R2-001
Round: 2
Impl-Runtime: agy
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
…_assign

review_assign の round_no < 1 の下限境界で AssignmentError を送出する
振る舞いを現状固定テストで固定する。同モジュールの impl_assign や
review_seats には下限境界テストがあるが review_assign だけ抜けていた。
対象コードは変更しない。

Item-Id: R2-003
Round: 2
Impl-Runtime: kiro
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
…_assign

review_assign の輪番(母集合 3 者から (ラウンド番号 - 1) % 3 の 1 者を外す
各分岐)を現状固定テストで固定する。ホスト claude / codex / agy / kiro それぞれ
について round 1..6 を通し、3 ラウンド周期で循環すること、返るレビュー担当が
常に 2 者でホスト自身を含まないことを併せて固定する。対象コードは変更しない。

Item-Id: R2-004
Round: 2
Impl-Runtime: claude
Impl-Model: default

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
HOST_RUNTIMES に含まれないホストで AssignmentError と既存メッセージが返る経路を固定する。

Item-Id: R2-005
Round: 2
Impl-Runtime: codex
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
takemi-ohama and others added 3 commits September 22, 2026 01:34
…s.py#_append_model_measurement_warnings

引数 7 個のうち、1 ラウンド 1 担当の計測文脈として常に組で渡り回る 5 値
(round_no / runtime / requested / observed / role_label)を NamedTuple
`MeasurementContext` にまとめた。requested と observed はどちらも str で、
位置引数で並べると取り違えても型では気付けなかった。

呼び出し側は aggregate の実装担当経路と _aggregate_round_reviewers の
レビュー担当経路の 2 箇所。どちらもキーワードで ctx を組み立てる。
振る舞いは不変。

Item-Id: R6-004
Round: 6
Impl-Runtime: claude
Impl-Model: default

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…b/metrics.py#_append_model_measurement_warnings"

This reverts commit 5f63640.
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。

@takemi-ohama takemi-ohama left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 cross-review | round 1 | kiro | COMMENT

共通層への切り出し・席の埋め方(review_seats の n≥3/2/1/0 の分岐)・止めない確認(probe_auth と require_all)・再開の反映(apply_resume_args と participants 作り直し)は、手順書・契約文書・テスト(test_lib_participants / test_state_resume_args / test_seat_names)と整合していることを確認した。席の名前は起動(launch-reviewer.sh の ${SEAT%%-*})・監視(monitor.py の seat_runtime)・計測(measure.py の SEAT_PATTERN)へ同じ規則で通っている。

修正提案は 1 件(文書整合)で、インラインに置いた。設計レベルの追加指摘は無い。

Comment thread plugins/ndf/skills/cross-review/docs/04-contracts.md Outdated

@takemi-ohama takemi-ohama left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 cross-review | round 1 | agy | REQUEST_CHANGES

概要サマリ

  • state.py: --only 指定時にその担当が認証失敗した場合、0 者チェック(終了コード 1 での停止)がスキップされ、使えない担当が rounds に選出されてしまう不具合を検出しました。
  • SKILL.md: 引数表から「再開で渡した引数の扱い」への案内が欠落しており、契約文書への動線が切れている点を指摘しました。

Comment thread plugins/ndf/skills/cross-review/scripts/state.py
Comment thread plugins/ndf/skills/cross-review/SKILL.md
1 者指定(`--only`)はレビュー担当の席の埋め合わせを行わないため、指定した実行主体が
認証の確認を通らないと使える者が 0 者のまま席へ座り、結果が残らないラウンドが続く。
0 者の検査が 1 者指定を素通ししていたので、その場合も終了コード 1 で止める。

あわせて文書を 3 か所直した。

- 手順書の Step 0 に「再開で渡した引数の扱い」(契約の文書)への案内を足す
- 契約の文書の再開の表で、1 者指定を「反映し、参加者を作り直す」行へ分ける
- 母集合と収束の文書に、1 者指定が確認を通らないときの終了を書く

テストは初期化と再開の両方の経路で 0 者を止めることを固定する(修正前は 2 件とも落ちる
ことを確認済み)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MGCedPTy818Zw7VYdmE4GB
@takemi-ohama

takemi-ohama commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor Author

🔧 /ndf:fix サマリ

対応件数: critical=0 / major=1 / minor=2(合計 3 件)
deferred: 0 件 / rejected: 0 件
commit: 5172466
CI: SUCCESS(前のコミット時点の 15 チェックすべて pass。この修正の再実行は待っていない)
未解決スレッドの残数: 0

詳細

# 位置 重要度(再判定) 対応
1 plugins/ndf/skills/cross-review/scripts/state.py の _resolve_reviewers major(据え置き) 1 者指定で使える者が 0 者なら終了コード 1 で止める
2 SKILL.md の引数の節 minor(据え置き) Step 0 の注記から契約の文書の「再開で渡した引数の扱い」へ案内する
3 docs/04-contracts.md の再開の表 minor(据え置き) 1 者指定を「反映し、参加者を作り直す」行へ分ける

1 者指定で 0 者を止める(major)

1 者指定(--only)は席の埋め合わせを行わないため、指定した実行主体が認証の確認を通らないと、使える者が 0 者のまま _round_reviewers の順 2 でその 1 者が席へ座っていた。起動しても結果が残らないラウンドが続くため、初期化と再開の両方で終了コード 1 にした。状態ファイルは作らず、書き換えもしない。確認を飛ばした実行(NDF_SKIP_AUTH_CHECK)は使える者が空にならないため、従来どおり通る。

テストは 3 件足した(初期化 / 再開 / 確認を飛ばした場合)。検査を外すと前の 2 件が落ちることを確認済み。

文書(minor 2 件)

  • 手順書には行数の余白が無いため(tests/test_skill_layout.py が 420 行で固定、変更前も 420 行ちょうど)、段落を足さずに Step 0 の既存の注記へ案内を書いた
  • 契約の文書の表は 3 行に分けた。1 者指定は状態を書き換えたうえで確認をやり直し、外す者・足す者・全員を要する指定は参加者を作り直すだけである
  • 母集合と収束の文書(docs/05)の「1 者だけで回す指定」に、確認を通らないときの終了を書いた

検証

コマンド 結果
uv run --with pytest pytest scripts/tests plugins/ndf -q 4773 passed / exit=0
bash scripts/build-runtime-plugins.sh --check exit=0
python3 scripts/check-skill-frontmatter.py exit=0
python3 scripts/check-doc-staleness.py --root . exit=0
python3 scripts/check-markdown-links.py --root . exit=0
python3 scripts/check-skill-shell-vars.py exit=0

再レビューをお願いします。

🤖 Generated with Claude Code

https://claude.ai/code/session_01MGCedPTy818Zw7VYdmE4GB

@takemi-ohama takemi-ohama left a comment

Copy link
Copy Markdown
Contributor Author

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

監視上限の解決にも席のランタイム名を適用してください。

Comment thread plugins/ndf/scripts/lib/monitor.py

@takemi-ohama takemi-ohama left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 cross-review | round 2 | kiro | APPROVE

使える者の解決(resolve_participants / review_seats)・止めない確認(probe_auth)・再開の引数反映(apply_resume_args)・席の名前(SEAT_PATTERN / seat_runtime)の 4 経路を確認した。手順書から契約の文書への「再開で渡した引数の扱い」の移設と案内も辿れる。共通層と cross-review の 1641 件のテストを実行し全件通過。重点観点 1〜7 に、修正を要する指摘は見つからなかった。ホストが席に入る経路(観点 6)は実機未確認の残リスクとして申し送りどおり。

上限の表(limits.py)も担当別の環境変数も名前をランタイム名で引くため、席の名前
(claude-2 / agy-2 / kiro-2)のまま渡すと表に無い担当として既定の 180 秒へ落ち、
1 席目より早く無進捗(STALLED)と判定されていた。

- 並列監視の入口(_run_all)で席の名前をランタイム名へ直してから、監視の上限と
  無進捗の許容を引く
- 既定の解決(_agent_stall_default)も同じ扱いにする
- 2 席目が 1 席目と同じ許容・同じ担当別環境変数で監視されるテストを足す

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MGCedPTy818Zw7VYdmE4GB
@takemi-ohama

Copy link
Copy Markdown
Contributor Author

🔧 /ndf:fix サマリ(round 2)

対応件数: critical=0 / major=1 / minor=0(合計 1 件)
deferred: 0 件 / rejected: 0 件
commit: b9888ce
CI: SUCCESS(前のコミット時点の 15 チェックすべて pass。この修正の再実行は待っていない)
未解決スレッドの残数: 0

詳細

# 位置 重要度(再判定) 対応
1 plugins/ndf/scripts/lib/monitor.py L102 major(据え置き) 2 席目の監視の上限と無進捗の許容を、席の名前でなくランタイム名で引くよう直した

指摘のとおり、上限の表も担当別の環境変数も名前をランタイム名で引くため、席の名前(claude-2 / agy-2 / kiro-2)のまま渡すと表に無い担当として既定の 180 秒へ落ちていた。修正前の実測は次のとおりで、無進捗の許容だけが落ちる(監視の上限は工程で決まるため変わらない)。

[claude] ▶ hard timeout 1200s / stall 900s (phase review)
[claude-2] ▶ hard timeout 1200s / stall 180s (phase review)

直したのは 2 か所。

  • 並列監視の入口(_run_all)— 席の名前を _agent_runtime() でランタイム名へ直してから limits.monitor_timeout / limits.stall_timeout を引く
  • 既定の解決(_agent_stall_default)— 同じ扱いにする

起動側(launch-reviewer.sh)はすでに ${SEAT%%-*} でランタイム名へ直して launch-cli.sh を呼んでいるため、CLI の上限の側に同じ取りこぼしは無い。

テスト

plugins/ndf/skills/cross-review/tests/test_seat_names.py に 3 件(媒介変数化で 6 件)足した。

  • 2 席目の無進捗の許容が、そのランタイムの値と一致する(claude-2=900 / agy-2=480 / kiro-2=480 / codex-2=180)
  • 担当別の環境変数(MONITOR_STALL_CLAUDE)が 2 席目にも効く
  • _run_all を通しても、両席が同じ上限・同じ許容で監視される

修正を戻すと 5 件落ちることを確認した。テスト一式は 4779 件 pass(uv run --with pytest pytest scripts/tests plugins/ndf -q)。配布物の同期(scripts/build-runtime-plugins.sh)に差分は出ない。

@takemi-ohama takemi-ohama left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 cross-review | round 3 | agy | APPROVE

重点観点 1〜7、仕様適合、席の埋め合わせおよび再開引数の反映ロジック、テスト網羅性を確認しました。要修正点はありません。

@takemi-ohama takemi-ohama left a comment

Copy link
Copy Markdown
Contributor Author

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

plugins/ndf/scripts/lib/worktree-common.sh:1058 — [major / 変更範囲] 参加者解決・再開・席名の修正とは独立した書き込み先解析器の分割と、その作業記録 issues/refactoring-plan-rf793.md が混在しています。障害時の切り分けと差し戻しをこの PR の目的に限定できるよう、この解析器のリファクタリングと専用計画を別 PR へ分離してください。

@takemi-ohama

Copy link
Copy Markdown
Contributor Author

レビューへの返答(round 3 / 構造改善の成果を分ける提案)

判断: 分けない(却下)。 この Pull Request の工程の組み方に照らして、3 点を根拠に判断しました。

  1. 構造改善は、この Pull Request を対象に通す工程である。 工程表(development-workflow の
    「モードごとに起動する Skill」)では、実装の次・実装レビューの前に構造改善が置かれ、対象の
    Pull Request 番号を必須の引数に取ります。別の Pull Request へ移すと、工程の入力が変わります。
  2. 改修の計画は、その工程が残す成果物である。 直した理由と手順は提案の時点にしか残らないため、
    同じ Pull Request に載せる規約になっています(cross-refactoring の設計方針の「改修計画」)。
  3. 指摘の対象は、この実行で指定した範囲の内側である。 範囲には共通層の置き場所
    (plugins/ndf/scripts/lib)を含めており、書き込み先の解析器(worktree-common.sh)はその中に
    あります。範囲の外を触った変更ではありません。

切り分けと差し戻しについて。 1 改善項目 = 1 コミットの規約で積んでいるため、項目の単位で戻せます。
この実行では 27 件を採用し、14 件を適用、13 件は収束しなかったため項目の単位で取り消してあります。
適用した各コミットには、項目の識別子・ラウンド・実行主体を持つトレーラーが付いています。

残リスク。 構造改善の差分(14 件)は、この Pull Request の主題(参加する実行主体の解決と席の
埋め方、再開で渡した引数の反映)とは独立しています。障害の切り分けでは、主題の変更と構造の変更を
コミットの単位で分けて追うことになります。

@takemi-ohama takemi-ohama left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 cross-review | round 4 | kiro | APPROVE

共通層への切り出し(resolve_participants / review_seats / apply_resume_args)と cross-review の載せ替えを確認。席の名前の 3 経路(起動・監視・計測)の一貫性、review_seats n≥3 が旧 review_assign と全ラウンド一致、止めない確認と再開引数の反映(未指定は上書きしない・--only none の二重記録なし)、AC44 の契約文書への移設が辿れる点、新規テスト 71 件のローカル pass を確認。修正提案なし。

@takemi-ohama takemi-ohama left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 cross-review | round 4 | agy | APPROVE

検証サマリ

  • 対象コミット: b9888cefe820fc6cbc4982327d722d2a8f07bb12
  • 単体テスト: 1,647 件全件 PASS (pytest plugins/ndf/scripts/tests plugins/ndf/skills/cross-review/tests)
  • 判定: 重大な指摘・機能不整合・契約違反なし(APPROVE)

重点観点の確認結果

  1. 使える者の解決と席の埋め方
    • 0 者 / 1 者 / 2 者 / 3 者以上の各分岐における席割り当てと fallback(ホストおよび席の 2 つ目 -2)の振る舞いが assignment.review_seats および state.py で正しく整合していることを確認。
    • 1 者指定(--only)時に指定対象が確認を通らない場合、状態ファイルを作成・更新せず終了コード 1 で即時停止するガード(51724669)を確認。
  2. 止めない確認(probe_auth)
    • 認証確認が 1 者の失敗で中断せず (results, skipped) を返し、通らない者を unavailable に記録して続行することを確認。
    • NDF_SKIP_AUTH_CHECK 設定時にスキップログが出力され、状態ファイルおよび cmd_report(_print_participants)に反映されることを確認。
  3. 再開時の引数反映
    • statefile.py の apply_resume_args により、反映対象(max_rounds, rotate_after, only, verify_command, verify_exit_code)の更新と resume_changes への記録が正常に動作することを確認。
    • 非反映引数(--host)が既存状態と異なる場合に警告ログを出し状態を変更しないこと、--only none / --include none / --exclude none によるリセット処理が正しく動作することを確認。契約文書(docs/04-contracts.md)の表と完全に一致。
  4. 席の名前の一貫性
    • 起動(launch-reviewer.sh)、監視(monitor.py)、計測(measure.py / metrics.py)、結果取得(state.py read-result)の 3 経路すべてで SEAT_PATTERN に沿った席名(例: claude-2)が正しく伝搬・処理されることを確認。
    • コミット b9888cefe により、2 席目の監視タイムアウトおよび stall 判定が席名ではなくランタイム名(_agent_runtime)から適切に引かれるよう修正されていることを確認。
  5. 手順書と契約文書の整合
    • SKILL.md の Step 0 から docs/04-contracts.md の「再開で渡した引数の扱い」への誘導が適切に配置され、500 行制約を遵守しつつ契約仕様が追跡可能であることを確認。
  6. ホストが席に入る経路
    • ホストが fallback として席に入った場合の is_own_pr / event_downgrade 設定が正しく連携し、残リスクとして設計書に明記されていることを確認。
  7. 文書の規約
    • 見出しに識別子を含まないこと、説明文の主語・目的語に生コード識別子を直接置かず業務用語+括弧書きとすること、Mermaid 図の記号・ラベルの引用符囲みが遵守されていることを確認。

再開で渡した引数の扱いは、手順書ではなく契約の文書に置き、手順書からは案内で辿る形にした。
手順書の行数が上限(500 行。この手順書は検査が 420 行で固定している)に張り付いていて表を
足せないことと、同じ表を 2 か所へ置くと片方が古くなることによる。受け入れ条件の側を、実際の
置き場所へ合わせた。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MGCedPTy818Zw7VYdmE4GB
@takemi-ohama
takemi-ohama marked this pull request as ready for review September 22, 2026 03:24
@takemi-ohama
takemi-ohama merged commit 4d1470d into develop Sep 22, 2026
16 checks passed
@takemi-ohama
takemi-ohama deleted the feat/issue-727-participants branch September 22, 2026 03:31
Sign up for free to 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