Skip to content

cross-review: 誤りを示されていない重大な指摘が数えられずに承認で終わる → 数えない指摘を棄却と軽微な指摘に限る(#732 #624 #706) - #790

Open
takemi-ohama wants to merge 21 commits into
developfrom
feat/issue-732-uncounted-classification
Open

takemi-ohama wants to merge 21 commits into
developfrom
feat/issue-732-uncounted-classification

Conversation

@takemi-ohama

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

Copy link
Copy Markdown
Contributor

Summary

cross-review の収束の判定が、誰にも誤りを示されていない重大な指摘を数えずに承認で終わる事象を直す。数えない判断を、誤りだと示された指摘(棄却)と承認を妨げない軽微な指摘に限り、誤りを示されていない重大な指摘は新しい区分「未反証」(unrefuted)として数えて修正の工程へ渡す。「なぜ独立に確かめられていないか」は理由(unrefuted_reason: 反証なし no_critique / 支持なし not_supported)として状態ファイルに残る。

  • 区分を 6 つにする。人の判断待ちの条件から根拠の 2 項目を外し、重大な指摘の残余を未反証に、軽微な指摘の残余を立証不足に置く(設計の決定 2〜6)
  • 効果の測定の「この変更の方式」を、収束の判定と同じ 3 区分に揃え、2 か所の集合の一致をテストで固定する(決定 7)
  • 反証が揃わない取り込みでは、先に付いていた印を外し、そのラウンドを全件数える側へ戻す(決定 8)
  • 反証のプロンプトに「立証できないと返しても指摘は数から落ちない。誤りを示せるなら否定を返す」を書く(決定 9)
  • 規約 3 文書と確定仕様の区分の表・行き先・収束の判定・測定の表を同じ差分で更新する(決定 11)
  • 収束の判定の本体・終了コード・標準出力の変数は変えない(決定 10。担当 1 回の起動の結末を共通の語彙で読み、利用上限などの理由が失われる形を根本原因の場所で直す #729 の束との境界)

関連する issue: Closes #732 / Closes #624 / Closes #706

文書 場所
要求(受け入れ条件 AC1〜AC22) issues/issue-732-624-706-requirements.md
設計(決定 1〜11。業務用語と識別子の対応表) issues/issue-732-624-706-design.md(設計 PR #783
実装計画 issues/issue-732-624-706-plan.md

Test plan

  • uv run --with pytest pytest scripts/tests plugins/ndf -q → 4452 passed、exit=0(AC21。実装で 23 件、構造改善のテスト整備で 16 件を追加)
  • uv run --with pytest pytest plugins/ndf/skills/cross-review/tests -q → 908 件通過(基準 891 件 + 追加 17 件)、配置テスト 34 件(+6)
  • python3 scripts/check-skill-frontmatter.py → exit=0(AC22)
  • python3 scripts/check-doc-staleness.py → exit=0(AC22)
  • python3 scripts/check-markdown-links.py --root . → exit=0(AC22)
  • python3 scripts/check-doc-line-limit.py → exit=0(AC22。確定仕様は 471 行 / 上限 500)
  • bash scripts/build-runtime-plugins.sh --check → exit=0(生成物のずれ無し)
  • git diff -U0 develop -- plugins/ndf/skills/cross-review/scripts/state.py | grep '^@@' | grep -c cmd_judge → 0(AC17。収束の判定の本体の行に差分が無い)
  • AC18〜AC20 の grep → unrefuted が規約 06 / 04 / 05 と確定仕様に 6 / 5 / 1 / 7 行、「印を外す」が規約 06 に 1 行、「数から落ち」が反証のプロンプトに 1 行

受け入れ条件とテストの対応:

受け入れ条件 テスト
AC1〜AC10、AC14、AC16 tests/test_classify_findings.py(設計の実測 A〜K。期待値を改めた既存テストは AC16 の 4 件だけ)
AC11、AC12 tests/test_measure.py
AC13、AC15 tests/test_critiques.py
AC18〜AC20 tests/test_skill_layout.py

未検証の項目: 収束までのラウンド数の増え方と、未反証が多いときの修正の担当の負荷(設計の「未確認のまま残ること」。配布後に測定スクリプトの出力で見る)
既存の失敗: 無し(develop 2b14060 で 4413 件通過を確かめた後に着手)
範囲外と判断したもの: 担当を 1 者へ絞る指定の意味づけ(#727)、投稿の重なり(#730)、終了コードと結末の語彙(#729)、立証不足の区分の改名(設計の決定 6 で残す)

検査の工程

構造改善(/ndf:cross-refactoring)と実装レビュー(/ndf:cross-review)を通し、完了判定の段階 2〜4 を実行した。

構造改善

項目 結果
対象範囲 収束ループの状態の管理スクリプトとそのテスト(plugins/ndf/skills/cross-review/scripts / tests
ラウンド テスト整備 2 回 + 構造改善 2 回(終了理由は上限。max_outer_rounds
適用した改善 11 件(テストの追加 6 件、構造の整理 5 件)。取り消し 3 件
最終ゲート 全体テストで通過(exit=0、修正 0 回)
改修計画 issues/refactoring-plan-rf790.md

取り消した 3 件は、履歴に実行主体の記載を欠いたもの、テストの期待する振る舞いを変えたもの、適用そのものが通らなかったものである。内訳は改修計画にある。

実装レビュー

項目 結果
ラウンド 1 回で収束(approved
判定 2 者とも承認、指摘 0 件
最終スイープ 未解決の指摘 0 件(投稿の実数で確認)

完了判定

いずれも作業ツリーの根で実行し、終了コードで合否を判定した(2026-09-19T21:53Z 〜 21:56Z、cef8f365)。

段階 コマンド 結果
全体テスト uv run --with pytest pytest scripts/tests plugins/ndf -q 4452 passed / exit=0
生成物の同期 bash scripts/build-runtime-plugins.sh --check exit=0
Skill の宣言 python3 scripts/check-skill-frontmatter.py exit=0(49 個 / 警告 0 件)
配布物の定義 claude plugin validate . exit=0(未知フィールドの警告 24 件。終了コードは変わらない)
指示書 python3 plugins/ndf/scripts/instructions-check.py --root . exit=0

継続的統合は 15 件すべて成功(gh pr checks 790。手元で実行しないコンテナ起動の検査 4 件を含む)。

未検証の項目: 収束までのラウンド数の増え方と、未反証が多いときの修正の担当の負荷(配布後に測定の出力で見る)
既存の失敗: 無し
範囲外と判断したもの: 起動した担当が結果を残さないまま同じ適用の群を繰り返す事象(既存の #592#729 の範囲)、開発用の作業ツリーと同じブランチを検査の作業ツリーが取り出せない事象(既存の #638

影響範囲

配布先 変わるか
Claude Code 変わる(cross-review の状態の管理スクリプト・測定スクリプト・反証のプロンプト・規約 3 文書)
Codex 変わる(同じ Skill を配布)
Kiro CLI 変わる(skills/ を参照)
agy 変わる(skills/ を参照)

状態ファイルの classification に値 unrefuted が増え、unrefuted_reason が増える。version は上げない。この変更より前の状態ファイルは、次に収束の判定か反証の取り込みを呼んだ時点で区分が付け直される。

版を上げる必要があるか

要る。収束の判定が数える指摘の範囲(本番の振る舞い)が変わるため。版はまとまり単位でマージが終わった後に release で上げ、この Pull Request では上げない。

文書の検査

実装計画と本文に markdown-writing のセルフチェック 6 種を実行した。本文は検査の工程の結果を加えた後の値である。

検査 実装計画 本文
識別子(コードブロック外) 3 件(いずれもバッククォート内のファイルパスの指し示し) 7 件(バッククォート内のコマンド文字列・テストファイル名・状態の項目名の指し示し)
検討痕跡・変更履歴 0 件 0 件
強い否定語 1 件(「却下の理由を返す」。修正の担当の行為を指す業務用語で、設計文書と同じ語) 1 件(この表自身の行)
過剰な装飾語 0 件 0 件
根拠の曖昧な断定 0 件 0 件
多義語(5 回以上) 0 件 0 件

🤖 Generated with Claude Code

takemi-ohama and others added 13 commits September 19, 2026 11:26
収束の判定が数えないのは、誤りだと示された棄却と軽微な指摘だけにする。
人の判断待ちの条件から根拠の 2 項目を外し、重大な指摘の残余を新しい区分
「未反証」(unrefuted)として数え、理由(no_critique / not_supported)を
状態ファイルに残す。測定スクリプトの数える集合も同じ 3 区分に揃え、一致を
テストで固定する。反証が揃わない取り込みでは先に付いていた印を外す。
収束の判定の本体・終了コード・出力の変数は変えない。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
反証のプロンプトに「立証できないと返しても指摘は数から落ちない。誤りを
示せるなら否定を返す」を書く。規約 3 文書と確定仕様の区分の表を 6 行にし、
数えるのは 3 つと書き、揃わないときに印を外すことを足す。実装計画を issues/
に置き、設計文書の「未確認のまま残ること」を実装で決めた結果で更新する。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
measure の境界値、反証再取得ループ、PR prepare の公開入口を固定する。

Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
- critique-round.sh: collect-critiques 失敗時の終了コード素通し分岐を固定 (R1-003)
- rotate-pr.sh: squash モードでの新 PR 作成失敗時の旧 PR 復旧経路を固定 (R1-005)

Item-Id: R1-003
Round: 1
Impl-Runtime: agy
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
R2-001: measure の oracle 算出で resolved_thread_positions に非辞書要素
(文字列・null)が混じっても unmatched に数え、例外を出さず測定を続ける経路。
R2-002: rotate-pr.sh execute の --mode 値なし境界(${2:?...} で落ちる)と、
引数 0 個の entrypoint usage(exit 2)。いずれも gh/git を呼ぶ前で止まる。
R2-005: state.py cmd_set_current_pr で pr_history に過去 PR と現在 PR が並ぶとき、
過去 PR を変えず直前の現在 PR だけ閉じて新 PR を末尾へ足す分岐。

対象コードは変更していない。現状固定テストのみを追加。

Item-Id: R2-001
Round: 2
Impl-Runtime: kiro
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
execute --mode light が prepare.json の欠落・newtext.json の欠落・title の
空文字列・body の null をそれぞれ終了コード 1 で弾き、gh を呼ばず旧 PR を
open のまま残すことを固定する。対象のコードは変更しない。

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
公開入口 execute が state.json 不在時に終了コード 1 とエラーを返し、gh/git を呼ばない現状を固定する。

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

_verify_findings から以下の helper を抽出:
- 1 finding の verification record を生成しキャッシュと結果分類を行う _verify_one_finding
- merged_into の関係をたどり代表へ最良の verification を選ぶ _select_best_verification

_verify_findings を対象抽出、各 finding の検証、代表結果の集約の 3 段階に整理。

Item-Id: R3-001
Round: 3
Impl-Runtime: agy
Impl-Model: default
…scripts/state.py#COUNTED_CLASSIFICATIONS

cross-review の scripts / tests の構造改善(振る舞い不変)を 1 コミットにまとめる。

- R4-001: COUNTED_CLASSIFICATIONS を scripts/classifications.py へ集約し、
  state.py と measure.py が共有定義を import する(両者の重複を解消)。
- R4-004: conftest.py の autouse fixture を分割。gh 実行ガードは state_mod に
  依存させず、state.py の既定差し替えは state_mod を要求するテストだけへ適用する。
- R4-005: measure.py の _proposed から oracle のラウンド別分母絞りを
  _scoped_oracle_ids として抽出する。

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

レビュワーごとのファイル解決・JSON 読み込み・payload と comments の境界検証・
path / line / 本文の正規化が 1 つの二重ループに入っていた `_finding_keys` を
3 段の連鎖へ分ける。

- 第 1 段 `_read_finding_payload`: payload ファイルの読み込みと dict 検証
  (無い・読めないときは None、dict でなければ die(code=3))
- 第 2 段 `_comment_keys`: comments 要素の dict 検証と 3 つ組への変換
- `_finding_keys`: レビュワー列挙から各段をつなぐだけにする

振る舞いは変えない。die のメッセージと終了コード、位置欠損・行の型不正の
読み飛ばしは元のまま。

Item-Id: R4-002
Round: 4
Impl-Runtime: claude
Impl-Model: default
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
…ate.py#_init_new_state

新規初期化の各段階をモジュールレベル関数へ抽出し、初期化関数をオーケストレーションだけに整理する。構造依存テストも抽出後の段階呼び出しを検査する形へ更新する。

Item-Id: R4-003
Round: 4
Impl-Runtime: codex
Impl-Model: default
…ripts/state.py#_init_new_state"

This reverts commit 77d9383.
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、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 | APPROVE

区分を 6 つへ拡張し、誤りを示されていない majorunrefuted として数える変更は、収束の判定・効果の測定・反証プロンプト・規約 3 文書と確定仕様まで一貫している。COUNTED_CLASSIFICATIONSclassifications.py の 1 か所へ集約し test_measure.py で両モジュールの一致を固定した点、_handle_incomplete_critiques の印外しを複数印のケース込みでテストした点、_verify_one_finding / _select_best_verification / _read_finding_payload / _comment_keys / _scoped_oracle_ids の抽出がいずれも振る舞い保存である点を確認した。cross-review テスト 930 件通過・doc-staleness・build --check いずれも exit=0。修正を要する指摘は無い。

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

変更内容およびテスト・文書を確認しました。AC1〜AC22 の要件に沿って unrefuted 区分の追加と収束判定・効果測定の整合性確保、リファクタリング計画に基づいた分離が適切に行われており、回帰テストもすべて通過しています。指摘事項はありません。

@takemi-ohama
takemi-ohama marked this pull request as ready for review September 19, 2026 22:00
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