Repository navigation
スプリント m2087 - #2152
スプリント m2087#2152
Conversation
dev.agy/agents の symlink をやめ、scripts/lib/agy_agents.py が plugins/ndf/agents/*.md から frontmatter の model: の 1 行だけを対応表(sonnet→flash・opus→pro)で置き換えた写しを生成する。 --check は足りない・古い・余った写しと symlink を示して落ちる。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
normal の promote は承認ゲート 2 で止まるときに昇格の PR の先端を「承認したコミット」として 承認資料と metrics.approved_sha に載せる。promote-approved は --approved-from の資料の SHA と 先端を照合し、違えば head_moved で止まって承認ゲート 2 からのやり直しを next に示す。 資料を読めないときと、--gate-approved user に資料が無いときは gh を呼ばずに 2 で止まる。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s.py を 500 行に収める(#2104) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
正本の agents/*.md を直し、dev.agy/agents の写しを生成し直した。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2087 を実装する(スプリント m2087)
#2104 を実装する(スプリント m2087)
--expect-head-from の help とモジュールの docstring に、照合が食い違うか読めないときに プランの handoff が承認ゲート 2 へ戻し、--from verify から流し直すことを足した。 導入の確認の資料の SHA が 40 桁でないときの文言は、その資料の確かめたコミットを指す。 parse_sha の既定の文言(承認したコミット)は変えない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2142 を実装する(スプリント m2087)
Item-Id: I-005 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…reenWatch.poll poll から PR の状態の検査(_inspect_pr)・失敗と基盤待ちの処理(_handle_failures)・ チェックの進み具合の分類(_classify_progress)・締め切りの判定(_check_deadline)を抜き出し、 poll を手順の呼び出しの並びへ縮めた。振る舞いは変えない。 Item-Id: I-001 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…_templates.py#plan_promote normal 経路の steps を _promote_steps_normal へ、fast / auto 経路の steps を _promote_steps_mvv へ抜き出し、plan_promote は本番チャネルの解決と共通ステップの用意の後に どちらかを呼ぶ形へ縮めた。生成するプランは変えない。 Item-Id: I-002 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
写しの組み立て(_expected_copies)・--check の照合(_check_copies)・書き出し(_write_copies)を 抜き出し、sync は対応表の検査の後にそれらを呼ぶだけにした。標準エラーの文言と戻り値は変えない。 Item-Id: I-003 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
frontmatter_model と agy_copy が別々に持っていた frontmatter の走査(先頭と終わりの区切り・ 最初の model: 行)を _model_line_index へまとめ、両方がそれを使う形にした。 splitlines(keepends=True) でも区切りと model: の判定は変わらない。 Item-Id: I-005 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…up_pr PR 情報の取得と MERGED の判定を _merged_pr_info へ、作業ツリーの走査と除去を _remove_pr_worktrees へ抽出し、_cleanup_pr を「情報の取得 → 作業ツリーの除去 → ブランチの削除 → 一時作業ツリーの除去」の並びへ縮めた。 Item-Id: I-004 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es.py#plan_promote fast / auto の昇格の手順(_promote_steps_mvv)に残っていた `material = PROMOTE_MATERIAL` の別名を消し、prepare の cmd と mvv_gate_steps の --material で定数を直接使う。 Item-Id: I-006 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#record_approval 資料の存在の検査と本文の読み取りを _read_material へ抽出して _cells と verified_sha で 共有し、rows から欄を取り出す _material_sha_of・_recorded_sha_of を抽出した。 record_approval と from_material は _cells を 1 度だけ呼び、rows を使い回す。 Item-Id: I-007 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s.py#cmd_probe 分類ごとの (手, 要約のテンプレート) をモジュール先頭の PROBE_TABLE へ寄せ、 PROBE_CLASSES・PROBE_ACTIONS は対応表から導出する。cmd_probe には names と queued_runs を埋める部分と、stale を直したときの要約の選択だけを残した。 Item-Id: I-008 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
抽出した _merged_pr_info で merged-steps.py が 500 行を超えたため、 merged_lib/pr_info.py の merged_pr_info へ移した(本体は変えない)。 Item-Id: I-004 Impl-Runtime: claude Impl-Model: default
merged-steps.py が 500 行を超えたため、cmd_probe の分類の対応表 (PROBE_TABLE・PROBE_REMEDIED_SUMMARY と、それから導く PROBE_CLASSES・PROBE_ACTIONS)を merged_lib/probe_table.py へ移した(値は変えない)。 Item-Id: I-008 Impl-Runtime: claude Impl-Model: default
GreenWatch._stop_conflict を stop_conflict へ改名する。merge.py の _merge_pr が モジュールの外から呼ぶため、公開の操作として名前を揃える。振る舞いは変えない。 Item-Id: I-009 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…omote --expect-head-from と --approved-from で同じ形だった「資料から SHA を読み a.expect_head へ入れ、 ValueError を StepError(EXIT_UNREADABLE) に包む」を _pin_expect_head へ抽出する。 メッセージと終了コードは変えない。 Item-Id: I-010 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…promote promote が argparse の Namespace へ moved_next を後から生やし、GreenWatch が getattr で読んでいた 隠れた経路を、merge_when_green と GreenWatch の明示の引数 moved_next に置き換える。 head_moved の next に載る値は変えない。 Item-Id: I-011 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ise_pace.py#sprint_state test_supervise_pace.py と test_supervise_pace_auto.py が同じ手順で持っていたスプリントの状態の作成 (MVV の素材・sprint-state.py init・MVV の承認)を tests/pace_state.py の sprint_state へ抽出した。 違いだった pace は引数で渡し、両ファイルの呼び出しは "fast" / "auto" を明示する。 Item-Id: I-012 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
result.data の欠落・応答前の終了・stderr の末尾の添付・送る要求と出力の書式・ --cwd の既定値・応答後も残る app-server の停止を、app-server のスタブで固定する。 Item-Id: I-014 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y#main 応答の 1 行を読んで対象 ID かを判定する parse_hooks_list_response、error と result.data を確かめる extract_result、応答待ちの wait_for_hooks_list を main から抽出する。main は引数解析・起動・要求の送信・出力・終了処理を担う。 受信ログの扱い・診断・期限・終了コードは変えない。 Item-Id: I-014 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lib/delivery_templates.py#plan_promote 昇格のプランに固有の入力(mvv・production・verify)を PromoteParams にまとめ、 plan_promote の引数を 7 個から 5 個にした。呼び出し元(sprint_routes.route_waves)と テストの呼び出しを書き換えた。a / repo / condition は他の配布のプラン (plan_verify・plan_gate_2)と共通の引数なので、まとめずに残した。 Item-Id: I-013 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt_state 共通ヘルパー sprint_state が pace を必須の引数に取るようになったため、test_supervise_pace_auto から読み込む呼び手(test_supervise_pace_verify・test_supervise_pace_manual・test_sprint_inputs)に "auto"、test_supervise_pace から読み込む test_supervise_close_auto に "fast" を明示して渡す。 各呼び手が受けていた pace は抽出前と同じである。 Item-Id: I-012 Impl-Runtime: claude Impl-Model: default
改修計画 — devbasex/ai-plugins #2152
改善項目I-001 —
|
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | major | high | claude / codex / kiro | 採用 | 1 |
なぜ: 1 回の読み直しに、PR の状態の判定(MERGED/OPEN 外/draft/DIRTY)・SHA の更新・チェックの読み取り・失敗/基盤待ちの停止・pending/passed/empty/green の 4 系統の分岐・締め切りの判定が同居し、認知的複雑度 35・CC 17・分岐 17・74 行。読んだ中身を評価する部分(green/pending/empty の分類)と、止める/待つの判定が 1 本の流れに混ざっている
手順: 1. 先頭の PR 状態の検査(MERGED・非 OPEN・on_open フック・draft・DIRTY)を _inspect_pr(info) -> sha|emit として抽出し、poll からはそれを呼ぶ
2. reading を読んだ後の失敗/基盤待ちの処理を _handle_failures(reading) として抽出
3. pending/passed/empty/green の 4 分岐を _classify_progress(sha, reading) -> ("done",reason)|("wait",None) として抽出し、戻り値で poll の分岐を 1 段浅くする
4. 締め切りの判定を _check_deadline(reading, pending, passed) として抽出
5. poll 本体は手順の呼び出しの並びに縮める。test_merged_checks_fold.py / test_merged_probe.py を 1 手ごとに実行して退行が無いことを確認
I-002 — plugins/ndf/scripts/supervise_lib/delivery_templates.py#plan_promote
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | major | high | claude / codex / kiro | 採用 | 1 |
なぜ: 99 行・引数 7 個の 1 関数に、本番チャネルの解決・共通ステップ(approved / record)の組み立て・normal 経路の steps・fast/auto 経路の steps(verify/prepare/mvv/note/promote)が同居する。normal と fast/auto は別の理由で変わる 2 つの計画で、promote ステップの dict 構築がほぼ重複している
手順: 1. normal 経路の steps を _promote_steps_normal(promote, wait, timeout, material, approved, record) として抽出
2. fast/auto 経路の steps を _promote_steps_mvv(a, repo, promote, wait, timeout, verify, mvv, approved, record) として抽出
3. plan_promote は本番チャネルの解決と approved/record の用意を行い、mvv の有無で 2 つの抽出関数のどちらかを呼ぶ形へ縮める。test_supervise_new.py::test_plan_promote_with_mvv_judges_before_merging と test_supervise_pace_verify.py を 1 手ごとに実行
I-003 — scripts/lib/agy_agents.py#sync
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | major | high | claude / codex / kiro | 採用 | 1 |
なぜ: 1 関数に、対応表の検査・ソースから expected の構築・check モードの照合・書き込みモードの出力が同居し、認知的複雑度 30・CC 18・分岐 15・61 行。check と write という別の理由で変わる 2 つの出力経路が ok フラグと早期 return で絡み合う
手順: 1. 写しの組み立て(sources の走査と UnknownModel の報告)を _expected_copies(source_dir, out_dir, model_map, rel) -> dict | None として抽出
2. --check の分岐(symlink の拒否・missing / out of date / stale の報告)を _check_copies(out_dir, expected, rel) -> bool として抽出
3. 書き出しの分岐(symlink を外す・書く・余りを消す)を _write_copies(out_dir, expected) として抽出
4. sync は map_errors → _expected_copies → check なら _check_copies、でなければ _write_copies を呼ぶだけにする
5. scripts/tests/test_agy_agents.py を流し、stderr の文言と終了コードが変わらないことを確かめる
I-004 — plugins/ndf/scripts/merged-steps.py#_cleanup_pr
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | minor | medium | claude / kiro | 採用 | 2 |
なぜ: PR 1 件の片付けに、gh pr view の実行と出力の解析・MERGED でない/読めないときの早期 return・作業ツリーの走査と除去・ブランチの削除・一時作業ツリーの除去が同居し、認知的複雑度 14・CC 9・分岐 8・34 行。PR 情報の取得と、取得後の片付けの手順が 1 本に混ざる
手順: 1. gh pr view の実行と JSON 解析、MERGED 判定を _merged_pr_info(root, n, add) -> (branch, merge_commit)|None として抽出(None なら呼び出し元は return)
2. 作業ツリーの走査と除去を _remove_pr_worktrees(root, main_dir, branch, merge_commit, add) -> branch_free として抽出
3. _cleanup_pr は「情報の取得 → 作業ツリーの除去 → ブランチの削除 → 一時作業ツリーの除去」の並びへ縮める。test_merged_probe.py など cleanup を通すテストを 1 手ごとに実行
I-005 — scripts/lib/agy_agents.py#agy_copy
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| duplication | consolidate_duplication | minor | medium | claude / codex | 採用 | 2 |
なぜ: frontmatter_model と agy_copy が、先頭の区切り・終了の区切り・最初の model: 行を探す同じ走査規則を別々に持つ。読み取りと生成で同じ変更を二重に行う必要がある。生成物である dev.agy/agents/*.md の本文の重複は対象にしない。
手順: 1. 行の列から frontmatter 内の model: 行の添字(無ければ None)を返す _model_line_index(lines) を抽出
2. frontmatter_model は splitlines() の結果に _model_line_index を当て、model_value を返す形にする
3. agy_copy は splitlines(keepends=True) の結果に _model_line_index を当て、その行だけを置き換える形にする(keepends の有無で line.strip() == '---' の判定が変わらないことを確かめる)
4. test_agy_agents.py を流す
I-006 — plugins/ndf/scripts/supervise_lib/delivery_templates.py#plan_promote
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| dead_code | inline | minor | medium | claude | 採用 | 1 |
なぜ: #2104 で PROMOTE_MATERIAL を定数へ上げた後も、fast / auto の枝に material = PROMOTE_MATERIAL の別名が残り、同じ値を 2 つの名前で呼んでいる(normal の枝は定数を直接使う)
手順: 1. material = PROMOTE_MATERIAL の行を消し、prepare の cmd と mvv_gate_steps の --material を PROMOTE_MATERIAL へ置き換える
2. プランの契約のテストを流す
I-007 — plugins/ndf/scripts/lib/approved_commit.py#record_approval
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| duplication | extract_method | minor | medium | claude | 採用 | 1 |
なぜ: record_approval は material_sha(中で _cells を読む)の後にもう 1 度 _cells を呼び、from_material も material_sha と recorded_sha でファイルを 2 回読む。資料が無いときの検査(is_file と ValueError)も _cells と verified_sha で同じ形を 2 回書いている
手順: 1. 資料の存在を確かめて本文を返す _read_material(path, what) を抽出し、_cells と verified_sha の is_file の検査を置き換える(文言は what で今と同じにする)
2. rows から承認したコミットを取り出す _material_sha_of(rows, path) を抽出し、material_sha はそれを呼ぶ形にする
3. record_approval と from_material は _cells を 1 度だけ呼び、rows を使い回す
4. test_release_steps.py などの承認資料の読み書きのテストを流す
I-008 — plugins/ndf/scripts/merged-steps.py#cmd_probe
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| scattered_config | replace_with_lookup_table | minor | medium | kiro | 採用 | 2 |
なぜ: 分類(PROBE_CLASSES)ごとの要約文が cmd_probe の中の dict リテラルに埋め込まれ、PROBE_CLASSES・PROBE_ACTIONS という同じキー集合がモジュール先頭に別に定義されている。分類の種類を足すと 3 か所(classes・actions・summary)を同時に直す必要がある
手順: 1. 分類ごとの (action, summary テンプレート) をモジュール先頭の 1 つの対応表へ寄せる
2. summary に queued_runs / names を埋める部分だけ呼び出し側に残す
3. PROBE_CLASSES / PROBE_ACTIONS を対応表から導出し、定義の重複を無くす。test_merged_probe.py を実行
I-009 — plugins/ndf/scripts/merged_lib/merge.py#_merge_pr
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| feature_envy | rename | minor | medium | claude | 採用 | 1 |
なぜ: merge.py の _merge_pr が別モジュールの GreenWatch の非公開メソッド _stop_conflict を直接呼ぶ。名前が「内部専用」を示すのに、モジュールの外の呼び手がいる
手順: 1. GreenWatch._stop_conflict を stop_conflict へ改名(公開の操作として扱う)
2. checks.py の内部の呼び出しと merge.py の _merge_pr の呼び出しを書き換える
3. tests 配下に _stop_conflict を参照する箇所があれば合わせて直し、merge-when-green の衝突のテストを流す
I-010 — plugins/ndf/scripts/merged_lib/merge.py#promote
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| duplication | extract_method | minor | medium | claude | 採用 | 1 |
なぜ: --expect-head-from と --approved-from の 2 つで「資料から SHA を読み a.expect_head へ入れ、ValueError なら StepError(..., EXIT_UNREADABLE) に包む」を同じ形で 2 回書いている。照合の材料が 3 つ目に増えるたびに同じ try/except が増える
手順: 1. _pin_expect_head(a, reader, path, what) を抽出(reader は approved_commit.verified_sha か material_sha、what は「確かめたコミット」「承認したコミット」)
2. promote の 2 つの try/except をこの呼び出しに置き換える
3. test_sprint_close_merge_green.py の promote の照合のテスト(--expect-head-from / --approved-from が読めない・食い違う)を流し、終了コードと stderr が変わらないことを確かめる
I-011 — plugins/ndf/scripts/merged_lib/merge.py#promote
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| hidden_dependency | change_signature | minor | medium | claude | 採用 | 1 |
なぜ: promote が argparse の Namespace へ moved_next を後から生やし、checks.py の GreenWatch._check_expected が getattr(self.a, 'moved_next', None) で読む。引数に現れない経路で 2 モジュールがつながり、merge-when-green 側からは存在が見えない
手順: 1. merge_when_green に moved_next=None の引数を足し、GreenWatch(root, a, moved_next=...) へ明示的に渡す
2. GreenWatch.init で self.moved_next を持ち、_check_expected は self.moved_next を next に載せる
3. promote は a.moved_next を代入せず、merge_when_green(..., moved_next=...) で渡す
4. checks.py の docstring の「a.moved_next」を新しい引数名へ直す
5. head_moved の next を確かめる既存テスト(test_sprint_close_merge_green.py)を流す
I-012 — plugins/ndf/scripts/tests/test_supervise_pace.py#sprint_state
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| duplication | extract_test_helper | minor | medium | codex | 採用 | 2 |
なぜ: test_supervise_pace_auto.py の sprint_state と、MVV素材作成・状態初期化・任意の承認記録まで同じ手順を重複して持つ。実質的な違いは init に渡す pace の値だけで、承認状態の作り方が変わる際に両方の修正が必要になる。
手順: 1. 両関数のコマンドと環境、ファイル名、approve=False の扱いが同じであることを確認する
2. plugins/ndf/scripts/tests 配下の共通ヘルパーへ、tmp_path・pace・approve を受ける状態作成処理を抽出する
3. 両テストファイルの呼出しを明示的な fast/auto 引数付きの共通ヘルパー呼出しへ変更する。片方の test_*.py を他方から import しない
4. 両ファイルのテストを実行し、承認済みと未承認のケースの意味が維持されていることを確かめる。
レビューで確かめるテストの差分: plugins/ndf/scripts/tests/pace_state.py, plugins/ndf/scripts/tests/test_supervise_pace.py, plugins/ndf/scripts/tests/test_supervise_pace_auto.py(機械で期待値が変わったか決まらなかった)
I-013 — plugins/ndf/scripts/supervise_lib/delivery_templates.py#plan_promote
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_parameter_list | introduce_parameter_object | minor | low | kiro | 採用 | 1 |
なぜ: 引数が 7 個(a, repo, ci_wait, mvv, condition, production, verify)あり、plan_verify・plan_gate_2 と a/repo/condition/verify/mvv が繰り返し一緒に渡る。配布のプランの入力が毎回同じ組で流れている(data_clump)
手順: 1. a/repo/condition と、配布に固有の verify/mvv/production を 1 つの小さな値(dataclass PromoteParams)にまとめる
2. plan_promote の呼び出し元(sprint_routes)を 1 手で書き換え、既存の位置引数を崩さない範囲でキーワード化する
3. test_supervise_new.py / test_supervise_pace_verify.py を実行して引数の受け渡しが変わっていないことを確認。影響範囲が呼び出し元へ広がるため、効果(引数列の短縮)が見積りの行数に見合うかを適用者が判断する
レビューで確かめるテストの差分: plugins/ndf/scripts/tests/test_supervise_new.py, plugins/ndf/scripts/tests/test_supervise_pace_verify.py(機械で期待値が変わったか決まらなかった)
レビューで確かめる呼び手の書き換え: plugins/ndf/scripts/supervise_lib/sprint_routes.py(範囲の外の既存のファイル。機械が呼び手の書き換えと判定した)
I-014 — tests/runtime-smoke/lib/codex-hooks-list.py#main
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | major | low | codex | 採用 | 2 |
なぜ: CLI引数、app-server起動、スレッドとキュー、JSON応答の選別と検証、期限切れ、終了処理が1関数に混在する。既存の現状固定テストはエラー応答とノイズ行からの正常応答を通すが、EOF・result.data欠落・期限切れの経路を固定していない。
手順: 1. tests/runtime-smoke/fixtures/hooks-positive-control/assert-characterization.sh に、result.data欠落と応答前終了のスタブを加えて、現在の終了コード・標準出力・診断を固定する。期限切れは短い時計を渡せる境界を作る前後で現在の条件を固定する
2. 行をJSONとして読み、対象IDかを判定し、result/errorを取り出す処理を同じファイル内のヘルパーへ抽出する。対象外行を読み飛ばす扱いと受信ログを保つ
3. 応答待ちを独立した関数へ抽出し、必要ならプロセスと受信状態をまとめて渡して引数を4個以下にする。main は引数解析・起動・呼出し・finallyの終了処理を担う
4. tests/runtime-smoke/test_hook_definitions_characterization.py を実行し、要求の送信順、出力JSON、終了コード、タイムアウト境界、kill/wait の実行が変わらないことを確認する。
レビューで確かめるテストの差分: tests/runtime-smoke/lib/codex-hooks-list.py(機械で期待値が変わったか決まらなかった)
指標の測定
- 状態: written / 言語とツールの対応: 既定(.ndf/code-metrics.json は無い) / 所要: 31.5 秒(使えた時間 270 秒 / 上限 270 秒)
- 指標のファイル: /tmp/ndf-worktrees/devbasex--ai-plugins/rf2152/work/.cross_refactoring/code-metrics-rf2152.md
| 言語 | ツール | 版 | ランナー | ファイル | 秒 | 結果 |
|---|---|---|---|---|---|---|
| python | ruff-complexipy | ruff 0.16.9 / complexipy 8.0.1 | uvx | 255 | 1.2 | 測った |
| shell | — | — | — | 14 | — | unsupported_language |
| 重複: python | symilar | pylint 4.0.9 | uvx | 255 | 25.5 | 測った(3 箇所) |
| 重複: shell | jscpd | jscpd 4.3.0 | npx | 14 | 4.0 | 測った(0 箇所) |
時間の上限
| 値 | 中身 |
|---|---|
| 提案の枠の終わり(監視の上限 = 残り + 余裕) | 2026-10-29T12:48:03+00:00 |
| 改修計画の枠の終わり(同上) | 2026-10-29T12:57:03+00:00 |
| テストの追加の終わり = 実装の終わり − Σ(採っていて未検証の項目の実装の見積り) | 2026-10-29T13:19:57+00:00 |
| 実装の終わり = 最終ゲートの修正の打ち切り − バッファ − Σ(採っていて未検証の項目の検証の見積り) | 2026-10-29T13:21:15+00:00 |
| 直しの試行の打ち切り | 2026-10-29T13:35:01+00:00 |
| 想定最大時間の終わり H(子プロセスはすべてここまでに止まる) | 2026-10-29T13:50:47+00:00 |
| 確かめの開始の締め切り = H − 確かめの見込み(最終ゲート修正と打ち切りの後の取り消しもここまで) | 2026-10-29T13:40:31+00:00 |
| 確かめの見込み(秒。最終ゲートの確かめ 1 回。バッファの最終ゲートの全体テスト) | 616 |
| 最終ゲート修正 1 回の見込み(秒。バッファの final_fix。起動は今 + この値が確かめの開始の締め切り以前のときだけ) | 330 |
| 指標の測定の上限(秒。提案の枠の中から割く) | 270 |
| 着手前のテスト 1 回の上限(秒) | 1602 |
| 範囲テスト 1 回の上限(秒) | 1487 |
| 手元の全体テスト 1 回の上限(秒) | 3339 |
| CI の待ちの上限(秒) | 1848 |
| 余裕(秒。手順の上限と CLI の上限に足す) | 270 |
入力: 予算 90 分 / 全体テストの所要 w 1113.0(ci-steps) / 着手前の実測 x 495.5 / CI の壁時計 c 616.0 / 範囲テストの所要 s 533.9(history) / 戦略 local-scoped-ci-whole
無音の打ち切りは手順の監視の上限と同じ値である。項目ごとの期限は持たない(実装を止めるのは実装の終わりだけ)。
見送った提案
| 対象 | 兆候 | 理由 | 根拠(MVV) | 補足 |
|---|---|---|---|---|
plugins/ndf/scripts/lib/approved_commit.py#compare_approved |
long_method | budget | Value 10 / Value 6 | 見積り 9.6 分が残りに入らない |
plugins/ndf/scripts/merged_lib/checks.py#InfraWatch.step |
long_method | budget | Value 10 / Value 6 | 見積り 9.6 分が残りに入らない |
plugins/ndf/scripts/merged_lib/merge.py#_merge_pr |
long_parameter_list | budget | Value 10 / Value 1 / Value 6 | 見積り 9.6 分が残りに入らない |
plugins/ndf/scripts/merged_lib/merge.py#gate_stop |
long_method | budget | Value 10 / Value 6 | 見積り 9.6 分が残りに入らない |
plugins/ndf/scripts/merged_lib/merge.py#gate_stop |
long_parameter_list | budget | Value 10 / Value 6 | 見積り 9.6 分が残りに入らない |
plugins/ndf/scripts/tests/test_supervise.py#test_new_sprint_writes_waves_in_order |
deep_nesting | budget | Value 10 / Value 6 | 見積り 9.6 分が残りに入らない |
plugins/ndf/scripts/lib/approved_commit.py#_outside_to_tip |
one_by_one_iteration | budget | Value 3 / Value 10 / Value 1 | 見積り 12.3 分が残りに入らない |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | APPROVE
指定範囲47ファイルを確認し、critical/majorに該当する修正指摘はありません。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | kiro | APPROVE
47 ファイル(refactoring のコミット群と、範囲に含まれる既マージの #2104 / #2087 / #2142 の機能コミット)を確認した。critical / major の基準に当たる指摘は無い。checks.py#poll の抽出(_inspect_pr → _reset_on_new_sha → _note → _handle_failures → _classify_progress → _check_deadline)は元の順序と self.items の in-place 更新を保ち、recheck=False → _check_expected の順も維持している。cmd_probe の PROBE_TABLE 化(stale の remedied 分岐と .format(names, queued_runs) の扱い)、_cleanup_pr の merged_pr_info/_remove_pr_worktrees への分割、agy_copy の _model_line_index 共通化(splitlines と keepends=True・CRLF・行末保持)はいずれも振る舞いを保ち、現状固定テストと 2 件の『検証の失敗を直す』コミットで裏付けられている。本番マージの gate を触る #2104(--approved-from 必須化・moved_next・gate_head)は AC1-AC8 / I1-I7 の網羅テストがあり、merge-when-green 側の moved_next 既定は None で従来どおり。dev.agy/agents の symlink→生成写しの変更に伴う生存参照(build/validate/smoke/docs)も更新済みで、残る旧参照は issues/ の時点記録のみ。
🔧 /ndf:fix サマリ | commit (なし)対応件数: critical=0 / major=0 / minor=0(合計 0 件) |
スプリント m2087 の課題を develop へ取り込む。
利用者向けの変化
plugins/ndf/dev.agy/agents/)では、modelに tier 名が入ります(#2087 を実装する(スプリント m2087) #2149)plugins/ndf/dev.agy/agents/は生成された写しです。内容を変えるときは元のエージェント定義を直し、ビルドで作り直します(#2087 を実装する(スプリント m2087) #2149)--approved-fromで渡す(#2104 を実装する(スプリント m2087) #2150)移行の手順
課題と設計
コミット
変更の統計
テスト(supervise.py の run のステップ)
集めた実装の PR
閉じる課題
Closes #2087
Closes #2104
Closes #2142
手動確認
runtime-plugin-smoke-latest.ymlの agy の行を見る(受け入れ条件 9)。agy 1.4 系の手元でagy plugin installの後にagy plugin listでエージェントが 11 本あることを見るpace: normalの承認ゲート 2 を 1 度通し、承認資料に先端の SHA が載ることと、承認の後にマージされた先端がその SHA であることを見る(リリース後テストで確かめる)モード: standard / 通した工程: 実装 → Pull Request
🤖 Generated with Claude Code