Repository navigation
Description
何が起きたか
検査のプランの cross-refactoring(想定最大時間 30 分)で、実装に使えた枠が約 4 分しかなく、リファクタリング計画の 4 項目のうち 2 項目が not_done で終わった。一方で、直しの試行と最終ゲート修正のために取った後ろの枠(約 17 分)は使われずに残った(fix_rounds 0・最終ゲートは 1 回で通過)。
| 区切り | 時刻 |
|---|---|
| 提案の枠の終わり | 20:49:44 |
| リファクタリング計画の枠の終わり(計画の時点で使えた時間 6.3 分) | 20:52:44 |
| 実装の終わり = 最後の項目の完了期限 | 20:56:42 |
| 直しの試行の打ち切り | 21:03:48 |
| 最終ゲート修正の打ち切り(想定最大時間の終わり) | 21:13:44 |
| 項目 | 見積り | 状態 |
|---|---|---|
I-001 SnapshotManager.rotate の extract_method |
— | 採用 |
I-002 bin/devbase#cmd_build の duplication |
— | not_done(実装の締め切りまでにコミットが無い) |
I-003 container.py#cmd_post_start の long_method |
— | not_done(実装の完了期限を過ぎてコミットした) |
I-004 SnapshotManager._validate_volumes の extract_method |
— | 採用 |
見送りの表では、ほかに 11 件が「見積り 1.1〜2.1 分が残りに入らない」(budget)で外れた。入力は 予算 30 分 / 全体テストの所要 w 69.6 秒 / 着手前の実測 x 132.8 秒 / CI の壁時計 c 45.0 秒 / 戦略 local-full。
原因の見立て
締め切りは計画の前に固定の配分で決まり、直しと最終ゲートの予備を先に確保する。予備が使われなかったときに、その分が実装の項目へ回らない。I-003 は締め切りの後にコミットしており、あと数分あれば採用できた見込みが高い。
直し方の案
- 項目ごとの締め切りを、前の項目が早く終わった分・予備のうち使われていない分だけ後ろへずらす(最終ゲートの打ち切り時刻は動かさない)
- または、計画の時点で使える時間が想定最大時間の 1/4 を切るときは、項目の数を絞るか予備の比を下げる
- 少なくとも、完了報告に「予備のうち使わずに残った時間」を出し、予算を変える判断の材料にする
見つけた場所
devbasex/devbase のスプリント m7d の Pull Request(#421)の検査のプラン。2026-10-03。リファクタリング計画の記録は devbasex/devbase#421 の cross-refactoring のコメント。関連: #1491(中断の後の固定の締め切り)・#1522(予算を変える基準)
再発(2026-10-05、スプリント m744・PR #1745)
全体テストの長いリポジトリでは、30 分の想定最大時間のうち計画の時点で使える時間がほぼ 0 になり、提案 14 件がすべて見送られた(採用 0)。
| 値 | 中身 |
|---|---|
| 入力 | 予算 30 分 / 全体テストの所要 w 336.1 秒 / 着手前の実測 x 389.5 秒 / CI の壁時計 c 504.0 秒 / 戦略 local-full |
| 手順の所要 | 着手前のテスト 6.5 分・提案 5.5 分・計画 2.3 分・最終ゲートの全体テスト 5.2 分 |
| リファクタリング計画の時点で使えた時間 | 0.27 分 |
| 見送り | 14 件(budget 12・vocabulary 2) |
| 所要 | 20.0 分(想定最大時間との差 +10.0 分。使わずに残った) |
devbase の例(w 69.6 秒)は実装の枠が約 4 分だったが、こちらは実装の枠が 0 だった。全体テストが数分を超えると、既定の 30 分では提案を集めるだけで終わる。直し方の案の「計画の時点で使える時間が想定最大時間の 1/4 を切るとき」の判定を、提案の前(着手前のテストの後)にも置き、要る予算を出して止まるか、検査のプランが --budget-minutes を全体テストの所要から決めるかを選ぶ材料になる。記録は PR #1745 の cross-refactoring のコメント(#1745 (comment) )。
再発(2026-10-06、スプリント m1793・PR #1801、ndf 10.17.65-dev)
同じ形がまた起きた。提案 28 件 → 候補 25 件のうち、リファクタリング計画の時点で使えた時間が 1.3 分で、採用 1 件・時間で見送り 23 件(budget)。予備の時間は使わずに残った(fix_rounds 0・最終ゲートは 1 回で通過)。
| 値 | 中身 |
|---|---|
| 予算 | 30 分(検査のプランの既定) |
| 手順の所要 | 着手前の全体テスト 6.6 分(395.8 秒)・提案 5.0 分(codex が 300 秒で上限まで)・計画 1.3 分・実装 0.8 分・検証 4.7 秒・最終ゲートの全体テスト 5.9 分 |
| 実行の所要 | 20.5 分(1,227 秒。想定最大時間との差 約 9.5 分は使わずに残った) |
同じ日の PR #1799(スプリント m1290 の検査)も、提案 287 秒・計画 91 秒・全体テスト 403.6 秒 + 381.1 秒で、採用 0 件だった(~/.local/state/ndf/metrics/devbasex--ai-plugins/cross-refactoring-allocation.jsonl)。このリポジトリでは全体テストが 2 回で約 12.5 分になり、30 分の予算では提案を集めて 1 件を直すのが上限になっている。リファクタリング計画: #1801 (comment)
要求と受け入れ条件
この節から下が要求である(2026-10-06 に requirements-design で書いた)。上の節は起票の記録としてそのまま残す。#1491(計画の後に中断して再開すると、固定の締め切りが過ぎていて全項目が not_done になる)をこの要求へ取り込んだ。 どちらも「想定最大時間の中で、実装・直し・最終ゲートへ時間をどう配るか」という cross-refactoring の時間の配分の問題であり、締め切りを決める同じ式(refactor_lib/budget.py・refactor_lib/timeline.py)を直すため、1 本の設計で扱う。
依頼(原文)
#1743。この要求へ次を取り込む: #1491(計画の後に中断して再開すると固定の締め切りが過ぎていて全項目が not_done になる)。どちらも「想定最大時間の中で実装・直し・最終ゲートへ時間をどう配るか」という cross-refactoring の時間の配分の問題として 1 本の設計で扱う。#1743 は振り返り(PR 1801・1799)で再発: 30 分のうち全体テスト 2 回(各 6 分前後)が食い、実装に使えたのが 1.3 分で 25 件中 23 件が時間切れ。#1491 の受け入れ条件も同じ写し(issues/issue-1743-requirements.md)へ含め、#1491 の本文には「## 受け入れ条件」の節を書き、#1743 の要求へ取り込んだことを書く。人へ問わずに進め、決められない点は前提か未決として課題の本文へ書く。
#1491 の依頼(原文):
再開のとき、止まっていた時間の分だけ締め切りをずらすか、残りの予算で計画し直す
2026-10-07 の利用者の指示(原文。この本文の末尾の「追記: 棚卸しの実測」):
cross-refactoring の無意味な制約はどんどん外す
実測から分かったこと(PR 1801 の内訳)
PR 1801 の実行(rf1801-20261006T142613Z)の、リファクタリング計画の時点の計算を実測から戻すと次のとおりである(B = 30 分、戦略 local-full)。
| 区分 | 分 | 実際に使ったか |
|---|---|---|
| 経過 E(着手前の全体テスト 6.6・提案 5.0・計画 1.3) | 12.9 | 使った |
| バッファ: 危険フラグの全体テスト(w) | 約 6.6 | 使わなかった(危険フラグは立たず、whole_test.danger は null。PR 1780・1799 も同じ) |
| バッファ: 最終ゲートの全体テスト(w) | 約 6.6 | 使った(5.9 分) |
| バッファ: 修正 1 回・最終ゲート修正 1 回 | 約 2.6 | 使わなかった(fix_rounds 0・最終ゲートは 1 回で通過) |
| 使える時間 A = B − E − バッファ | 1.3 | 実装 0.8 分 |
手元の全体テストを 3 回分(着手前の 1 回は経過、危険フラグと最終ゲートの 2 回はバッファ)数えており、うち危険フラグの 1 回分(約 6.6 分)は 3 回の実行でいずれも走っていない。 項目を採るかどうかはリファクタリング計画の時点にしか決めないため、後で余った時間は採る件数を増やさない。
棚卸しの 9 回(rf1673〜rf1801。本文の末尾の追記)では、見送り 121 件のうち 94 件が budget だった。既定の 30 分の 5 回は、どれも約 20 分で終わって 10 分前後を使わずに残した。項目ごとの着手期限・完了期限は、時間が残っていても項目を止める。 着手期限・完了期限で not_done になったのは 13 件で、rf1718(B = 60 分)は 10 件を「実装の締め切りまでにコミットが無い」で not_done にしたまま、60 分のうち 14.5 分を残して終わった(elapsed_seconds 2,733)。
目的
- 想定最大時間のうち、実際に走る見込みの手順へ時間を配り、実装に使える時間を増やす(cross-refactoring: 実装の枠が想定最大時間の 30 分のうち約 4 分で項目が not_done になり、直しと最終ゲートの予備が使われずに残る #1743)
- 中断して再開しても、止まっていた時間のせいで採った項目が
not_doneにならない(cross-refactoring: 計画の後に中断して再開すると、固定の締め切りが過ぎていて全項目が not_done になる #1491) - 実装に使える時間が 1 件も入らないほど短いと分かった時点で、提案に時間を使わずに止まり、要る想定最大時間を示す(cross-refactoring: 実装の枠が想定最大時間の 30 分のうち約 4 分で項目が not_done になり、直しと最終ゲートの予備が使われずに残る #1743 の 2026-10-05 の再発)
- 想定最大時間を変える判断の材料として、バッファのうち使わずに残った時間を報告に出す(cross-refactoring: 実装の枠が想定最大時間の 30 分のうち約 4 分で項目が not_done になり、直しと最終ゲートの予備が使われずに残る #1743 の直し方の案の 3 つ目・検査のプランで cross-refactoring の予算を既定から変える基準が Skill に無く、conductor が根拠なく 60 分を写す #1522 の材料)
- 想定最大時間が残っている間は、項目ごとの見積りから出した期限で項目を止めない(2026-10-07 の追記・rf1718)
- 実装と検証が早く終わって時間が余ったら、見送った候補を採り直して余った時間を項目へ回す(2026-10-07 の追記)
前提
- 前提 1: 想定最大時間(
--budget-minutes)は、cross-refactoring が動いていた時間で数える。 中断して止まっていた時間は数えない。したがって再開したとき、まだ過ぎていない締め切りと打ち切り(開始 + Bを含む)は止まっていた時間の分だけ後ろへずれる。cross-refactoring: 計画の後に中断して再開すると、固定の締め切りが過ぎていて全項目が not_done になる #1491 の依頼の 2 案(ずらす / 残りの予算で計画し直す)のうち「ずらす」を採る。計画し直すと、実装担当の CLI を再び起動して LLM の時間を使い、終えた項目の扱いも作り直しになるためである(Value 4) - 前提 2: 止まっていた時間は、再開の時刻 − 状態ファイルに残った最後の記録の時刻で測る。最後の記録の時刻を持たない状態ファイル(この変更より前の版で作ったもの)は、今の振る舞い(ずらさない)のまま進め、報告に 1 行で知らせる
- 前提 3: 中断に当たらない打ち直し(止まっていた時間が余裕
0.05·B以下)では締め切りをずらさない。秒単位の打ち直しで締め切りが揺れないようにするためである - 前提 4: 採る件数はリファクタリング計画の時点で決め、検証の後に時間が残っていれば、
budgetで見送った候補を順位の順に採り直す。採り直しは計画し直さない(LLM を起動せず、見積り・順位・範囲テストは計画の時点の値を使う)。cross-refactoring: 計画の後に中断して再開すると、固定の締め切りが過ぎていて全項目が not_done になる #1491 の再開も計画し直さない(前提 1) - 前提 5: 「実装に使える時間が 1 件も入らない」の判定に使う 1 件の長さは、配分テーブル(
refactor_lib/allocation.py)の見積りのうち最も短い項目の合計(テストの追加を除く)とする。配分テーブルは履歴の直近 10 回から集計され、プロジェクトごとに変わる(Value 5) - 前提 6: 検査のプランが渡す
--budget-minutesの既定(30 分)は変えない。cross-refactoring が「要る想定最大時間」を出し、どの値で打ち直すかは呼び出し側が決める - 前提 7: 止めてよいのは、越えると後ろの手順(検証・最終ゲート・その直し)の時間を食う時刻だけである。項目ごとの見積りから出した着手期限・完了期限は外す。どの締め切りを残すかは設計が決める
対象範囲
含む:
- リファクタリング計画の時点のバッファの数え方(走らない見込みの手順を実装へ回す)
- 項目ごとの締め切りと、直しの試行・最終ゲート修正の打ち切りの、再開での扱い
- 着手前のテストの後、提案者を起動する前の判定(実装に使える時間が 1 件も入らないなら止まる)
- 報告と実行の履歴(
cross-refactoring-allocation.jsonlのkind: runの行)に、使わずに残ったバッファと、再開で締め切りをどう扱ったかを残す - 項目ごとの着手期限・完了期限を外し、実装を止める時刻を 1 つにすること(2026-10-07 の追記)
- 検証の後に余った時間で、
budgetで見送った候補を採り直すこと(2026-10-07 の追記) - 上の変更に合わせた
cross-refactoringの文書(docs/02-plan-and-implement.mdの「締め切り」、docs/01-state-and-propose.mdの「再開」)
含まない:
- 検査のプランが
--budget-minutesを全体テストの所要から決める仕組み(呼び出し側の変更。下の未決) - 着手前のテスト・最終ゲートの全体テストそのものを短くすること(テストの戦略と全体テストの所要の問題)
- 提案と計画の枠の係数(
PROPOSE_SHARE 0.20・PLAN_SHARE 0.10)の見直し - 採り直しのために計画し直すこと(提案者・実装担当の LLM を起動し直して新しい候補や計画を作ること)
- リファクタリングの戦略を阻害する他の制約(cross-refactoring: リファクタリングの戦略(分割・抽出・移動・改名・インライン化・テストの共通化)を阻害する制約を外す #1814)
- リファクタリング計画より前の再開(提案・計画の途中での中断)の締め切りの扱い。今の振る舞い(枠が収まらずに止めた後の打ち直しは o を打ち直した時刻から数える、
timeline.window_offset)を変えない - cross-review と supervise の時間の上限(共通ライブラリ
scripts/lib/test_strategy.pyの係数は変えない)
ドメインイベント
| # | イベント | 引き金 | 失敗したとき | 順序の前提 |
|---|---|---|---|---|
| E1 | 着手前のテストを終えた | init |
上限を超えたら終了コード 4 で止まる(今のまま) | — |
| E2 | 実装に使える時間の見込みを出した | E1 の直後に init が計算する |
見込みに 1 件の長さが入らなければ、要る想定最大時間を出して終了コード 4 で止まり、提案者を起動しない(E3 へ進まない) | E1 |
| E3 | 提案を集めた | 駆動の propose |
今のまま | E2 |
| E4 | リファクタリング計画を取り込み、採る項目と締め切りを決めた | merge-plan |
1 件も入らなければ final へ進む(今のまま) |
E3 |
| E5 | 中断した | プロセスの終了・利用者の停止・中継の切り替え | — | E4 の後(この要求の範囲) |
| E6 | 再開し、止まっていた時間だけ締め切りをずらした | 同じ init の打ち直し |
最後の記録の時刻が無ければずらさず、1 行知らせる(前提 2) | E5 |
| E7 | 項目を実装し、検証した | 駆動の implement・verify |
実装を止める時刻(設計の「実装の終わり」)までにコミットが無い項目は採り直しの候補へ戻す。項目ごとの期限では not_done にしない |
E4(再開なら E6、採り直しなら E11) |
| E8 | 危険フラグの全体テストを走らせた / 走らせなかった | 検証で危険フラグが立ったか | 落ちたら直しの試行へ(今のまま) | E7 |
| E9 | 最終ゲートを通した | 駆動の final |
落ちたら最終ゲート修正(1 回目は打ち切らない。今のまま) | E8 |
| E10 | 報告と実行の履歴を残した | report |
— | E9 |
| E11 | 見送った候補を採り直した | 検証の後、最終ゲートの前 | 残った時間に入る候補が無ければ、持ち越した項目を not_done にして E9 へ |
E7・E8 |
用語
| 用語 | 意味 |
|---|---|
| 想定最大時間 | --budget-minutes。この要求では、cross-refactoring が動いていた時間で数える(前提 1) |
| バッファ | リファクタリング計画の見積りで、想定最大時間から経過を引いた後に差し引いておく時間(危険フラグと最終ゲートの全体テスト・修正 1 回・最終ゲート修正 1 回)。state.plan.reserve |
| 使える時間 | リファクタリング計画の時点で、採る項目の見積りを収める時間。state.plan.available_minutes |
| 止まっていた時間 | 中断から再開までの時間。前提 2 の式で測る |
| 採り直し | 検証の後に時間が残ったとき、budget で見送った候補と、実装を止める時刻までにコミットが無かった項目から、残った時間に入るものを順位の順に採り、テストの追加・実装・検証をもう 1 巡回すこと。計画し直さない |
受け入れ条件
実装へ回す時間(#1743)
- 前提: PR 1801 の入力(B = 30 分・戦略
local-full・w = x = 395.8 秒・c = 504 秒・経過 12.9 分・配分テーブルのfix= 1.3 分)でリファクタリング計画を組む
操作:merge-planの計算(純粋な関数)を呼ぶ
結果: 使える時間(plan.available_minutes)が 7.0 分以上になる(今は 1.3 分) - 同じ入力で、最終ゲート修正の打ち切り(
limits.final_end_at)は開始 + 30 分のまま変わらない - 同じ入力で、最終ゲートの全体テスト 1 回分(w)と最終ゲート修正 1 回分(
final_fix)はバッファに残る(最終ゲートの時間を削って実装へ回さない) - 実装の後の検証で危険フラグが立ったときは、今までどおり危険フラグの全体テストを走らせる(危険フラグを理由とする全体テストの実行を減らさない)
- 前提: 危険フラグが立ち、最終ゲート修正の打ち切りまでに危険フラグの全体テストと最終ゲートの全体テストの両方を走らせる時間が無い
結果: 実行は止まらずに最終ゲートへ進み、最終ゲートが落ちたら最終ゲート修正の 1 回目を打ち切らずに走らせる(決定 26 のまま)。何を省いたかが報告に 1 行出る - CI に任せる戦略(
local-scoped-ci-whole)では、バッファと使える時間の計算が変更の前と同じ値になる(危険フラグの全体テストは今も 0 分で数えている)
提案の前に止まる(#1743 の 2026-10-05 の再発)
- 前提: PR 1745 の入力(B = 30 分・w = 336.1 秒・x = 389.5 秒・c = 504 秒・
local-full)
操作:initが着手前のテストを終える
結果: 提案とリファクタリング計画の枠を使い切った後の使える時間の見込みに 1 件の長さ(前提 5)が入らなければ、提案者を起動せずに終了コード 4 で止まる - 上の止まる文に、見込みに 1 件の長さが入る想定最大時間の下限(整数の分)が出る
- 止まった実行を、文に出た下限以上の
--budget-minutesでinitを打ち直すと、着手前のテストを走らせ直さずに提案へ進む(今のwindow_stopped_atの打ち直しと同じ扱い) - PR 1801 の入力(この変更の後の計算)では止まらずに提案へ進む
再開(#1491)
- 前提: リファクタリング計画を取り込んだ後(
phaseがimplement)に中断し、止まっていた時間が最初の項目の着手期限までの残りより長い
操作: 同じinitを打ち直して再開する
結果: まだ来ていない締め切り(テストの追加の終わり・実装の終わり・直しの試行の打ち切り・最終ゲート修正の打ち切り)が、止まっていた時間の分だけ後ろへずれ、採った項目がnot_doneにならずに実装へ進む(中断を模したテストで、時計を引数で渡して確かめる) - 上の再開で、締め切りをどう扱ったか(止まっていた時間の秒と、ずらしたかどうか)が状態ファイルに 1 か所、報告に 1 行残る
- 止まっていた時間が余裕(
0.05·B)以下の打ち直しでは、締め切りが変わらない - 最後の記録の時刻を持たない状態ファイルからの再開では、締め切りを変えず、そのことが報告に 1 行出る
- 2 回中断したときは、止まっていた時間を足し合わせた分だけずれる
- 前提: 中断の前に、実装を止める時刻が既に過ぎていた
操作: 同じinitを打ち直して再開する
結果: その時刻はずれず、再開が動いていた間に無かった実装の時間を与えない
時間が残っている間は止めない(2026-10-07 の追記)
- 前提: rf1718 の形(B = 60 分。今の式なら最後の項目の完了期限が開始から約 28 分。開始から約 45.5 分で終わり 14.5 分が残った)の計画で、採った項目のコミットが開始から 40 分(今の完了期限の後、想定最大時間 − バッファ − 採っていて未検証の項目の検証の見積り の前)に来る
操作: 実装の取り込み(merge-implement)を呼ぶ
結果: コミットのある項目はすべて採られ、項目ごとの着手期限・完了期限を理由とするnot_doneが 0 件になる - 前提: 計画を取り込んだ
操作: 上限の表(limits)と項目(items[])を読む
結果: 項目は着手期限・完了期限を持たず、実装を止める時刻は「最終ゲート修正の打ち切り − バッファ − 採っていて未検証の項目の検証の見積り」の 1 つだけである - 前提: 実装を止める時刻までにコミットの無い項目がある
操作: 実装の取り込みを呼ぶ
結果: その項目はnot_doneにならず採り直しの候補へ戻る。実行の終わりまで採り直しに入らなかったときだけnot_doneになる - 前提: 時間が残っている
操作: 実装の CLI を監視する
結果: 実装を止める時刻より前に、項目の見積りを理由に CLI を止めない - 最終ゲート修正の打ち切り(
開始 + B)・直しの試行の打ち切り・打ち切りの後の取り消しの締め切りは変わらない
採り直し(2026-10-07 の追記)
- 前提: 検証(直しの試行を含む)を終え、残った時間(最終ゲート修正の打ち切り − 今 − バッファ)が 3.8 分で、
budgetで見送った候補の見積りが順位の順に 2.1・2.0・1.1 分
操作: 採り直しを呼ぶ
結果: 2.1 分と 1.1 分の候補を採り(入らない 2.0 分は飛ばして次を見る)、テストの追加・実装・検証をもう 1 巡回す - 前提: 残った時間に入る候補が無い
操作: 採り直しを呼ぶ
結果: 最終ゲートへ進み、持ち越した項目をnot_doneにする - 前提:
rank/duplicate/vocabulary/threshold/no_target/test_failedで見送った候補がある
操作: 採り直しを呼ぶ
結果: それらは採らない(採るのはbudgetの見送りと持ち越しの項目だけ) - 前提: 採り直しを呼ぶ
操作: Jev・提案者・実装担当の起動を数える
結果: 採り直しの判定は LLM を呼ばない(見積り・順位・範囲テスト・riskは計画の時点の値) - 前提: 採り直した
操作: 報告を読む
結果: 採り直した回数・件数・項目と、採らずに残ったbudgetの候補の数が 1 行出る
報告と記録(#1743 の直し方の案の 3 つ目)
- 報告に「バッファのうち使わずに残った時間」が、バッファの区分(危険フラグの全体テスト・最終ゲートの全体テスト・修正・最終ゲート修正)ごとの分で出る
- 実行の履歴の
kind: runの行に、使わずに残ったバッファの秒と、止まっていた時間の秒が残る - 実行の履歴の旧い行(新しいキーを持たない行)を読んでも、配分テーブルの集計(
allocation.build_table)が今と同じ値を返す
退行しないこと
- 時間に関わる数値は、今までどおり B・w・x・c・s・o と時計からの算術だけで決まり、実行の途中で LLM へ問わない
- 既存の cross-refactoring のテストがすべて通る
非機能の条件
| 大項目 | 条件 |
|---|---|
| 性能・拡張性 | PR 1801 の入力で、使える時間が 1.3 分から 7.0 分以上になる(上の受け入れ条件)。想定最大時間が残っている間は項目を not_done にせず、余った時間を採り直しで項目へ回す。1 回の実行の所要の上限(開始 + B、再開なら止まっていた時間を足した時刻)は延びない |
| 運用・保守性 | 使わずに残ったバッファと止まっていた時間が報告と実行の履歴に残り、#1522(予算を変える基準)の材料になる |
| 移行性 | この変更より前の版で作った状態ファイルから再開しても止まらない(前提 2)。実行の履歴の旧い行を読める |
影響
| 対象 | 影響 |
|---|---|
| 公開インタフェース | 変わらない(引数は増やさない。init の終了コード 4 で止まる場面が 1 つ増える) |
| データ | 状態ファイルに再開の記録(止まっていた時間)と最後の記録の時刻、実行の履歴の行にキーが増える。旧い形は読める |
| 既存の振る舞い | local-full / round-only でリファクタリング計画の使える時間が増え、採る件数が増える。項目ごとの着手期限・完了期限が無くなり、検証の後に見送った候補を採り直す(refactor.py のサブコマンドが 1 つ増える)。計画の後の再開で締め切りがずれる。着手前のテストの後に止まる場面が増える |
検証手段
| 項目 | 手段 |
|---|---|
| テスト | uv run --frozen --project . --all-extras pytest plugins/ndf/skills/cross-refactoring plugins/ndf/scripts/tests -q -n 4 |
| 静的解析・型検査 | uv run --frozen --project . ruff check plugins/ndf |
| 文書の参照 | python3 scripts/check-skill-frontmatter.py |
| 手動確認 | 次に検査のプランで cross-refactoring を走らせたとき(このリポジトリ、B = 30 分)、リファクタリング計画のコメントの使える時間が 7 分前後になり、採用が 2 件以上になることと、所要が想定最大時間より大きく短く終わったときは報告に採り直しの行があることを、conductor がコメントと実行の履歴で見る(リリース後テスト) |
前提とする取り決め
| 項目 | 参照先 / 決めたこと |
|---|---|
| プロジェクト構造 | 時間の式は refactor_lib/budget.py(純粋な処理)と refactor_lib/timeline.py(上限の表)に置き、時刻は引数で受ける(各モジュールの冒頭の取り決め)。テストと CI の待ちの係数は共通ライブラリ scripts/lib/test_strategy.py が持つ |
| コーディング規約 | AGENTS.md の「最小限のコード実装」。.md の文言を照合するテストは書かない |
| テスト戦略 | 締め切りと使える時間は純粋な関数の単体テストで、実測の入力(PR 1801・PR 1745)をそのまま与えて確かめる。再開は状態ファイルと時計を与えるテストで確かめる |
境界
| 区分 | 内容 |
|---|---|
| 常に行う | 既存テストの実行、時間の式の変更に合わせた docs/02-plan-and-implement.md の「締め切り」の表の更新 |
| 確認してから行う | 提案と計画の枠の係数・共通ライブラリの係数を変えること(この要求の範囲外) |
| 行わない | 検査のプランの既定の --budget-minutes を変えること、最終ゲートの全体テストを省くこと |
未決
| 項目 | 誰が決めるか | 期限 |
|---|---|---|
| 危険フラグの全体テストの時間を、リファクタリング計画の時点でどう実装へ回すか(バッファから外して最終ゲートの全体テストと兼ねる / 危険フラグが立ったときは見送る項目を減らして時間を作る など)。受け入れ条件は使える時間の値と、危険フラグの全体テストを減らさないことだけを決める | design(#1743 の設計) |
設計 PR |
| 提案の前に止まる判定の 1 件の長さに、配分テーブルの最短の見積りを使うか、もっと大きい値(想定最大時間の割合など)にするか(前提 5 は最短を置いた) | design |
設計 PR |
| 検査のプランが、cross-refactoring の出した要る想定最大時間で自動で打ち直すか(含まない。呼び出し側の変更) | 利用者(別の課題として起こすか) | このスプリントの振り返り |
進行
モード: —
- 要求と受け入れ条件 — 2026-10-06 15:45
- 作業場所の用意 — 2026-10-06 21:11
- 設計 — 2026-10-06 15:50
- 素材の収集と出典の確定
- ドキュメント再構成
- ドキュメントレビュー
- 計画 — 2026-10-06 21:10
- 実装 — 2026-10-06 22:31
- 構造改善 — 2026-10-07 00:28
- 実装レビュー — 2026-10-07 00:49
- 完了判定 — 2026-10-06 23:01
- Pull Request — 2026-10-06 23:16
- 確定仕様化
- 後片付け
- 配布 — 2026-10-07 01:15
- 体裁レビュー
- リリース後テスト
- 振り返り — 2026-10-07 05:17
- 棚卸し
追記: 棚卸しの実測(2026-10-07、利用者の指示「無意味な制約を外す」)
9 回の実行(rf1673〜rf1801)の見送り 121 件のうち 94 件が budget。既定の 30 分の 5 回は計画の時点で使える時間が 0.27〜2.04 分、採用 0〜2 件、どれも約 20 分で終わり 10 分前後を使わずに残した。
| 実行 | 計画までの経過 | バッファ | 使える時間 | 採用 | 予算で見送り | 実際の所要 |
|---|---|---|---|---|---|---|
| rf1745 | 14.4 分 | 15.3 分 | 0.27 分 | 0 | 12 | 20.0 分 |
| rf1763 | — | 14.7 分 | 2.04 分 | 2 | 15 | 22.1 分 |
| rf1780 | — | 15.8 分 | 0.94 分 | 0 | 18 | 19.9 分 |
| rf1799 | 13.5 分 | 15.8 分 | 0.70 分 | 0 | 22 | 20.2 分 |
| rf1801 | 13.2 分 | 15.5 分 | 1.31 分 | 1 | 23 | 20.4 分 |
- バッファのうち約 13 分は全体テスト 2 回分(
danger_whole_testとfinal_whole_test)。最終ゲートは検証の中の全体テストを使い回す(docs/04-verify-and-report.md:228)のに両方を差し引いている=余白に余白を重ねている - 着手期限・完了期限で
not_done13 件。rf1718 は 10 件をnot_doneにしたまま 60 分のうち 14.5 分を残して終わった=時間が残っていても止めている
利用者の指示により、この 2 つ(バッファの二重取り・時間が残っているのに止める期限)は外す対象として設計で扱う。リファクタリングの戦略を阻害する他の制約は #1814。
振り返り: #1825 (comment)
Activity
takemi-ohama commentedon Oct 6, 2026
再発(devbasex/devbase PR #432、スプリント m7e、2026-10-06)
改修計画 rf432 は想定最大時間 30 分に対し、改修計画の時点で使えた時間が 7.87 分、テストの追加の枠の終わりが 07:31:10、実装の枠の終わりが 07:34:57 で、major の 2 件(I-004
cmd_project_migrate_config・I-005sync_projectsの extract_method)は「テストの追加の締め切りまでにコミットが無い」で not_done になった。最終ゲートの修正の打ち切りは 07:52:02 で、実装の枠の後の約 17 分は使われていない。見送りの 16 件はすべて budget(見積り 0.7〜2.2 分が残りに入らない)。docs(design): #1743 の設計で I2・I8 と止まっていた時間の計測の契約を直す
docs(design): #1743 の設計で心拍の設定を 1 か所にし、間隔を見回りから切り離す
docs(design): #1743 の設計で時間が残っている間は項目の期限で止めず、余った時間で見送った候補を採り直す
docs(design): #1743 採り直しの巡の記録・持ち越しの経路・公開の時点・全体テストの有効範囲を定める
docs(design): #1743 採り直しの巡でテストの取り込み対象・取り消し済みの判定を巡ごとにし、CI へ寄せた危険フラグを巡を…
Docs: #1743 の設計に #1814・#1658 との関係、CLAUDE.md の扱い(決定 11)、システム構成・クラス図・パッ…
Docs: #1814 の設計で項目の期限の判定を #1743 に委ね、deletion の全体テストの超過を #1743 の未確認へ結び…
Docs: #1658 の「見送った改善項目」を #1743 の後の not_done に合わせ、採り直しの後の件数とシステム構成・パッケ…
Docs: #1743 の配置の図で引数を含む線の名前を引用符で囲む
Merge pull request #1816 from devbasex/design/issue-1743
Merge pull request #1823 from devbasex/feat/issue-1743-m1743
fix(cross-refactoring): 項目の期限を担当へ渡さず、採り直しで空の実装を起動しない(#1825 のレビュー)
takemi-ohama commentedon Oct 7, 2026
ndf v10.17.66 で本番へ配布した(https://github.com/devbasex/ai-plugins/releases/tag/ndf--v10.17.66 、release PR #1831)。リリース後テストの項目は承認資料の「未検証・残る危険」に従い、次の cross-refactoring の実行で確かめる。
Merge pull request #1836 from devbasex/docs/spec-m1743