Skip to content

スプリント m26-1 - #2268

Merged
takemi-ohama merged 73 commits into
developfrom
sprint/m26-1
Oct 31, 2026
Merged

takemi-ohama merged 73 commits into
developfrom
sprint/m26-1

Conversation

@takemi-ohama

Copy link
Copy Markdown
Contributor

スプリント m26-1 の課題を develop へ取り込む。

利用者向けの変化

移行の手順

  • 結果 JSON の契約が変わる。読み手は同じ版の plugins/ndf の中だけなので(前提 4)、同じ PR か同じ版で読み手も直す。利用者の手での移行は要らない(#2227の要求の移行性)(#2227 を実装する(スプリント m26-1) #2254)

課題と設計

コミット

変更の統計

 plugins/ndf/skills/merged/SKILL.md                 |  10 +-
 .../ndf/skills/plan-to-spec/references/excerpt.md  |  10 +-
 plugins/ndf/skills/progress-tracking/SKILL.md      |  43 +-
 .../skills/progress-tracking/references/excerpt.md |  20 +-
 plugins/ndf/skills/release-verification/SKILL.md   |  10 +-
 plugins/ndf/skills/release/SKILL.md                |   4 +-
 .../ndf/skills/release/references/release-steps.md |   7 +-
 plugins/ndf/skills/retrospective/SKILL.md          |   4 +-
 ...s__ndf__scripts__lib__post_queue.py--lines.json |   2 +-
 ..._ndf__scripts__lib__result_posts.py--lines.json |   2 +-
 ...ross-refactoring__scripts__drive.py--lines.json |   1 +
 ...s__refactor_lib__commands__setup.py--lines.json |   2 +-
 ...ls__cross-review__scripts__drive.py--lines.json |   1 +
 ...ipts__review_lib__commands__init.py--lines.json |   1 +
 113 files changed, 3792 insertions(+), 539 deletions(-)

テスト(supervise.py の run のステップ)

ステップ exit 最後の行
collect 0

集めた実装の PR

閉じる課題

Closes #671
Closes #1849
Closes #2079
Closes #2084
Closes #2085
Closes #2129
Closes #2143
Closes #2157
Closes #2183
Closes #2221
Closes #2227
Closes #2229

手動確認

モード: standard / 通した工程: 実装 → Pull Request

🤖 Generated with Claude Code

takemi-ohama and others added 30 commits October 31, 2026 04:01
- validate_result が ok と gaps の同居、gaps の無い終了コード 6 を誤りとして返す
- step_result.py emit の CLI でシェルから同じ形を出せるようにする
- step_read.py に pick_ok_attempt / open_place / place_stop を置く

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
最終スイープを終えても final が approved 以外(max_rounds・oscillation・error)なら、
駆動は status: stopped を返す(drive_pause.unconverged)。報告と件数(metrics.final を含む)は
ok と同じ形で残す。呼び出し側(supervise の DriveStep)は status だけを見る形のまま、
review(on_fail: abort)が失敗になり後続へ進まない。

回答ファイル(--result-file)は収束せずに終わったときも書き、cross-refactoring の
最終ゲートが単独起動で最終ステータスを読めるようにする(#1656)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…欠けとして載せる(#2227)

- lib/step-result.sh に sr_gh / sr_emit / sr_absorb ほかを置き、JSON は step_result.py emit が組む
- 書けなかったときは stopped / 6 と gaps、gh が無ければ 3、何も書けなければ 1
- 配布の記録の無い工程の案内は items の stage-missing へ移す

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 欠け・過程・判断の項目、ok の条件、終了コード 6・75、読む側の規則を README に書く
- progress-tracking の書けなかったときの返し方と結果の読み方を結果 JSON に合わせる

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- fill_queue_pr: 名前の一致する計画の完了した報告・状態ディレクトリが無ければ埋めずに理由を返す。
  完了して PR が無い・飛ばされた計画は従来どおり 0
- fill_stage が埋められないプランに unfilled を付け、queue は ok で返さない
- Engine: コマンドに {queue_pr:…}・{queue_state:…} が残ったステップは打たずに止まり、理由に残った差し込みを出す

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
置き場はあるが結果 JSON が無いときは従来どおり無い材料として書き、置き場が無いときと区別する。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…2227)

- step_read に result_line / not_ok_reason / process_if_not_ok を置き、state.py と sprint-close.py が同じ規則で読む
- 呼び出しの誤りの返し方を step-result.sh の sr_bad_args の 1 つにする
- state.py の snapshot / replay のオブジェクトの列を DICT_LISTS でまとめ、500 行に収める

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nc のテストを結果 JSON へ合わせる(#2227)

- mapfile を read -d '' のループへ、多バイト文字の直前の素の変数を ${} へ
- stage-completeness.md から Skill をまたぐリンクを外す

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2079 を実装する(スプリント m26-1)
利用者の承認(関門 1・関門 2)も答えの記録へ outcome: approved で 1 行書き、count は差し戻しの行だけを数える。
範囲に答えの行が無く、状態ファイルにも承認ゲートの記録が無ければ status: stopped・件数 null・終了コード 3。
outcome の無い既存の行は差し戻しとして数える(今と同じ件数)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2143 を実装する(スプリント m26-1)
…録する(#2183)

設計(fast・auto の MVV 判定と normal の助言)・承認ゲート 2(gate-2・昇格・本番の MVV 判定)のプランに reject を足す。
直してから run <計画> --from reject で流すと、sprint-state.py gate --outcome rejected を打ってから再提示のステップへ進む。
reject は from_only で、並びの次としては通らない(limits.default_next が飛ばす)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
project-mvv.py approve / check・project-decl.py write・glossary.py init は、宣言が
.gitignore の対象なら、除外している行(<ファイル>:<行> とパターン)と対象のファイルを
items(kind note・key gitignore・result ignored)と要約に出す。status は ok のまま。
検出は lib/ndf_tracking.py に寄せ、project-decl の _gitignore_note と
supervise_lib の _ignored の重複を除いた。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
project-analysis.md に「.ndf/ の追跡」を置き、外すのは個人の値(.ndf/.gitignore)と
実行時の出力(handoff/ など)だけとした。除外を検出したときの出力の形もそこに書く。
project-mvv.md の策定の 8 と handoff.md はそこを指す。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…振り返りで読み分ける(#2183)

pace.md・approval-request.md・conductor-entrypoints.md・retrospective の手順を、承認の行も差し戻しの記録へ書くことと、
reject のステップと、count の終了コード 3(未記録)に合わせる。新しい語は足さず、既存の「差し戻しの記録」を使う。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y と sprint_loop.py を行数の上限に収める(#2183)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2157 を実装する(スプリント m26-1)
#2227 を実装する(スプリント m26-1)
- レビューとリファクタリングは、status: ok の試行のうち番号の最も大きいものを読む。ok の試行が無ければ件数を載せず、ok で終わっていないと書く
- 全体テストは status が合否そのものなので、今と同じく最後の試行を読む
- cross-review の見送りは path と summary が同じなら、line の有無・値が違っても 1 件に畳む

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemi-ohama

Copy link
Copy Markdown
Contributor Author

改修計画 — devbasex/ai-plugins #2268

/ndf:cross-refactoring が提案し、改修計画し、適用した改善項目の記録である。
理由と手順は提案の時点でしか残らないため、公開の直前に書き出している。

  • 件数: 採用 10・未確認 0・取り消し 2・見送り 14(うち時間 14)(最終ゲート: passed)
  • 公開: 5387e75 を push した
  • 書き直した時刻: 2026-10-31T09:11:50
  • 対象範囲: conftest.py, docs/glossary.md, docs/glossary/glossary.json, docs/specifications/cross-review-writes-to-conductor.md, docs/specifications/ndf-release-approval-materials.md, docs/specifications/ndf-release-approved-commit.md, docs/specifications/ndf-sprint-close-referenced-issues.md, docs/specifications/ndf-usage-ledger-by-runtime.md, docs/specifications/ndf-worker-agent-and-skill-excerpts.md, docs/specifications/ndf-workflow-unit-and-gates.md, docs/specifications/quality-gates-design-match.md, issues/issue-2229-design.md, plugins/ndf/conftest.py, plugins/ndf/scripts/gate-rejections.py, plugins/ndf/scripts/glossary.py, plugins/ndf/scripts/hook_lib/worktree.py, plugins/ndf/scripts/lib/README.md, plugins/ndf/scripts/lib/approved_commit.py, plugins/ndf/scripts/lib/drive_pause.py, plugins/ndf/scripts/lib/gate_rejections.py, plugins/ndf/scripts/lib/loop_drive.py, plugins/ndf/scripts/lib/ndf_tracking.py, plugins/ndf/scripts/lib/post_queue.py, plugins/ndf/scripts/lib/result_posts.py, plugins/ndf/scripts/lib/run_owner.py, plugins/ndf/scripts/lib/run_state.py, plugins/ndf/scripts/lib/run_state_kinds.py, plugins/ndf/scripts/lib/sprint_loop.py, plugins/ndf/scripts/lib/step-result.sh, plugins/ndf/scripts/lib/step_read.py, plugins/ndf/scripts/lib/step_result.py, plugins/ndf/scripts/merged-steps.py, plugins/ndf/scripts/progress-record.sh, plugins/ndf/scripts/project-decl.py, plugins/ndf/scripts/project-mvv.py, plugins/ndf/scripts/projects-sync.sh, plugins/ndf/scripts/release-steps.py, plugins/ndf/scripts/release_lib/approval.py, plugins/ndf/scripts/release_lib/materials.py, plugins/ndf/scripts/sprint-close.py, plugins/ndf/scripts/sprint-state.py, plugins/ndf/scripts/supervise_lib/commands.py, plugins/ndf/scripts/supervise_lib/delivery_templates.py, plugins/ndf/scripts/supervise_lib/engine.py, plugins/ndf/scripts/supervise_lib/limits.py, plugins/ndf/scripts/supervise_lib/plan.py, plugins/ndf/scripts/supervise_lib/queue.py, plugins/ndf/scripts/supervise_lib/queue_fill.py, plugins/ndf/scripts/supervise_lib/release_templates.py, plugins/ndf/scripts/supervise_lib/sprint_routes.py, plugins/ndf/scripts/supervise_lib/sprint_waves.py, plugins/ndf/scripts/supervise_lib/state.py, plugins/ndf/scripts/supervise_lib/verify_steps.py, plugins/ndf/scripts/worktree-deps.sh, plugins/ndf/skills/backlog-refinement/SKILL.md, plugins/ndf/skills/backlog-refinement/scripts/upkeep.py, plugins/ndf/skills/backlog-refinement/scripts/upkeep_report.py, plugins/ndf/skills/cross-refactoring/scripts/drive.py, plugins/ndf/skills/cross-refactoring/scripts/refactor.py, plugins/ndf/skills/cross-refactoring/scripts/refactor_lib/commands/setup.py, plugins/ndf/skills/cross-review/SKILL.md, plugins/ndf/skills/cross-review/scripts/drive.py, plugins/ndf/skills/cross-review/scripts/review_lib/commands/init.py, plugins/ndf/skills/cross-review/scripts/state.py, plugins/ndf/skills/development-workflow/references/approval-request.md, plugins/ndf/skills/development-workflow/references/conductor-entrypoints.md, plugins/ndf/skills/development-workflow/references/handoff.md, plugins/ndf/skills/development-workflow/references/pace.md, plugins/ndf/skills/development-workflow/references/project-analysis.md, plugins/ndf/skills/development-workflow/references/project-mvv.md, plugins/ndf/skills/development-workflow/references/stage-completeness.md, plugins/ndf/skills/merged/SKILL.md, plugins/ndf/skills/plan-to-spec/references/excerpt.md, plugins/ndf/skills/progress-tracking/SKILL.md, plugins/ndf/skills/progress-tracking/references/excerpt.md, plugins/ndf/skills/release-verification/SKILL.md, plugins/ndf/skills/release/SKILL.md, plugins/ndf/skills/release/references/release-steps.md, plugins/ndf/skills/retrospective/SKILL.md, scripts/script-structure-allow/plugins__ndf__scripts__lib__post_queue.py--lines.json, scripts/script-structure-allow/plugins__ndf__scripts__lib__result_posts.py--lines.json, scripts/script-structure-allow/plugins__ndf__skills__cross-refactoring__scripts__drive.py--lines.json, scripts/script-structure-allow/plugins__ndf__skills__cross-refactoring__scripts__refactor_lib__commands__setup.py--lines.json, scripts/script-structure-allow/plugins__ndf__skills__cross-review__scripts__drive.py--lines.json, scripts/script-structure-allow/plugins__ndf__skills__cross-review__scripts__review_lib__commands__init.py--lines.json, tests, plugins/ndf/scripts/tests, plugins/ndf/skills/backlog-refinement/tests, plugins/ndf/skills/cross-refactoring/tests, plugins/ndf/skills/cross-review/tests, plugins/ndf/skills/cross-review/scripts/tests, plugins/ndf/skills/development-workflow/tests, plugins/ndf/skills/merged/tests, plugins/ndf/skills/release/tests, scripts/tests
  • テストの戦略: local-scoped-ci-whole(根拠 derived:test_duration)
  • 範囲テストの雛形: uv run --frozen --project . --all-extras pytest {paths} -q -n 4 -o junit_family=xunit1 --junitxml=.ndf/tmp/junit.xml / npm --prefix factory ci --no-audit --no-fund --silent && factory/node_modules/.bin/vitest run --root factory {paths} / python3 scripts/check-script-structure.py {paths}(静的解析) / bash scripts/check-lint.sh -- {paths}(静的解析)
  • 最終ゲートへ寄せた危険フラグ: D1, D3, D4, D5(項目 I-001, I-005, I-004, I-007, I-006, I-008, I-012)
  • 着手前のテスト: uv run --frozen --project . --all-extras pytest plugins/ndf/scripts/tests plugins/ndf/skills/backlog-refinement/tests plugins/ndf/skills/cross-refactoring/tests plugins/ndf/skills/cross-review/scripts/tests plugins/ndf/skills/cross-review/tests plugins/ndf/skills/development-workflow/tests plugins/ndf/skills/merged/tests plugins/ndf/skills/release/tests scripts/tests tests -q -n 4 -o junit_family=xunit1 --junitxml=.ndf/tmp/junit.xml && python3 scripts/check-script-structure.py && bash scripts/check-lint.sh(scope)
  • 着手前のテストの結果: 通過(651.7 秒 / HEAD fda7282)
  • 既存失敗の件数: 0
  • 想定最大時間: 75 分 / 改修計画の時点で使えた時間: 36.65 分
  • 実装担当: claude

改善項目

I-001 — plugins/ndf/scripts/lib/approved_commit.py#compare_approved

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method major high claude / codex / kiro 採用 1

なぜ: 承認したコミットから先端までの比較が、読める存在の確認・祖先の判定・承認の外のコミットの収集・shipped による退避・木の比較という直列の段を 1 関数で進め、認知的複雑度 33・CC 12・return が 9 本。各段は前段の出力を次段の入力にする直列の処理で、連鎖へ分解できる

手順: 1. 存在の確認(approved/tip/allowed.head)を _commits_resolvable(root, approved, tip, allowed) -> bool へ抽出
2. 承認の外のコミットの収集と shipped による退避を _classify_outside(root, approved, tip, allowed, shipped) -> (outside, tolerated) | None へ抽出
3. 木の比較を _tree_matches(root, v, approved, allowed, shipped) -> bool | None へ抽出
4. compare_approved は各段を順に呼び、Verdict を組み立てるだけにする
5. test_approved_commit.py / test_release_approved_commit.py を実行し、Verdict の reason・outside・tolerated が不変であることを確かめる

I-002 — plugins/ndf/scripts/supervise_lib/queue_fill.py#fill_queue_pr

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method major high claude / codex / kiro 採用 1

なぜ: {queue_pr:<名>} の解決と {queue_state:<名>} の解決という別々の差し込みの埋めが 1 関数に同居し、認知的複雑度 29・CC 8・分岐 7。2 つのループは共有する text を順に置換するだけで、それぞれ独立した段階として名前が付けられる

手順: 1. _fill_prs(text, names, items, plan) -> (text, missing) を抽出する(完了した結果の PR の番号で置き換え、無ければ欠けの文を返す)
2. _fill_states(text, states, items, plan) -> (text, missing) を抽出する(? 付きは空文字で埋める現状を保つ)
3. fill_queue_pr は読み込み・2 つの呼び出し・欠けがあれば理由・無ければ write_text_atomic の順だけにする
4. test_supervise_pace.py・test_release_check_state.py・test_supervise_layout.py を流す

I-003 — plugins/ndf/scripts/glossary.py#cmd_merge

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method major high codex / kiro 取り消し 0

なぜ: 1 関数が MERGE_HEAD の確認・段(stage 1/2/3)の読み取りと検証・用語集のマージ・ファイル書き込み・git add・commit を通しで行い、認知的複雑度 37・CC 16・分岐 13・49 文に達する。段の読み取りと検証(for n in (1,2,3) のループと parse_glossary・bad_keys)は名前の付く独立した段階で、cmd_merge の制御の流れから切り出せる

手順: 1. test_glossary.py の実際の git による merge 系テストを基準にし、段 1 が無いケース、削除された側、不正な JSON・キー、文書だけの衝突が通るか確認する。足りないケースだけ先に現状固定テストを足す。
2. root・source・存在する段の集合の 3 引数で段 1〜3 の用語集を返す補助関数を、同じファイル内へ抽出する。段が無い場合の既定値と unreadable の文言を保持する。
3. cmd_merge の読み取り部分を呼び出しへ置き換える。失敗時に書かない順序、git add・commit のタイミング、結果 JSON と終了コードを変えず merge 系テストを実行する。

取り消した理由: 文書の文言を固定するテストは足さない(plugins/ndf/scripts/tests/test_glossary.py: docs/glossary.md)

I-004 — plugins/ndf/scripts/supervise_lib/limits.py#_targets

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method major medium kiro / codex 採用 1

なぜ: judge のステップの遷移の収集と、それ以外のステップの遷移の収集(next / skip_to / gate_next / on_fail / on_section_missing / on_exit)が 1 関数に同居し、認知的複雑度 32・CC 16・分岐 15。先頭の if step.get('type') == 'judge': の塊は早期 return で閉じており、独立した関数へ切り出せる

手順: 1. judge の choices を処理する部分を _judge_targets(steps, step) -> list へ抽出する
2. 残りの遷移キー(next/skip_to/gate_next/on_fail/on_section_missing/on_exit)の収集を _edge_targets(steps, step) -> list へ抽出する
3. _targets は type を見てどちらかへ振り分けるだけにする
4. test_limits.py / test_supervise_limits.py を実行し、unknown_targets・loops・step_limit の値が不変であることを確かめる

I-005 — plugins/ndf/scripts/hook_lib/worktree.py#notice

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method major medium codex / kiro 採用 3

なぜ: 事象の種類での分岐(userPromptSubmit / PreToolUse)・書き込み先の相対化と許可の判定・既に案内した先の重複除去と状態の保存・出力の組み立てが 1 関数に同居し、認知的複雑度 25・CC 13・分岐 12・return が 8 本。許可の判定の塊と重複除去の塊はそれぞれ名前の付く段階である

手順: 1. 書き込み先を相対化して許可の判定で絞る部分を _flagged_targets(got, where) -> list[str] へ抽出
2. 既に案内した先の除去と状態の保存を _dedupe_notified(path, state, flagged) -> list[str] へ抽出
3. notice は抽出した関数を呼び、空なら None を返し、残れば _output を呼ぶだけにする
4. test_hook_words.py / test_worktree 系のテストを実行し、notice の返り値(辞書・文字列・None)が不変であることを確かめる

I-006 — plugins/ndf/scripts/release-steps.py#cmd_release

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method major medium codex 採用 1

なぜ: 107 行の関数が、配布用ブランチの検査、既存 PR の再利用可否、チェック結果を含む PR 本文、本番の承認比較と昇格、タグ・後片付けの結果まで組み立てる。PR の説明文を変えるだけでも承認と昇格の制御を含む関数を編集することになる。

手順: 1. test_release_steps.py と test_release_approved_commit.py を基準に、開発版・本番・マージ済み PR への追加コミット・先端移動の経路を確認する。
2. 既存 PR を探し、マージ済みなら追加コミットの有無を確認する部分を root・branch・base の補助関数へ抽出する。fetch と祖先判定の順序はそのままにする。
3. CHANGELOG の節と run_checks の結果から PR 本文を組む部分を root・args・plugin・plugins の補助関数へ抽出する。各チェックの実行回数と PR が無いときだけ実行する条件を保持する。
4. cmd_release を上記の呼び出しへ置き換える。本番の承認検査・再比較・昇格・公開の条件は動かさず、両テスト群を実行する。

I-007 — plugins/ndf/scripts/supervise_lib/sprint_waves.py#plan_sprint_design

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method major medium kiro 採用 1

なぜ: 設計のフェーズのプランを 1 関数で組み立てており、本体が 165 行とファイル内で最長。steps のリストが設計の工程の入口の検査・要求・設計・PR・レビュー・用語チェックの各ステップを 1 つの辞書リテラルに連ねている。工程のまとまりごとに steps を作る補助関数へ切り出すと、各まとまりを単体で読め、plan_advise_design / plan_mvv_design からの改変も追いやすくなる

手順: 1. 用語チェックのまとまり(glossary-check / fix-glossary / glossary-recheck / push-glossary)を _glossary_steps(glossary_check, push) -> list へ抽出
2. レビューのまとまり(review / sync-review / requirements-recheck)を _review_steps(a) -> list へ抽出
3. plan_sprint_design は抽出した steps のリストを連結して steps を作る
4. test_supervise.py / test_supervise_pace*.py を実行し、生成されるプランの steps(id・遷移)が不変であることを確かめる

I-008 — plugins/ndf/skills/backlog-refinement/scripts/upkeep_report.py#cmd_report

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method major medium codex 採用 1

なぜ: 83 行の関数が 3 種の記録を読み、候補の集計、apply の旧形式補完と区分集計、合算できない記録の欠け判定、表示項目と最終結果まで組み立てる。apply の記録互換性を直すたびに、report 全体の出力処理も編集範囲へ入る。

手順: 1. test_upkeep_script.py の report 系、特に同一回の apply の合算・古い記録・後からの承認・記録不足、および test_upkeep_rank_cli.py の report ケースを基準にする。
2. apply の記録から items・metrics・gaps を返す _apply_report(app) を抽出する。旧形式を最後の一回として読む条件と、lost の扱いをそのまま移す。
3. cmd_report は読み込み、候補・apply・rank の結果の組み合わせ、emit に絞る。辞書とリストの順、件数・wait_seconds・欠けがあるときの status と summary を既存テストで確認する。

I-009 — plugins/ndf/scripts/lib/result_posts.py#queue_for

兆候 手法 重要度 等級 提案元 状態 コミット
duplication extract_method minor medium claude 採用 1

なぜ: 一時の置き場 os.environ.get('CROSS_REVIEW_TMP_DIR') or str(worktree / TMP_DIRNAME) が queue_for と _resolve_fix_inputs の 2 か所に同じ式で書かれている。置き場の規則が片方だけ変わると待ち行列と修正の結果ファイルが別の場所を指す

手順: 1. _tmp_base(worktree) -> pathlib.Path を抽出する
2. queue_for と _resolve_fix_inputs の式を _tmp_base の呼び出しへ置き換える
3. test_result_posts.py を流す

I-010 — plugins/ndf/skills/cross-refactoring/tests/crossref_helpers.py#_item

兆候 手法 重要度 等級 提案元 状態 コミット
duplication extract_test_helper major medium claude 取り消し 0

なぜ: 計画済みの項目(id・rank・path・smell・estimate・commits・estimated_diff_lines など 25 鍵)を組む _item が test_culprit_git・test_stop_revert_git・test_whole_test_triage_git・test_fix_rules_git・test_assert_changes・test_final_gate・test_kinds_and_launch_git・test_structure_check_scope_git・test_after_plan_no_llm_git・test_readopt_git・test_scope_verdict_git の 11 本に写されている(指標の重複の上位 10 件の大半がこの形)。状態の項目の形が変わるたびに 11 か所を直すことになる

手順: 1. crossref_helpers に planned_item(item_id, rank, path='src/calc.py', **over) を足す(現状の共通の 25 鍵を既定にし、over で上書きする)
2. 11 本のテストの _item を、ファイルごとの差(path・command・estimate など)を over へ移して planned_item の呼び出しへ置き換える
3. 各ファイルの import に planned_item を足し、使わなくなった定数(FAR など)の import を整理する
4. cross-refactoring のテストを全部流し、件数が変わらないことを確かめる

取り消した理由: テストの期待する振る舞いが変わっています(plugins/ndf/skills/cross-refactoring/tests/test_after_plan_no_llm_git.py, plugins/ndf/skills/cross-refactoring/tests/test_culprit_git.py, plugins/ndf/skills/cross-refactoring/tests/test_scope_verdict_git.py, plugins/ndf/skills/cross-refactoring/tests/test_stop_revert_git.py)。構造改善では期待出力を変えません。振る舞いの変更は別の変更に分けてください

I-011 — plugins/ndf/scripts/lib/run_state.py#_sweep_session

兆候 手法 重要度 等級 提案元 状態 コミット
duplication extract_method minor medium claude 採用 2

なぜ: _sweep_session と _sweep_deps が同じ 3 分岐(持ち主の記録が無い → 寿命の窓・持ち主のプロセスが居る → kept・居ない → 消して removed)と同じ理由の文を別々に書いている

手順: 1. _owned_item(kind, path, pid, is_alive, mtime, now, remove) -> dict を抽出する(pid が None なら _window_item、is_alive() が真なら『持ち主のプロセス {pid} が動いている』で kept、それ以外は remove() して removed)
2. _sweep_session のループ本体を _owned_item の呼び出しへ置き換える(is_alive は lambda: _process_alive(*owner))
3. _sweep_deps も同じく置き換える(is_alive は lambda: _process_alive(pid, None, 'worktree-deps.sh'))
4. test_run_state.py の session_state・deps_work のテストを流す

I-012 — plugins/ndf/scripts/lib/run_state.py#remove_review_worktree

兆候 手法 重要度 等級 提案元 状態 コミット
dead_code change_signature minor low claude 採用 1

なぜ: remove_review_worktree・remove_run_dir・remove_pr_dir の引数 pr は本体で一度も使われず、受け渡されるだけである。呼び手(_sweep_one_review・merged-steps)が意味のない値を渡し続け、引数の列が長く読める

手順: 1. remove_review_worktree から pr を外す
2. remove_run_dir・remove_pr_dir から pr を外し、中の呼び出しを合わせる
3. _sweep_one_review の 2 か所の呼び出しから pr を外す
4. merged-steps._remove_pr_tmp_worktrees の remove(root, path, n, state) を remove(root, path, state) にする
5. テストに直接の呼び出しが無いことを grep で確かめ、test_run_state.py を流す

指標の測定

  • 状態: written / 言語とツールの対応: 既定(.ndf/code-metrics.json は無い) / 所要: 74.9 秒(使えた時間 225 秒 / 上限 225 秒)
  • 指標のファイル: /tmp/ndf-worktrees/devbasex--ai-plugins/rf2268/work/.cross_refactoring/code-metrics-rf2268.md
言語 ツール 版 ランナー ファイル 秒 結果
python ruff-complexipy ruff 0.16.9 / complexipy 8.0.1 uvx 488 1.1 測った
shell — — — 17 — unsupported_language
重複: python symilar pylint 4.0.9 uvx 488 71.0 測った(37 箇所)
重複: shell jscpd jscpd 4.3.0 npx 17 1.2 測った(0 箇所)

時間の上限

値 中身
提案の枠の終わり(監視の上限 = 残り + 余裕) 2026-10-31T08:37:07+00:00
改修計画の枠の終わり(同上) 2026-10-31T08:44:37+00:00
テストの追加の終わり = 実装の終わり − Σ(採っていて未検証の項目の実装の見積り) 2026-10-31T08:55:35+00:00
実装の終わり = 最終ゲートの修正の打ち切り − バッファ − Σ(採っていて未検証の項目の検証の見積り) 2026-10-31T08:56:03+00:00
直しの試行の打ち切り 2026-10-31T09:09:31+00:00
想定最大時間の終わり H(子プロセスはすべてここまでに止まる) 2026-10-31T09:25:25+00:00
確かめの開始の締め切り = H − 確かめの見込み(最終ゲート修正と打ち切りの後の取り消しもここまで) 2026-10-31T09:12:08+00:00
確かめの見込み(秒。最終ゲートの確かめ 1 回。バッファの最終ゲートの全体テスト) 797
最終ゲート修正 1 回の見込み(秒。バッファの final_fix。起動は今 + この値が確かめの開始の締め切り以前のときだけ) 157
指標の測定の上限(秒。提案の枠の中から割く) 225
着手前のテスト 1 回の上限(秒) 1620
範囲テスト 1 回の上限(秒) 1956
手元の全体テスト 1 回の上限(秒) 4554
CI の待ちの上限(秒) 2391
余裕(秒。手順の上限と CLI の上限に足す) 225

入力: 予算 75 分 / 全体テストの所要 w 1518.0(ci-steps) / 着手前の実測 x 651.7 / CI の壁時計 c 797.0 / 範囲テストの所要 s 540.0(history) / 戦略 local-scoped-ci-whole

無音の打ち切りは手順の監視の上限と同じ値である。項目ごとの期限は持たない(実装を止めるのは実装の終わりだけ)。

見送った提案

対象 兆候 理由 根拠(MVV) 補足
plugins/ndf/scripts/supervise_lib/limits.py#_targets deep_nesting duplicate Value 4 / Value 1 / Value 6 C-007 と同じ変更
plugins/ndf/scripts/merged-steps.py#_remove_pr_tmp_worktrees duplication budget Value 6 / C4 / Value 7 見積り 19.3 分が残りに入らない
plugins/ndf/scripts/lib/run_state.py#remove_review_worktree duplication budget Value 6 / C4 見積り 11.7 分が残りに入らない
plugins/ndf/scripts/lib/step_result.py#_check_status_code duplication budget Value 6 / Value 4 見積り 11.7 分が残りに入らない
plugins/ndf/scripts/lib/run_state.py#sweep_states scattered_config budget Value 6 / Value 7 / Value 8 見積り 13.4 分が残りに入らない
plugins/ndf/scripts/glossary.py#text_findings duplication budget Value 6 / Value 8 / Value 1 見積り 19.3 分が残りに入らない
plugins/ndf/scripts/supervise_lib/sprint_waves.py#plan_sprint_impl duplication budget Value 6 見積り 19.3 分が残りに入らない
plugins/ndf/scripts/supervise_lib/queue_fill.py#results_named duplication budget Value 6 見積り 11.7 分が残りに入らない
plugins/ndf/skills/cross-refactoring/tests/test_culprit_git.py#_implement duplication budget Value 6 / Value 1 見積り 12.0 分が残りに入らない
plugins/ndf/skills/cross-refactoring/tests/test_culprit_git.py#_item duplication budget Value 6 / Value 1 見積り 12.0 分が残りに入らない
plugins/ndf/scripts/release_lib/materials.py#check_lines conditional_chain budget Value 2 / Value 1 見積り 12.3 分が残りに入らない
plugins/ndf/scripts/tests/test_release_check_state.py#test_queue_state_takes_the_named_plan_state_dir test_bypasses_module_boundary budget Value 6 / Value 1 見積り 12.3 分が残りに入らない
plugins/ndf/scripts/lib/run_owner.py#_now_iso magic_value budget Value 6 見積り 12.9 分が残りに入らない
plugins/ndf/scripts/supervise_lib/release_templates.py#_prepare_steps data_clump budget Value 4 / Value 1 / Value 6 見積り 14.8 分が残りに入らない
plugins/ndf/scripts/merged-steps.py#_cleanup_result duplication budget Value 6 見積り 19.3 分が残りに入らない

@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 | codex | REQUEST_CHANGES

修正指摘3件(major)。

@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 | REQUEST_CHANGES

大規模なスプリント PR(#2229 の run_state・#2221 の配布物判定・#2079 の投稿控え・#1849・#1340・#2183 ほか)に rf2268 の構造改善を重ねたもの。抽出した関数(queue_fill・limits・sprint_waves・approved_commit・worktree・result_posts・upkeep_report)は振る舞いを保っており、approval ゲートの shipped 判定・head_moved の再マージ(3 回)は読めない入力で必ず gate へ倒れる fail-safe になっていて、承認の迂回は確認できなかった。指摘は merged cleanup の集計 1 件のみ。

Comment thread plugins/ndf/scripts/merged-steps.py Resolved
- queue_fill: {queue_pr:<名>} は「関門」で終えた設計プランの PR も埋める(design-merge が止まらない)
- approved_commit: 配布物の変更パスを -z と --no-renames で読み、日本語のパスと配布物から外への移動を見落とさない
- merged-steps: own と swept を値でなく印で分け、処理済みの pr<n>/rf<n> を sweep_states の skip へ渡す

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemi-ohama

Copy link
Copy Markdown
Contributor Author

🔧 /ndf:fix サマリ | round 1 | commit ad4f7b9

対応件数: critical=0 / major=4 / minor=0(合計 4 件)
決着: 4 件 / 見送り: 0 件 / 却下: 0 件
CI: SUCCESS

@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 2 | claude | REQUEST_CHANGES

修正指摘 2 件(major)。(1) cross-review の未収束を終了コード 1・gaps 無しの stopped で返すため、検査のプランの review(on_fail: abort)が max_rounds のたびに中断し、設計の決定 1(終了コード 6 と gaps で on_exit により振り分ける)と食い違う。(2) 承認の外のコミットを通す判定が配布物の拒否リスト(plugins/・.claude-plugin/)だけで、秘密を使うワークフローが実行する scripts/・.github/ の変更が承認ゲート 2 を通らずに main へ入る。

@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 2 | kiro | APPROVE

round 1 の kiro の唯一の指摘(merged cleanup の集計の二重計上)と codex の 3 件(queue_fill の関門・approved_commit の NUL/-z と --no-renames)は ad4f7b9 で解消を確認した。承認境界(compare_approved の shipped 判定・check_approved が SHIPPED を渡す・HeadMoved の 3 回の再マージ)は、読めないコミット/木を「配布物に触れた」とみなして必ず gate へ倒す fail-safe で、承認の迂回は確認できなかった。run_state.py の片付けは作業の有無を確かめてから --force なしで外し、設計文書(approved-commit・quality-gates)も実装と整合する。このラウンドで新たに書く critical/major の指摘は無い(APPROVE)。

- cross-review の未収束(final が approved 以外)を stopped・終了コード 6・gaps(kind: review)で返す。
  drive のステップでも on_exit を読み、検査のプランの review は 6 を base-sync へ回す(#2227 の決定 1)
- 承認の外のコミットを通す判定を、配布物の拒否リストから許可リスト(docs/・issues/)へ反転する。
  scripts/・.github/ など秘密を渡す CI が実行する未承認の変更を承認ゲート 2 で止める(C1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemi-ohama

Copy link
Copy Markdown
Contributor Author

🔧 /ndf:fix サマリ | round 2 | commit f4ffafa

対応件数: critical=0 / major=2 / minor=0(合計 2 件)
決着: 2 件 / 見送り: 0 件 / 却下: 0 件
CI: SUCCESS

@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 3 | claude | REQUEST_CHANGES

修正指摘 1 件(major)。round 2 の直しで未収束を終了コード 6 にした条件が final != approved で、レビューそのものが成立しなかった final=error(席を選べない・修正のコード関連 CI 失敗)まで終了コード 6 になり、検査のプランの on_exit {"6": "base-sync"} 経由でマージまで進む。

@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 3 | codex | REQUEST_CHANGES

修正指摘2件(major)。

- cross-review の終わりが final=error(レビューが成立していない)なら終了コード 1 の中断で返し、
  終了コード 6(gaps)は max_rounds・oscillation だけにする。検査の review の on_exit["6"] でマージへ進まない
- 未収束で ok の試行が無いレビューでも、見送った指摘の件数と本文・位置を承認資料へ載せる

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemi-ohama

Copy link
Copy Markdown
Contributor Author

🔧 /ndf:fix サマリ | commit a6855a5

対応件数: critical=0 / major=0 / minor=0(合計 0 件)
決着: 3 件 / 見送り: 0 件 / 却下: 0 件
CI: NONE

@takemi-ohama
takemi-ohama marked this pull request as ready for review October 31, 2026 10:32
@takemi-ohama
takemi-ohama merged commit c935521 into develop Oct 31, 2026
25 checks passed
@takemi-ohama
takemi-ohama deleted the sprint/m26-1 branch October 31, 2026 10:32
@takemi-ohama

Copy link
Copy Markdown
Contributor Author

MVV 判定(関門 2(本番への配布の承認))

  • 判定: follow(関門を省いた。利用者が承認した MVV を事前の許可として扱う)
  • 根拠: Mission / Vision / Value 1 / Value 2 / Value 3 / Value 6 / Value 7 / C3 / C4 / C5 / C6 / C7 / P1(プロジェクト MVV: approved・版 3)
  • 時刻: 2026-10-31T10:36:46+00:00
  • ログ: /home/ubuntu/.local/state/ndf/mvv-gate.jsonl の 2026-10-31T10:36:46+00:00 の行

理由

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