Skip to content

cross-review: 利用上限で止まった担当が「結果ファイル無し」と報告されて空振りの起動し直しで待たされ、止めた担当が後から結果を書く → 上限を理由に報告して同じラウンドで起動し直さず、止めた後は書かせない(#729 #619 #584) - #791

Open
takemi-ohama wants to merge 49 commits into
developfrom
feat/issue-729-outcome-vocabulary

Conversation

@takemi-ohama

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

Copy link
Copy Markdown
Contributor

Summary

担当の CLI が利用上限で落ちると、監視はその文言を読めず、結果なしの理由は「結果ファイル無し」に畳まれていた。進行側は同じ担当を同じラウンドで起動し直し、監視の上限 1 回分(レビューで 1200 秒)を待ってから全体を誤りで終えていた(#619)。監視が止めた担当の子プロセスが、止めた後に結果ファイルを書くことがあった(#584)。根本原因は、結果なしの判断を cross-review と cross-refactoring がそれぞれ結果ファイルの有無だけで行い、監視が書いた理由を誰も読まないことにある(#729)。

この変更で成り立つこと:

  • 結末の語彙(理由 9 語)と起動し直しの可否を、結末の共通層(plugins/ndf/scripts/lib/monitor_outcome.py)の 1 か所に置く。起動 1 回の結末を 1 つの値として読む関数(read_launch_outcome)を新設し、cross-review の結果の取り込みはその値を読むだけになる。cross-refactoring の側は契約だけを受け取り、実装は G4(cross-refactoring の取り込みが結果なしを値で受け、群の状態と未検証コミットの取り消しを 1 か所で決める #728)が行う
  • 監視が利用上限の文言(kiro の月間の上限、claude の 429、既存の quota / rate limit / HTTP 429)を検知し、理由「利用上限」(usage_limit)を結末に添える。CLI 自身の上限で結果を書かずに終わった担当は理由「CLI の上限」(cli_timeout)になる。監視の終了コードと標準出力は変えない
  • cross-review の判定は結果なしの担当の理由を 1 行で出し、起動し直しても解けない理由(利用上限)を含むときは同じラウンドで起動し直さず、誤りの終わりとして終了コード 1 で止める。報告のラウンド表にも理由が出る。骨組み(SKILL.md)の行は 1 つも変わらない
  • 起動の手順が CLI を独立したプロセスグループで起動し(set -m)、監視はグループの先頭のときだけグループごと止める。止めた後に子プロセスが結果ファイルを書かない

設計は issues/issue-729-619-584-design.md(PR #781 でマージ済み。決定 12 件)、要求と受け入れ条件は issues/issue-729-619-584-requirements.md(AC1〜AC24)、実装の分解は issues/issue-729-619-584-implementation-plan.md(8 タスク)にある。設計の決定は変えていない。「未確認のまま残ること」の 1・3・5・6 を、実装で決めた結果へ更新した。

関連する issue: Closes #729 / Closes #619 / Closes #584

受け入れ条件と確かめ方

条件 何で確かめたか
AC1(理由 9 語・既定の対応は変えない) plugins/ndf/scripts/tests/test_monitor_outcome_unit.py
AC2〜AC7(利用上限・CLI の上限の検知、除外、終了コードと標準出力は変えない) plugins/ndf/skills/cross-review/tests/test_monitor_usage_limit.py(設計文書の「実測」の 10 行、偽の claude を err.log / stdout.log の両方で)。既存の test_monitor_outcome_file.py / test_monitor_early_error.py は変更せずに通る
AC8〜AC11(結末を 1 つの値として読む、失敗しない) test_monitor_outcome_unit.py(監視の結果ファイル × 結果ファイルの組み合わせ、capsys で出力が空)
AC12(可否の表は共通層だけ) git grep -n 'usage_limit' -- plugins/ndf/skills の一致は文書とテストだけ。判定のテストに「共通層の集合を差し替えると可否が追随する」検査がある
AC13(取り込みが理由と監視の詳細を残す、終了コードは変えない) plugins/ndf/skills/cross-review/tests/test_read_result_reason.py(stem 3 か所の突き合わせを含む)
AC14〜AC17(判定の理由の行、利用上限で止める、7 / 1 の枝は変えない、報告の表) plugins/ndf/skills/cross-review/tests/test_judge_no_result_reason.py
AC18(文書の理由 10 語、見分け方) docs/01-state-and-review.md の表と docs/03-review-output.md の「上限に当たった場合の見分け方」
AC19〜AC21(プロセスグループ) plugins/ndf/skills/cross-review/tests/test_launch_cli_process_group.py(3 秒後に子が書く偽の CLI)
AC22〜AC23(退行、同期、定義の検査) 下の Test plan
AC24(骨組みの行は変えない) git diff origin/develop -- plugins/ndf/skills/cross-review/SKILL.md が 0 行

Test plan

実行日: 2026-09-19。作業ツリー .worktrees/feat/issue-729-outcome-vocabulary(HEAD は origin/develop を取り込んだ 406d510)。監視の環境変数(MONITOR_*)を export していないシェルで実行した。

項目 コマンド 結果
全体テスト uv run --with pytest pytest scripts/tests plugins/ndf -q -p no:cacheprovider 4555 passed(変更前 4413)/ exit=0
配布物の同期 bash scripts/build-runtime-plugins.sh --check 生成物に差なし / exit=0
定義の検査 python3 scripts/check-skill-frontmatter.py exit=0
定義の検査 claude plugin validate . 警告(policy / interface の未知フィールド)のみ / exit=0
文書の検査 python3 scripts/check-doc-line-limit.py 271 files, limit 500 / exit=0(docs/01-state-and-review.md は 500 行)
文書の検査 python3 scripts/check-markdown-links.py exit=0
文書の検査 python3 scripts/check-doc-staleness.py exit=0
AC12 git grep -n 'usage_limit' -- plugins/ndf/skills から /tests//docs/ を除く 0 行
AC24 git diff origin/develop -- plugins/ndf/skills/cross-review/SKILL.md 0 行
#619 の再現 標準エラーに Monthly request limit reached を書いて終わる偽の kiro を PATH に置き、launch-cli.sh kiro … reviewmonitor.py 8619 --phase review --agents kiro --poll 1state.py read-result 8619 kirostate.py judge 8619 監視 exit=4・reason=usage_limit → 取り込み exit=1・no_result_reason=usage_limitmonitor_detail あり → 判定 exit=1(7 ではない)・NO_RESULT_REASONS='kiro=usage_limit'final=errorrelaunched なし
#584 の再現 3 秒後に子プロセスが late-result.json を書く偽の CLI を launch-cli.sh codex で起動し、_kill_pid(pid) の後に 4 秒待つ os.getpgid(pid) == pid(起動元とは別のグループ)、結果ファイルは書かれない。対照(止めない)では書かれる

チェックボックスの形で書くテンプレートの 4 項目のうち、playwright-kit のテストはこの変更が触らないため実行していない。

未検証の項目:

  • macOS の bash 3.2 での set -m(実機が無い。GNU の配布物 bash-3.2 の doc/bash.1CHANGES で存在と振る舞いを確かめた。成り立たなければグループの先頭でないと判定して pid だけの停止に落ちる)
  • claude の 429 が err.log と stdout.log のどちらに出るか(実物のログが無い。両方を偽の claude で試し、どちらでも理由が usage_limit になる)

既存の失敗: 無し(変更前の全体テスト 4413 件が通ることを先に確かめた)

範囲外と判断したもの:

影響範囲

配布先 変わるか
Claude Code 変わる(共通層の 3 ファイルと cross-review の状態の操作・文書)
Codex 変わる(同じ plugins/ndf/ を配布する)
Kiro CLI 変わる(同上。build-runtime-plugins.sh --check で生成物に差は無い)
agy 変わる(同上)

状態ファイルには結果なしのときだけ monitor_detail の鍵が増える。監視の結果ファイルと監視の記録の reason に 2 値が増える。既存のファイルはそのまま読める(移行なし)。

構造改善

/ndf:cross-refactoring を通した(テスト整備 2 ラウンド + 構造改善 4 ラウンド。上限で終了)。26 項目のうち 14 件を取り込み、7 件を取り消し、5 件が未着手のまま終わった。理由と手順は issues/refactoring-plan-rf791.md にある。

進行は 3 度中断した。1 度目と 2 度目は担当 CLI が結果を残さずに終わり同じ群が開き直された(#647 の形)ため手で止めて担当を差し替え、3 度目は実行環境の再起動で状態ファイルが消えた。再起動後は head で全体テスト(4564 passed / exit=0)を通し、全コミットを改修計画と突き合わせ、取り消しの範囲から漏れて残っていた検証前の 1 コミットを項目単位で戻した(d03916cf)。再開時に前のラウンドの未着手の群を飛ばす形は #792 として残した。

完了判定

head 6acd1b8b に対する検証。作業ツリー .worktrees/feat/issue-729-outcome-vocabulary(受け入れ条件の再実行は head に同期した別の作業ツリー)。監視の環境変数(MONITOR_*)は export していない。合否は終了コードで見た。

段階 コマンド 対象範囲 実行時刻(UTC) 結果
限定的な検証 uv run --with pytest pytest <受け入れ条件が指すテスト> -q 7 ファイル(test_monitor_outcome_unit / test_monitor_usage_limit / test_monitor_outcome_file / test_monitor_early_error / test_read_result_reason / test_judge_no_result_reason / test_launch_cli_process_group 2026-09-19T19:59:32Z〜2026-09-19T19:59:45Z 178 passed / exit=0(7 件とも)
全体テスト uv run --with pytest pytest scripts/tests plugins/ndf -q 全体 2026-09-19T19:57:40Z 4564 passed / exit=0
静的解析・ビルド bash scripts/build-runtime-plugins.sh --check 全体 2026-09-19T19:56:23Z 生成物に差なし / exit=0
静的解析・ビルド python3 scripts/check-skill-frontmatter.py 全体 2026-09-19T19:56:23Z exit=0
静的解析・ビルド claude plugin validate . 全体 2026-09-19T19:56:23Z 警告(未知フィールド)のみ / exit=0
静的解析・ビルド python3 plugins/ndf/scripts/instructions-check.py --root . 全体 2026-09-19T19:56:23Z exit=0
文書の検査 check-doc-line-limit / check-markdown-links / check-doc-staleness / check-cross-skill-refs 全体 2026-09-19T19:58:20Z exit=0(4 件とも)
結合・端から端まで 継続的統合(runtime-smoke の 4 ランタイムを含む必須検査) head 6acd1b8b 20:03 時点で読んだ 16 件すべて SUCCESS

受け入れ条件: 24/24 満たす(AC1〜AC11・AC13〜AC17・AC19〜AC21 は上の 7 ファイル、AC12 は git grep の除外後 0 行、AC18 は文書の表と節の実在、AC22〜AC23 は全体テストと同期・定義の検査、AC24 は SKILL.md の差分 0 行)

未検証の項目:

既存の失敗: なし

範囲外と判断したもの: #792(収束ループを中断から再開すると前のラウンドの未着手の群を飛ばす)。構造改善で取り消しの範囲から 1 コミットが漏れて残った形は、取り込みの取り消しを 1 か所で決める #728(G4)の範囲に入るため起票していない

版を上げる必要があるか

要る。本番の振る舞い(結果なしの理由と起動し直しの判断)が変わる。上げるのはまとまり単位でマージが終わった後で、release の工程が行う。

文書の検査

この本文(構造改善・完了判定の 2 節を足した後の全体)と実装計画に markdown-writing のセルフチェック 6 種を掛けた結果。

検査 PR 本文 実装計画
識別子・略語(表とコードブロックの外、バッククォート無し) 0 件 0 件
検討痕跡・変更履歴 0 件 0 件
強い否定語 1 件(この表自身が引用する節の題名。そのまま残す) 1 件(既存の節の題名「monitor.py が誤って kill する場合の手順」の引用。そのまま残す)
過剰な装飾語 0 件 0 件
根拠の曖昧な断定 0 件 0 件
多義語(5 回以上) 0 件 「タスク」12 回(計画の分解の単位として用語表で定義。一意)

🤖 Generated with Claude Code

takemi-ohama and others added 13 commits September 19, 2026 11:01
設計文書(PR #781)の決定 12 件を 8 つのタスクへ分解する。共通層(語彙・監視・起動)→
cross-review の読む側 → 文書と退行の確認の順に進める。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Task 1。`REASONS` に `usage_limit` / `cli_timeout` / `unparsable` を足し、
`NO_RELAUNCH_REASONS` と `relaunch_same_agent` で起動し直しの可否を 1 か所に持つ。
`read_launch_outcome` は結果ファイルと監視の結果ファイルを突き合わせ、
`LaunchOutcome`(payload / reason / detail / monitor / relaunch_same_agent)を返す。
例外・SystemExit・標準出力/標準エラーへの出力を出さない。

`from __future__ import annotations` は外した。注釈が文字列になると `dataclass` が
`sys.modules` を引き、`importlib` で登録せずに読む既存テストが落ちるため。

受け入れ条件: AC1、AC8〜AC11

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Task 2。`USAGE_LIMIT_FATAL`(kiro の `Monthly request limit reached`、claude の
`"api_error_status":429`、既存の quota / rate limit、HTTP 429)と、claude の
stdout.log 向けの `CLAUDE_STDOUT_USAGE_LIMIT` を新設。`EARLY_ERROR_FATAL` の HTTP 行は
401 / 403 に絞る。照合の順序は利用上限 → 致命 → 警告の見た目の致命で、
`MonitorOutcome.reason` に `usage_limit` を添え、`_record_outcome` は結末の理由を
優先して書く。`_scan_early_fatal` は「止めるべき文言があるか」の契約を保つ
(既存の `test_monitor_early_error.py` を変えずに通す)。

受け入れ条件: AC2〜AC4、AC6、AC7

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Task 3。`CLI_TIMEOUT_AFTER_EXIT`(agy の `print timeout after <時間> with turn in
progress`)を新設。`_process_exit_outcome` は終了して結果ファイルが無いときだけ
err.log を照合し、一致すれば `NO_RESULT` に `reason="cli_timeout"` を添える。
結果ファイルがあれば従来どおり `OK` / `ok`。

受け入れ条件: AC5

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Task 4。`launch-cli.sh` は `launch_runtime` の直前で `set -m`、直後で `set +m` にし、
背景起動した CLI の pid をプロセスグループの番号にする。`monitor._kill_pid` は
pid がグループの先頭で、かつ監視自身のグループでないときだけ `os.killpg`
(SIGTERM → 3 秒 → SIGKILL)を送り、それ以外は従来どおり `os.kill`。
ゾンビの扱いは変えない。

`set -m` は bash 3.2 の bash.1(GNU Bash-3.2、2006-09-28)に
「Monitor mode. Job control is enabled. Background processes run in a separate
process group」と記載があり、macOS の bash 3.2 でも使える。

受け入れ条件: AC19〜AC21

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Task 5(AC13、AC12)。`_read_review_result_file` は結果ファイルを自前で開かず
`monitor_outcome.read_launch_outcome` を呼び、`payload` が無ければ共通の `reason` を
`no_result_reason` に残す。監視の結果ファイルがあれば `monitor_detail` に監視の
`detail` を残す(空なら鍵を書かない)。終了コードは従来どおり `unparsable` が 3、
それ以外は 1。起動の手順・監視・取り込みの stem が同じ形であることをテストで固定する
(設計文書の未確認 6)。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Task 6(AC14〜AC17、AC24)。`_handle_no_result_round` は結果なしの担当ごとの理由を
集めて先に `NO_RESULT_REASONS='<担当>=<理由> ...'` を標準出力へ出す。理由のどれかが
共通層の `relaunch_same_agent` で偽なら、起動し直さずに `final=error` として終了コード 1
で止め、標準エラーに担当・理由・`monitor_detail` を出す。すべて可なら従来どおり
(1 度目は 7 と `RELAUNCH_AGENTS`、2 度目は 1)。報告の表は結果なしの担当を
`<担当>=NO_RESULT(<理由>)` の形で出す。判定の終了コードの分岐は増えず、SKILL.md の
骨組みは変えない。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…書へ載せる(#729 #619 #584)

Task 7。理由の表を 10 語にし(起動し直しの可否の列を足す)、判定が出す
NO_RESULT_REASONS の行と利用上限で止める規則を書く。「monitor.py が誤って
kill する場合の手順」に、監視の結果ファイルと監視の記録から上限を見分ける
表を足す。契約の文書に read_launch_outcome の値と monitor_detail の鍵を書く。
共通層の一覧に read_launch_outcome の責務を足す。

設計文書の「未確認のまま残ること」の 1・3・5・6 を、実装で決めた結果
(偽の claude を両方の形で試した・bash 3.2 の一次資料・照合の順序・stem の
突き合わせのテスト)へ更新する。実装計画の「やらないこと」に #789 を足す。

01-state-and-review.md は 4 つの罠の引用ブロックを同じ内容の表へ組み直し、
500 行の上限内に収めた。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
終了コード0の未認証判定と、UTF-8を含む監視結果の追記順を現状固定テストで覆う。

Item-Id: R1-001
Round: 1
Impl-Runtime: codex
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
compare の 4 分岐(取得失敗・前回記録なし・一致・不一致)の現状の戻り値を
単体テストとして固定する。既存の instructions-check のテストは refresh.fetch を
スタブへ差し替えるため、compare 本体はどこでも通っていなかった。
対象のコードは変更しない。

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

Copy link
Copy Markdown
Contributor Author

構造改善の工程で見つけた範囲外の課題を #792 として残した(収束ループを中断から再開すると、前のラウンドの未着手の群を飛ばして次のラウンドを開く)。

takemi-ohama and others added 15 commits September 19, 2026 12:32
OSError、HTTPError、URLError を opener から発生させ、FetchResult の失敗理由を固定する。

Item-Id: R2-002
Round: 2
Impl-Runtime: codex
Impl-Model: default
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
成功と失敗を混ぜて返す opener を差し替えで用意し、複数の source を渡して
refresh(sources, timeout, opener) を呼ぶ。返る行数が source 数と一致し、
失敗件数が失敗した source 数と一致すること、各行に name と取得の成否が
含まれることを、実行して得た値で固定する。

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

R3-001 (centralize_configuration): monitor_outcome.OUTCOME_KEYS に `phase` を
加えて契約文書の並びと揃え、monitor.py の _record_outcome が組み立てた辞書の
キー集合を OUTCOME_KEYS と突き合わせる assert を置いた。

R3-002 (extract_method): state.py の _handle_no_result_round から、理由の集約と
出力・共通の異常終了処理・再起動対象の記録と互換出力を小さな関数へ抽出した。

R3-004 (consolidate_duplication): monitor.py の monitor_agent で、5 つの終了分岐が
繰り返していた _finish_monitor 呼び出しを局所的な finish 処理へ寄せた。

振る舞いは変えていない(既存テスト 4564 件が通る)。

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

初期化結果という同じ概念を表す 11 個の位置引数を、名前付きフィールドを持つ
_InitResult の値オブジェクト 1 個へ置き換える。連続する 3 個の bool と末尾の
件数・再開フラグは呼び出し側で順序を取り違えても検出しにくかったため、
再開経路と新規初期化経路の両方でキーワード引数から _InitResult を構築する。
標準出力の機械可読ブロックの形式と順序は変えない。

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

検証コマンドの実行と、代表への最良結果の反映をそれぞれ名前付き関数へ抽出する。

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

_resume_from_state に直列で置かれていた段階を名前付き関数へ分離する。

- _find_resumable_state: state ファイルの探索と再開可否(final 済み)の判定
- _refresh_resume_state: 旧形式の補完・manual 指示の反映・review_instructions の
  再計算・carried_over の記録(保存はせず、変更有無だけを返す)
- _sync_resume_worktree: 保存後の auto_flush → tmp_dir 解決 → 登録済み worktree の
  同期を、副作用の順序が見える形で 1 か所へ寄せる

_resume_from_state は各段階の呼び出しと _print_init_result だけになる。
出力・保存順序・副作用の順は不変(全体テスト 4564 passed / exit=0)。

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

_init_new_state に同居していた 5 個のローカル関数
(_resolve_pr_and_ownership / _prepare_review_instructions /
_prepare_worktree_and_comments / _prepare_initial_assignment /
_build_initial_review_state)と _finalize_initial_state をモジュール
レベルへ抽出し、_init_new_state を各段を順に呼ぶオーケストレーション
だけに縮めた。段の入出力は既存の _Init* NamedTuple をそのまま使う。

構造の現状固定テスト(test_init_body_not_duplicated.py)は、
_init_new_state 単体ではなく新規 init 経路を構成する関数群を
まとめて見るよう更新し、「同じ文が 2 回並ばない」「副作用のある
呼び出しは 1 回だけ」という元の意図を保った。

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

This reverts commit f19e31d.
takemi-ohama and others added 21 commits September 19, 2026 13:38
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
…/scripts/state.py#cmd_check_oscillation

一致種別 (exact / near / body) を if/elif で 3 変数に加算していた集計を
collections.Counter への置き換えに直す。重なりの件数は None 以外の値の総和で
出し、表示は counts から読む。あわせて _finding_keys をそのまま呼ぶだけの
collect_keys クロージャを消し、直接呼び出しに戻す。振る舞いは変えない。

Item-Id: R4-003
Round: 4
Impl-Runtime: claude
Impl-Model: default

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s-review/scripts/state.py#cmd_check_oscillation"

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

別名の解決と deferred の正規化を小関数へ抽出し、記録用辞書の組み立てを明確にする。

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

Queue.flush から読み取り済み項目の処理を _flush_item へ抽出、
state.py の _sync_worktree からターゲット解決と同期判定を抽出し、
metrics.py の format_report で unmeasured / assumed 節の生成を _emit_bullet_section へ統合。

Item-Id: R5-001
Round: 5
Impl-Runtime: agy
Impl-Model: default
…e.flush

待ち行列の項目処理結果と worktree 同期判定の入力を構造化し、抽出した処理の責務と受け渡しを明確にする。箇条書き節の共通化も維持する。

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

待ち行列の項目処理結果と worktree 同期判定の入力を構造化し、抽出した処理の責務と受け渡しを明確にする。箇条書き節の共通化も維持する。

Item-Id: R5-001
Round: 5
Impl-Runtime: codex
Impl-Model: default
…cripts/state.py#_load_payload

payload が dict でない経路と comments が list でない経路が、型名の違いだけで
同じ警告(0 件・判定は中断)を出していた。共通の _reject_payload() へ末尾の
定型句を集約し、片方の文言だけが動いて 2 経路が食い違うのを防ぐ。振る舞いは不変。

Item-Id: R5-003
Round: 5
Impl-Runtime: kiro
Impl-Model: default
…review/scripts/state.py#_load_payload"

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

build_parser に連続していた init のオプション定義と 13 個の副コマンド登録を、
副コマンドごとの登録関数 `_add_<name>_parser(sub)` へ抽出する。build_parser は
トップレベル parser と subparsers を作り、`_SUBCOMMAND_REGISTRARS` を元の順で
呼んで返すだけにする。`--help` の一覧は登録順で出るため、順序は変えていない
(トップと 14 副コマンドの `--help` 出力が変更前後で一致することを確認)。

Item-Id: R5-005
Round: 5
Impl-Runtime: claude
Impl-Model: default
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。
状態ファイルは差分から除外されるため、Pull Request から読める場所へ置く。
CLI ごとの認証プローブ処理と、待ち行列項目の解釈・書き戻し先探索を補助関数へ抽出する。

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

This reverts commit bb191de.

ラウンド 5 の適用ラウンド 1(R5-001 / R5-002 / R5-004)の担当が積んだコミット。同じ群に
割り当てのないコミットが混ざったため群ごと取り消したが、取り消しの範囲がそのコミットに
届いておらず、検証を受けていない変更が残っていた。項目単位の取り消しとして戻す。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
再起動で消えた状態ファイルの代わりに、head の全体テストとコミットの突き合わせで確定した
状態を写す。R6-001 / R6-002 は検証を通ったので採用、R5-001 / R5-002 / R5-004 は
残っていた 1 コミットを戻したので取り消し 1 コミット。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@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

利用上限(usage_limit)・CLI の上限(cli_timeout)・結末の共通層(read_launch_outcome)・プロセスグループ停止(set -m + os.killpg)の 4 系統を確認した。理由の語彙(9 語)とパターンの移設(429 と quota/rate limit を EARLY_ERROR_FATAL から USAGE_LIMIT_FATAL へ)は整合し、_MONITOR_DECIDED_REASONS による「payload が勝つ」判定・relaunch_same_agent の可否も設計どおり。主要 5 テスト 145 件を実機で実行し全て通過。auth.py / state.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 1 | agy | APPROVE

設計文書(#729 #619 #584)の受け入れ条件 AC1〜AC24 と実装・テストが整合しており、結末語彙の一元管理、利用上限での即時中断と再起動防止、およびプロセスグループによる子プロセスの停止処理が適切に実装されています。

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