cross-review: 利用上限で止まった担当が「結果ファイル無し」と報告されて空振りの起動し直しで待たされ、止めた担当が後から結果を書く → 上限を理由に報告して同じラウンドで起動し直さず、止めた後は書かせない(#729 #619 #584) - #791
Open
takemi-ohama wants to merge 49 commits into
Open
takemi-ohama wants to merge 49 commits into
takemi-ohama wants to merge 49 commits into
Conversation
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 から読める場所へ置く。
Contributor
Author
|
構造改善の工程で見つけた範囲外の課題を #792 として残した(収束ループを中断から再開すると、前のラウンドの未着手の群を飛ばして次のラウンドを開く)。 |
OSError、HTTPError、URLError を opener から発生させ、FetchResult の失敗理由を固定する。 Item-Id: R2-002 Round: 2 Impl-Runtime: codex Impl-Model: default
This reverts commit 38afae0.
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。 状態ファイルは差分から除外されるため、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.
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。 状態ファイルは差分から除外されるため、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
….py#Queue.flush" This reverts commit 311bf7f.
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。 状態ファイルは差分から除外されるため、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.
….py#Queue.flush" This reverts commit 1e8216f.
なぜ直すのか(理由)とどう直すのか(手順)は提案の時点でしか残らない。 状態ファイルは差分から除外されるため、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
commented
Sep 19, 2026
takemi-ohama
left a comment
Contributor
Author
There was a problem hiding this comment.
🤖 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
commented
Sep 19, 2026
takemi-ohama
marked this pull request as ready for review
September 19, 2026 20:06
11 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
担当の CLI が利用上限で落ちると、監視はその文言を読めず、結果なしの理由は「結果ファイル無し」に畳まれていた。進行側は同じ担当を同じラウンドで起動し直し、監視の上限 1 回分(レビューで 1200 秒)を待ってから全体を誤りで終えていた(#619)。監視が止めた担当の子プロセスが、止めた後に結果ファイルを書くことがあった(#584)。根本原因は、結果なしの判断を cross-review と cross-refactoring がそれぞれ結果ファイルの有無だけで行い、監視が書いた理由を誰も読まないことにある(#729)。
この変更で成り立つこと:
plugins/ndf/scripts/lib/monitor_outcome.py)の 1 か所に置く。起動 1 回の結末を 1 つの値として読む関数(read_launch_outcome)を新設し、cross-review の結果の取り込みはその値を読むだけになる。cross-refactoring の側は契約だけを受け取り、実装は G4(cross-refactoring の取り込みが結果なしを値で受け、群の状態と未検証コミットの取り消しを 1 か所で決める #728)が行うusage_limit)を結末に添える。CLI 自身の上限で結果を書かずに終わった担当は理由「CLI の上限」(cli_timeout)になる。監視の終了コードと標準出力は変えないSKILL.md)の行は 1 つも変わらない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
受け入れ条件と確かめ方
plugins/ndf/scripts/tests/test_monitor_outcome_unit.pyplugins/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は変更せずに通るtest_monitor_outcome_unit.py(監視の結果ファイル × 結果ファイルの組み合わせ、capsysで出力が空)git grep -n 'usage_limit' -- plugins/ndf/skillsの一致は文書とテストだけ。判定のテストに「共通層の集合を差し替えると可否が追随する」検査があるplugins/ndf/skills/cross-review/tests/test_read_result_reason.py(stem 3 か所の突き合わせを含む)plugins/ndf/skills/cross-review/tests/test_judge_no_result_reason.pydocs/01-state-and-review.mdの表とdocs/03-review-output.mdの「上限に当たった場合の見分け方」plugins/ndf/skills/cross-review/tests/test_launch_cli_process_group.py(3 秒後に子が書く偽の CLI)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:cacheproviderbash scripts/build-runtime-plugins.sh --checkpython3 scripts/check-skill-frontmatter.pyclaude plugin validate .policy/interfaceの未知フィールド)のみ / exit=0python3 scripts/check-doc-line-limit.pydocs/01-state-and-review.mdは 500 行)python3 scripts/check-markdown-links.pypython3 scripts/check-doc-staleness.pygit grep -n 'usage_limit' -- plugins/ndf/skillsから/tests/と/docs/を除くgit diff origin/develop -- plugins/ndf/skills/cross-review/SKILL.mdMonthly request limit reachedを書いて終わる偽の kiro を PATH に置き、launch-cli.sh kiro … review→monitor.py 8619 --phase review --agents kiro --poll 1→state.py read-result 8619 kiro→state.py judge 8619reason=usage_limit→ 取り込み exit=1・no_result_reason=usage_limit・monitor_detailあり → 判定 exit=1(7 ではない)・NO_RESULT_REASONS='kiro=usage_limit'・final=error・relaunchedなしlate-result.jsonを書く偽の CLI をlaunch-cli.sh codexで起動し、_kill_pid(pid)の後に 4 秒待つos.getpgid(pid) == pid(起動元とは別のグループ)、結果ファイルは書かれない。対照(止めない)では書かれるチェックボックスの形で書くテンプレートの 4 項目のうち、
playwright-kitのテストはこの変更が触らないため実行していない。未検証の項目:
set -m(実機が無い。GNU の配布物 bash-3.2 のdoc/bash.1とCHANGESで存在と振る舞いを確かめた。成り立たなければグループの先頭でないと判定して pid だけの停止に落ちる)usage_limitになる)既存の失敗: 無し(変更前の全体テスト 4413 件が通ることを先に確かめた)
範囲外と判断したもの:
sys.modulesに登録せずに読む流儀(dataclassとfrom __future__ import annotationsの組み合わせで落ちる)gitfacts.read_result)の置き換えは G4(cross-refactoring の取り込みが結果なしを値で受け、群の状態と未検証コミットの取り消しを 1 か所で決める #728)影響範囲
plugins/ndf/を配布する)build-runtime-plugins.sh --checkで生成物に差は無い)状態ファイルには結果なしのときだけ
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 していない。合否は終了コードで見た。uv run --with pytest pytest <受け入れ条件が指すテスト> -qtest_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)uv run --with pytest pytest scripts/tests plugins/ndf -qbash scripts/build-runtime-plugins.sh --checkpython3 scripts/check-skill-frontmatter.pyclaude plugin validate .python3 plugins/ndf/scripts/instructions-check.py --root .check-doc-line-limit/check-markdown-links/check-doc-staleness/check-cross-skill-refsruntime-smokeの 4 ランタイムを含む必須検査)6acd1b8b受け入れ条件: 24/24 満たす(AC1〜AC11・AC13〜AC17・AC19〜AC21 は上の 7 ファイル、AC12 は
git grepの除外後 0 行、AC18 は文書の表と節の実在、AC22〜AC23 は全体テストと同期・定義の検査、AC24 はSKILL.mdの差分 0 行)未検証の項目:
406d5102)に実行した記録が上の Test plan にあり、再現スクリプトは実行環境の再起動で消えた。同じ経路の自動テスト(利用上限 39 件・プロセスグループ 6 件)は head で通る → リリース後テストで確かめる既存の失敗: なし
範囲外と判断したもの: #792(収束ループを中断から再開すると前のラウンドの未着手の群を飛ばす)。構造改善で取り消しの範囲から 1 コミットが漏れて残った形は、取り込みの取り消しを 1 か所で決める #728(G4)の範囲に入るため起票していない
版を上げる必要があるか
要る。本番の振る舞い(結果なしの理由と起動し直しの判断)が変わる。上げるのはまとまり単位でマージが終わった後で、
releaseの工程が行う。文書の検査
この本文(構造改善・完了判定の 2 節を足した後の全体)と実装計画に
markdown-writingのセルフチェック 6 種を掛けた結果。🤖 Generated with Claude Code