Repository navigation
スプリント m26-3 - #2348
スプリント m26-3#2348
Conversation
- sprint_close_lib/record_find.py を新設。まとめの課題を閉じる PR とそれを参照する PR から、
段階が本番か配布なしで、スプリント: が閉じる PR を含むリリース記録の PR を 1 本決める。
2 つ以上のスプリントにあれば特定できないとして採らない
- queue_fill が {queue_record} を埋め、見つからなければ計画を書き換えずに流さない(unfilled)。
plan.QUEUE_NAMED に {queue_record} を足し、run でも残れば止まる
- sprint_routes.record_pr_ref は unknown を組まず、merge・手で届ける・検証の環境だけ・
手動反映の本番系と開発ループのまとめで {queue_record} を返す。雛形と昇格は今のまま
- 開発ループの承認ゲート 2 の後のまとめへ values.pr を渡さない。差し込みを埋められずに
流さなかった計画のある周回は失敗で締める
- dist_record.released を足し、sprint-close.py と共有する(振る舞いは変えない)
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>
#2230 を実装する(スプリント m26-3)
版の判定を lib/release_version.py に置き、bump は書き換える前に origin のベースブランチの版と タグを読む。ベースブランチの版以下・既にタグのある正式版は終了コード 3、読めなければ 2 で止める。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
new sprint / new close の --version・--prod を任意にし、--level を足す。雛形は版が無ければ
{release_version}・{release_base} を書き、プランへ「版」の欄を置く。bump は 2・3 で judge を通らずに止める。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
開発版は origin から次に空いている版を決め、記録の版が自分の配布の前に別のスプリントに出ていれば 決め直す。本番は開発版の記録の base で出し、タグがあれば止める。埋められなければ項目の version に理由を載せる。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bump は自分の作業場所の位置を渡す。キューの差し込みを通すテストは差し込みを差し替え、 origin を読む bump のテストは bare の origin を用意する。 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>
#2164 を実装する(スプリント m26-3)
…_sprint manifest のステージ配列から queue と pipeline の文字列を組む部分を sprint_pipeline として抽出した。 手で行うステージの有無による 2 つの経路の文字列を現状固定テストで固定した。 Item-Id: I-001 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d_find.py#find_record 閉じる PR の収集(_closers_of)・候補の展開(_candidates)・記録の読み取りと振り分け(_released_records)を それぞれ抽出し、find_record には順に呼ぶ流れと RecordHit の組み立てだけを残した。 Item-Id: I-002 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…/release_templates.py#release_version_of 開発版から接尾辞を外す正規表現が release_version_of と sprint.prod_version に別々に書かれていたため、 release_templates に strip_suffix を 1 つ置いて両方から呼ぶ形にした。versions.release_base(semver)は 形の違う版で例外を投げ、ビルドメタデータも落とすため振る舞いが変わるので使わない。 sprint.py で使われなくなった re の import を消した。 Item-Id: I-003 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
抽出した sprint_pipeline でファイルが 500 行を超えたため、wait_lap と同じ sprint_loop_gate.py へ移し、sprint_loop.py からは読み込んで使う(sl.sprint_pipeline の参照は変わらない)。 Item-Id: I-001 Impl-Runtime: claude Impl-Model: default
…ind_record 抽出した _candidates が backlog-refinement の upkeep_rank.py の同名関数と衝突したため、_record_candidates へ改名した。 Item-Id: I-002 Impl-Runtime: claude Impl-Model: default
Item-Id: I-004 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e2_answer 承認と差し戻しの時系列から最新の答えを選ぶ部分を latest_gate2_answer(gates, rejections, since) として 抽出した。gate2_answer には状態ファイルと差し戻しログを読み、同じ周回・関門 2 の差し戻しに絞る部分だけを残す。 fresh と EPOCH の規則、同じ時刻は承認を採る順序、JsonReadError を空とする扱いはそのまま。 Item-Id: I-004 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ng_blocker kept_all を段階的に上書きする if/elif 連鎖を、配布の段階から閉じられない理由を返す _stage_blocker と、 リリース後テストの記録から (理由, verdicts) を返す _verify_verdicts に分けた。_closing_blocker は _stage_blocker → (理由が無く、リリース後テストを見るとき) _verify_verdicts の 2 段だけにした。 Item-Id: I-005 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ue_fill.py#_fill_dev 記録がある開発版の確かめ直し(出ているか → 自分の配布か → 明示か → 決め直し)を _recheck_dev へ抽出し、早期 return で入れ子を平らにした。_fill_dev は記録の有無で 2 つの経路を選ぶだけになる。振る舞いは変えない。 Item-Id: I-006 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
タグの無い正式版がベースブランチの版以下のときに終了コード 3 で止め、次に空いている版を ベースブランチの次のパッチとする経路を固定する(既存テストが通っていなかった経路)。 Item-Id: I-007 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on.py#bump_check old == new のときの打ち直しの判定を _rerun へ、止めるときの既に出ている版と次に空いている 版の組み立てを _taken_stop へ抽出した。bump_check は形の検査 → 観測 → 打ち直し → 書き換えてよいかの判定 → 止める理由の直線になる。振る舞いは変えない。 Item-Id: I-007 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…_sprint まとめの queue のコマンドの組み立て(gate2_pipeline・sprint_pipeline・continuation の 3 か所)を sprint_loop_gate.queue_command へ抽出し、--max 3 を QUEUE_MAX にまとめた。 止まった記録を stops へ移して running に戻す 2 行(resume_stopped と cmd_sprint)を resume_record へ抽出した。出力の文字列は変わらない。 Item-Id: I-008 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…elease 開発版の PR の使い回し・作成とマージを _merge_release_pr へ、本番の PR の作成と承認した先端を 指定したマージの再試行(HEAD_MOVED_RETRIES・承認ゲートでの停止)を _merge_prod_pr へ抽出した。 cmd_release は前提検査・push・各段階の呼び出し・タグ公開・結果の組み立てを担う。 副作用の順序と出力は変わらない。 Item-Id: I-009 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
抽出でファイルが 1266 行になり、構造検査の例外リストの上限(1252 行)を超えた。振る舞いを変えずに 行数を詰めた: 本番の PR の題・本文を変数へ置いて create_pr の呼び出しを 1 行にし、抽出先の docstring を 短くし、ver の一時変数と cmd_release の空行を外し、マージコミットの補完を `or` にした(git は merge が空のときだけ呼ばれる点は同じ)。1251 行。 Item-Id: I-009 Impl-Runtime: claude Impl-Model: default
…#cmd_queue then からステージの並びとすべてのプランを作る部分を _normalize_stages へ、 宣言の読み取り・done の初期化・知らせ始める位置と前の一覧の読み取りを _prepare_queue へ抜き出した。cmd_queue は正規化 → 準備 → 起動 → 待ちの流れになる。 durable の import は本体に残す。 Item-Id: I-010 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Item-Id: I-011 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…loop.py#resume_stopped 止まった理由ごとの再開の振る舞いを if-elif の連鎖から、理由ごとの手続き(_resume_mvv_changed / _resume_user_stop / _resume_budget / _resume_gate2 / _resume_refused)と対応表へ移した。 手続きは (止まったままの結果 or None, 次のコマンド) を返す共通の形にそろえ、budget_* は接頭辞で引く。 resume_stopped は対応表を引いて手続きを呼び、再開の共通の後処理だけを持つ。振る舞いは変えない。 Item-Id: I-011 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
対応表への置き換えで sprint_loop.py が 541 行になり、構造検査(500 行)を超えた。 承認ゲート 2 の答えの読み取りと承認後の続き(EPOCH / gate2_answer / latest_gate2_answer / gate2_pipeline)を新しいモジュール sprint_loop_gate2.py へ移し、sprint_loop から読み込む。 再開の手続きは sprint_loop の名前空間の gate2_answer / gate2_pipeline を引くままで、振る舞いは変えない。 使われなくなった import を外した。 Item-Id: I-011 Impl-Runtime: claude Impl-Model: default
改修計画 — devbasex/ai-plugins #2348
改善項目I-001 —
|
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | major | high | claude / codex / kiro | 採用 | 2 |
なぜ: 1 メソッドに (1) 周回の前提チェック・(2) sprint-state init の実行と MVV ゲートの写し・(3) new sprint の実行・(4) まとめの組み立て・(5) manifest からの pipeline 文字列の組み立て、が 67 行・認知的複雑度 22・分岐 10 で同居する。特に手で行うステージ有無で pipeline を分ける末尾のブロックは独立した段階として名前が付く。
手順: 1. test_sprint_loop.py のスプリント生成拒否、manual の後まで close を待つ経路、引継ぎの next のテストを確認する。
2. manifest のステージ配列・close のプラン・done・rec を入力とし、queue と pipeline を返す関数を同じファイル内に抽出する。最初の command、後続の command/manual、関門を除外する判定をそのまま移す。
3. cmd_sprint には外部実行、lap の更新、記録保存と結果出力を残し、抽出関数への値の受け渡しを明示する。
4. manual が無い場合と manual/別 command がある場合の文字列を現状固定し、close が案内される順序と既存 metrics が変わらないことを確認する。
レビューで確かめるテストの差分: plugins/ndf/scripts/tests/test_sprint_loop.py(機械で期待値が変わったか決まらなかった)
I-002 — plugins/ndf/scripts/sprint_close_lib/record_find.py#find_record
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | major | high | claude / codex / kiro | 採用 | 2 |
なぜ: 1 関数に (1) まとめ課題ごとの閉じる PR の収集・(2) 候補 PR の展開・(3) 候補ごとの記録の読み取りと段階/スプリントによる絞り込み・(4) 曖昧判定と最終決定、の 4 段階が通しで同居し、認知的複雑度 30(本体の最大)・分岐 13・ネストした for の中に try が入る。段階に名前が付き、前段の出力が次段の入力になる直列構造なので連鎖へ分解できる。
手順: 1. 課題ごとの閉じる PR の集合を作る部分を _closers_of(root, repo, issues) -> dict[int, set[int]] として抽出
2. 閉じる PR と、それを参照する PR の和を作る部分を _candidates(root, repo, closers) -> set[int] として抽出
3. 候補ごとに parse_record して kept / pre に振り分ける部分を _released_records(root, repo, cands, closers_of) -> (kept, pre) として抽出(StepError → _Unreadable の変換もここへ)
4. find_record は try の中で 1〜3 を順に呼び、後半の RecordHit の組み立てだけを残す
5. test_record_find.py を流して結果が変わらないことを確かめる
I-003 — plugins/ndf/scripts/supervise_lib/release_templates.py#release_version_of
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| duplication | consolidate_duplication | major | high | claude | 採用 | 1 |
なぜ: 開発版から接尾辞を外す規則 re.sub(r"-.*$", "", v) が release_templates.release_version_of と supervise_lib/sprint.py の prod_version に別々に書かれている(範囲外の sprint_loop_record.prod_of にも 3 つ目の写しがあり、docstring が「同じ規則」と互いを指している)。この PR で release_version.py は versions.release_base(semver)を版の規則の 1 か所と定めたのに、雛形の側だけ正規表現の写しが残る
手順: 1. sprint.py の prod_version を、版があれば versions.release_base(version) を返す形へ置き換える(呼ぶ前に deps.require("versions") が済んでいるかを確かめる。済んでいなければ supervise_lib 側に 1 つだけ接尾辞を外す関数を置き、両方から呼ぶ)
2. release_templates.release_version_of の re.sub を同じ関数の呼び出しへ置き換える
3. sprint.py・release_templates.py で使われなくなった re の import を消す
4. test_supervise*.py・test_release_steps.py を流す
I-004 — plugins/ndf/scripts/lib/sprint_loop.py#gate2_answer
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| hidden_dependency | extract_method | major | medium | codex / kiro | 採用 | 2 |
なぜ: 引数は lap と since だが、実際には lap 内のパスとグローバルな差し戻しログを読み、時刻変換・新旧判定・承認と差し戻しの優先をまとめて決める。既存テストは停止前の承認を除く経路を通す一方、両方の記録の時系列の組合せを直接固定していない。
手順: 1. 変更前に現状固定テストを追加し、承認と差し戻しの前後関係、同時刻時の選択、since と同時刻、時刻なし、MVV による承認の除外を現在の出力で記録する。仕様を新しく定義し直さない。
2. state と差し戻しログを読む部分を gate2_answer に残し、gates・rejections・since を明示して受け取る純粋な選択関数を同じファイル内に抽出する。fresh と EPOCH の既存規則をそのまま移す。
3. gate2_answer の公開シグネチャと JsonReadError 時の空配列扱いは維持し、抽出関数を呼ぶ。
4. 純粋な関数の固定テストと、cmd_start 経由のゲート 2 再開テストを両方実行する。
I-005 — plugins/ndf/scripts/sprint-close.py#_closing_blocker
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| conditional_chain | extract_method | minor | medium | claude / kiro | 採用 | 1 |
なぜ: 閉じてよいかの判定が kept_all を段階的に上書きする if/elif 連鎖(record_pr 0 / unknown / 記録なし / 本番前)と、その後の verify ブロックの判定が 1 関数に積み重なる(認知的複雑度 22・分岐 9・ネストが深い)。kept_all を途中で書き換える形は読む順でしか追えない。
手順: 1. record_pr と stage から閉じられない理由(kept_all)だけを決める _stage_blocker(a, rec) を抽出し、理由 or None を返す
2. verify ブロックから verdicts を決める部分を _verify_verdicts(a, rec, record_repo) として抽出
3. _closing_blocker 本体は _stage_blocker → (理由が無ければ) _verify_verdicts の 2 段にし、kept_all の逐次上書きをやめる
I-006 — plugins/ndf/scripts/supervise_lib/queue_fill.py#_fill_dev
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| deep_nesting | flatten_conditional | minor | medium | claude / kiro | 採用 | 1 |
なぜ: 開発版の版を決める処理が rec の有無・is_taken・own の 3 段の入れ子で、正常系(ensure_filled)が末尾に埋もれる(認知的複雑度 21・分岐 8・return 5)。例外的な状態(読めない・既出・自分の配布でない)を先に判定して抜ける形にできる。
手順: 1. 記録がある側を _recheck_dev(f, obs, rec) -> (rec, stopped) として抽出し、早期 return でネストを平らにする(is_taken でなければ rec をそのまま返す → own が None なら unreadable で止める → own なら rec を返す → explicit なら taken で止める → redecide)
2. _fill_dev は記録の有無で 2 つの経路を選ぶだけにする
3. test_release_version.py と queue の版の差し込みを通すテスト(fill_release_version を使う 3 本)を流す
I-007 — plugins/ndf/scripts/lib/release_version.py#bump_check
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| conditional_chain | flatten_conditional | minor | medium | claude / kiro | 採用 | 2 |
なぜ: bump_check は old == new と cmp の組み合わせを 2 回に分けて判定し、後半は is_taken・prerelease・cmp で次の版と既存の版を別々の三項・if 連鎖で決める。打ち直しの判定(old == new の場合)と、止める理由の組み立てが 1 関数に混ざる
手順: 1. old == new のときの打ち直しの判定(cmp < 0 / cmp == 0 と own_released)を _rerun(repo, new, base, obs, cmp, metrics) -> (already, stop) | None として抽出
2. 止めるときの existing と nxt を決める部分を _taken_stop(plugin, new, obs, cmp, metrics) -> BumpStop として抽出
3. bump_check は形の検査 → 観測 → _rerun → 書き換えてよいかの判定 → _taken_stop の直線にする
4. test_release_steps.py と test_bump_keeps_instructions.py の bump の経路を流す(bump_check を直接呼ぶテストが無いため、終了コード 2 / 3 と打ち直しの 3 経路を通すテストがあるかを先に確かめ、欠ければ現状固定テストを足す)
レビューで確かめるテストの差分: plugins/ndf/scripts/tests/test_release_steps.py(機械で期待値が変わったか決まらなかった)
I-008 — plugins/ndf/scripts/lib/sprint_loop.py#cmd_sprint
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| duplication | extract_method | major | medium | claude | 採用 | 1 |
なぜ: まとめの queue のコマンド「python3 SUPERVISE queue <ステージ> --max 3 [--then ...] --done 」の組み立てが cmd_sprint・gate2_pipeline・sprint_loop_gate.py(342 行)の 3 か所に写されている。--max 3 の値も 3 か所に散る。止まった記録を stops へ移して running に戻す 2 行(resumed_at)も resume_stopped と cmd_sprint に重複する
手順: 1. sprint_loop_gate.py に queue_command(stages: list[list[str]], done: Path) -> str を抽出し、--max 3 を名前付きの定数にする
2. sprint_loop.gate2_pipeline と cmd_sprint の手で行うステージがある側の組み立てをこの関数の呼び出しへ置き換える
3. sprint_loop_gate.py の 342 行の組み立ても同じ関数へ置き換える
4. 止まった記録を解く 2 行を resume_record(env, rec) として抽出し、resume_stopped と cmd_sprint から呼ぶ
5. test_sprint_loop.py を流す(出力の pipeline 文字列が一致することで固定される)
I-009 — plugins/ndf/scripts/release-steps.py#cmd_release
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | major | medium | codex | 採用 | 2 |
なぜ: 配布前提の検査、開発版 PR の再利用とマージ、本番の承認コミット照合と先端移動時の再試行、タグ公開、結果の整形まで 1 関数が担う。承認に関わる再試行の境界が PR 作成や結果集計の中に埋もれ、変更時に読む範囲が広い。
手順: 1. test_release_steps.py と test_release_approved_commit.py を実行し、PR 再利用・承認の外の変更・先端移動・承認情報なしでの停止を固定する。
2. 開発版 PR の再利用または作成とマージを、PR 番号とマージコミットを返す関数へ抽出する。前提検査と push の順序は保つ。
3. 本番 PR の作成と承認した先端を指定したマージ再試行を、必要な承認情報を明示して受け取る関数へ抽出する。再照合、HEAD_MOVED_RETRIES、Gate の終了コードと metrics の更新時点を維持する。
4. cmd_release は各段階の呼び出し・dev の結果出力・タグ公開・最終結果の組み立てを担う。抽出先は同じ対象ファイル内とし、既存の _publish_tag_and_release を使う。
5. 外部コマンドを新規に実行せず、既存テストの git/gh の代替で副作用の順序と公開結果を確認する。
I-010 — plugins/ndf/scripts/supervise_lib/queue.py#cmd_queue
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | major | medium | kiro | 採用 | 1 |
なぜ: 1 関数に (1) then/stages の正規化・(2) 宣言の読み取りと done の初期化・(3) 耐久ワークフローの起動と resolve・(4) wait ループと attention の通知、が 57 行・認知的複雑度 22・引数 7 で同居する。stages の正規化と起動準備は durable を import する前の純粋なファイル処理で、分けると単体で試せる。
手順: 1. then から then_stages/stages/all_plans を作る部分を _normalize_stages(plans, then) として抽出
2. 宣言の読み取り・done の初期化・listing の判定を _prepare_queue(all_plans, plans, done) として抽出し、(decl, done_path, seen, listing) か _not_started を返す
3. cmd_queue 本体は正規化 → 準備 → launch_queue → wait ループに整理(durable の import は本体に残す)
I-011 — plugins/ndf/scripts/lib/sprint_loop.py#resume_stopped
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| conditional_chain | replace_with_lookup_table | major | low | kiro | 採用 | 3 |
なぜ: 止まった理由(stop['condition'])ごとの再開の振る舞いが、mvv_changed / user_stop / budget_* / gate2_returned / refused(+CONTINUATION_STEP) / refused の長い if-elif 連鎖で 1 関数に散らばる(認知的複雑度 22・分岐 11・return 5)。種類ごとの早期 return と nxt の組み立てが混在し、新しい止まり方を増やすたびにこの連鎖を直す。
手順: 1. 各分岐の本体を condition ごとのハンドラ関数(_resume_mvv_changed / _resume_user_stop / _resume_budget / _resume_gate2 / resume_refused)へ抽出し、(停止結果 or None, nxt) を返す共通の形にそろえる
2. condition のプレフィックス照合(budget)を含めてディスパッチする小さな対応表を作る
3. resume_stopped 本体は対応表を引いてハンドラを呼び、早期 return か stops への移動+write_record+handoff の共通後処理だけを残す
指標の測定
- 状態: written / 言語とツールの対応: 既定(.ndf/code-metrics.json は無い) / 所要: 24.9 秒(使えた時間 225 秒 / 上限 225 秒)
- 指標のファイル: /tmp/ndf-worktrees/devbasex--ai-plugins/rf2348/work/.cross_refactoring/code-metrics-rf2348.md
| 言語 | ツール | 版 | ランナー | ファイル | 秒 | 結果 |
|---|---|---|---|---|---|---|
| python | ruff-complexipy | ruff 0.16.9 / complexipy 8.0.1 | uvx | 234 | 0.8 | 測った |
| shell | — | — | — | 10 | — | unsupported_language |
| 重複: python | symilar | pylint 4.0.9 | uvx | 234 | 21.9 | 測った(2 箇所) |
| 重複: shell | jscpd | jscpd 4.3.0 | npx | 10 | 1.2 | 測った(0 箇所) |
時間の上限
| 値 | 中身 |
|---|---|
| 提案の枠の終わり(監視の上限 = 残り + 余裕) | 2026-11-01T05:46:17+00:00 |
| 改修計画の枠の終わり(同上) | 2026-11-01T05:53:47+00:00 |
| テストの追加の終わり = 実装の終わり − Σ(採っていて未検証の項目の実装の見積り) | 2026-11-01T06:09:00+00:00 |
| 実装の終わり = 最終ゲートの修正の打ち切り − バッファ − Σ(採っていて未検証の項目の検証の見積り) | 2026-11-01T06:11:32+00:00 |
| 直しの試行の打ち切り | 2026-11-01T06:21:13+00:00 |
| 想定最大時間の終わり H(子プロセスはすべてここまでに止まる) | 2026-11-01T06:38:22+00:00 |
| 確かめの開始の締め切り = H − 確かめの見込み(最終ゲート修正と打ち切りの後の取り消しもここまで) | 2026-11-01T06:23:00+00:00 |
| 確かめの見込み(秒。最終ゲートの確かめ 1 回。バッファの最終ゲートの全体テスト) | 922 |
| 最終ゲート修正 1 回の見込み(秒。バッファの final_fix。起動は今 + この値が確かめの開始の締め切り以前のときだけ) | 107 |
| 指標の測定の上限(秒。提案の枠の中から割く) | 225 |
| 着手前のテスト 1 回の上限(秒) | 3708 |
| 範囲テスト 1 回の上限(秒) | 1428 |
| 手元の全体テスト 1 回の上限(秒) | 3708 |
| CI の待ちの上限(秒) | 2766 |
| 余裕(秒。手順の上限と CLI の上限に足す) | 225 |
入力: 予算 75 分 / 全体テストの所要 w 1236.0(ci-steps) / 着手前の実測 x 475.8 / CI の壁時計 c 922.0 / 着手前のテストの所要の見込み s 1236.0(whole) / 戦略 local-scoped-ci-whole
無音の打ち切りは手順の監視の上限と同じ値である。項目ごとの期限は持たない(実装を止めるのは実装の終わりだけ)。
見送った提案
| 対象 | 兆候 | 理由 | 根拠(MVV) | 補足 |
|---|---|---|---|---|
plugins/ndf/scripts/lib/sprint_loop.py#gate2_answer |
long_method | duplicate | Value 6 | C-007 と同じ変更 |
plugins/ndf/scripts/lib/release_version.py#bump_check |
long_method | duplicate | Value 6 | C-016 と同じ変更 |
plugins/ndf/scripts/lib/sprint_loop_gate.py#continuation |
duplication | budget | Value 6 / Value 7 / Value 4 | 見積り 16.4 分が残りに入らない |
plugins/ndf/scripts/supervise_lib/sprint_waves.py#plan_sprint_release |
duplication | budget | Value 6 / Value 5 | 見積り 16.4 分が残りに入らない |
plugins/ndf/scripts/supervise_lib/release_templates.py#release_names |
duplication | budget | Value 6 / Value 7 | 見積り 16.4 分が残りに入らない |
plugins/ndf/scripts/lib/release_version.py#observe |
long_method | budget | Value 10 / Value 4 | 見積り 8.8 分が残りに入らない |
plugins/ndf/scripts/supervise_lib/queue.py#fill_stage |
long_method | budget | Value 10 / Value 4 | 見積り 8.8 分が残りに入らない |
plugins/ndf/scripts/supervise_lib/sprint_routes.py#manual_production_waves |
duplication | budget | Value 10 / Value 6 | 見積り 8.8 分が残りに入らない |
plugins/ndf/scripts/tests/test_supervise_design_match.py#pr_repo |
duplication | budget | Value 10 / Value 6 | 見積り 9.1 分が残りに入らない |
plugins/ndf/scripts/tests/test_supervise_new.py#test_supervise_new.py |
duplication | budget | Value 10 / Value 6 | 見積り 9.1 分が残りに入らない |
plugins/ndf/scripts/sprint_close_lib/record_find.py#RecordHit.reason |
conditional_chain | budget | Value 10 / Value 6 | 見積り 9.2 分が残りに入らない |
plugins/ndf/scripts/lib/sprint_loop.py#cmd_sprint |
magic_value | budget | Value 8 / Value 10 / Value 6 | 見積り 9.9 分が残りに入らない |
plugins/ndf/scripts/lib/dist_record.py#released |
magic_value | budget | Value 8 / Value 10 / Value 6 / Value 7 | 見積り 9.9 分が残りに入らない |
plugins/ndf/scripts/supervise_lib/release_templates.py#_prepare_steps |
long_parameter_list | budget | Value 10 / Value 6 | 見積り 11.9 分が残りに入らない |
plugins/ndf/scripts/release-steps.py#base_version |
duplication | budget | Value 6 / Value 10 | 見積り 16.4 分が残りに入らない |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | REQUEST_CHANGES
配布不要の条件判定より先に版を検査して後続を止める経路を修正してください。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | kiro | APPROVE
41 ファイル(#2089 系の extract_method/consolidate を中心とした refactoring と、#2164 の版の fill 時決定・#2230 の記録 PR 探索の 2 機能)を全件読んだ。gate2_answer/latest_gate2_answer・resume_stopped のハンドラ分割・_closing_blocker/_stage_blocker/_verify_verdicts・release-steps の _merge_release_pr/_merge_prod_pr 抽出・cmd_queue の _normalize_stages/_prepare_queue 分割・queue_command への --max 3 の一本化は、base との差分を追った範囲でいずれも挙動が保たれている。新機能で増える git fetch / gh 呼び出し(bump の observe、fill_release_version、find_record)は #2164・#2230 の設計どおりで、plan を atomic に埋め戻すため queue 打ち直しでも二重に呼ばれず、test で境界・失敗系・落下後の再開まで固定されている。docs(3 spec)・pace.md・waiting.md・SKILL.md の記述はコード(has_record・record_pr_ref の分岐順・{queue_record} の release-verify 配置・unfilled を失敗に数える規則)と一致している。critical/major の基準(通常経路の誤動作・秘密/認可/データ/不可逆・呼び出し回数の意図せぬ増加・設計と実装の食い違い)に当たる指摘は、今回の範囲では見つからなかった。
「版」と「実行の条件」を持つ配布のプランは、queue の差し込みで版を照会する前に条件を打つ。 配布不要(skip_code)なら版を照会・差し込みせずに流し、engine が条件を打ち直して完了で終える。 明示の版が既出でも unfilled で止まらず、まとめ・課題のクローズへ進む。 条件の実行は engine と queue で共有する run_condition(steps.py)へ寄せた。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🔧 /ndf:fix サマリ | round 1 | commit 62f27fe対応件数: critical=0 / major=1 / minor=0(合計 1 件) |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | claude | REQUEST_CHANGES
開発ループのまとめが、周回のスプリントで出し終えた版を明示の版として渡し続けるため、最終の検査で変更が出た周回は #2164 の既出の検査で必ず止まる。1 件を直してください。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | kiro | APPROVE
43 ファイル全件を base...head の差分で読んだ。#2089 のリファクタリング(sprint_loop の resume ハンドラ分割と gate2 を sprint_loop_gate2 へ抽出・engine/queue の run_condition と _normalize_stages/_prepare_queue 抽出・release-steps の _merge_release_pr/_merge_prod_pr・sprint-close の _stage_blocker/_verify_verdicts・queue_command への --max 一本化)と、2 機能(#2164 の版の fill 時決定 = release_version.py・queue_fill.fill_release_version、#2230 の記録 PR 探索 = sprint_close_lib/record_find.py・{queue_record})を追った。round 1 の codex の major(配布不要の条件判定を版の検査より先に行う)は commit 62f27fe の queue.fill_stage の _release_skipped_by_condition で対応済みで、test_fill_stage_asks_the_condition_before_the_version が code=0/3 の両経路を固定している。重点基準(通常経路の誤動作・秘密/認可/データ/不可逆・ネットワーク/CI/AI 起動の回数増・設計文書と実装の食い違い)に当たる critical/major は、この範囲では見つからなかった。調べた候補はいずれも設計どおりで棄却した: (1) 配布プランの実行の条件が fill_stage と engine の 2 回走るが check-trigger.py changed は通信せず git 履歴のみ読む読み取り専用で副作用なし・skip 最適化のため構造上避けにくい。(2) dev プランの流し直しごとの git fetch/own_released は版の横取りを再検査する意図的な設計(#2164)で、ensure_filled が冪等。(3) record_pr_ref が STAGE_NONE→pace:auto→テンプレの順へ替わり auto のまとめが {queue_record} を使うのは #2230 決定 5 のとおりで test で固定。(4) {release_version}/{release_base} は leftover_placeholders の網に無いが、この語の産出元 release_names/version_field は常に「版」欄も置くため実経路で未解決のまま流れない。closing_refs の (repo, n) 照合・released の段階判定・gate2_answer の現状固定テストも実装と一致。
最終の検査で変更があると、出し終えた版が既出として止まり、まとめと周回が失敗で締まっていた。 まとめの配布の版は流す時点に次に空いている版で決める。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🔧 /ndf:fix サマリ | commit b88f88f対応件数: critical=0 / major=0 / minor=0(合計 0 件) |
MVV 判定(関門 2(本番への配布の承認))
理由
|
スプリント m26-3 の課題を develop へ取り込む。
利用者向けの変化
--record-prに{queue_record}を組みます。(#2230 を実装する(スプリント m26-3) #2333)移行の手順
課題と設計
コミット
変更の統計
テスト(supervise.py の run のステップ)
集めた実装の PR
閉じる課題
Closes #2044
Closes #2121
Closes #2164
Closes #2230
手動確認
モード: standard / 通した工程: 実装 → Pull Request
🤖 Generated with Claude Code