Skip to content

スプリント m26-2 - #2318

Merged
takemi-ohama merged 52 commits into
developfrom
sprint/m26-2
Nov 1, 2026
Merged

takemi-ohama merged 52 commits into
developfrom
sprint/m26-2

Conversation

@takemi-ohama

Copy link
Copy Markdown
Contributor

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

利用者向けの変化

移行の手順

  • NDF を agy または kiro へ入れている場合、新しい版からは更新が届きません。配布から外れた Skill を手元から消すかどうかは、利用者が判断してください。NDF の側から利用者の手元の導入物を消すことはしません。(#2231 を実装する(スプリント m26-2) #2306)
  • sprint-close.py の閉じる条件が増える(契約の変更)。呼ぶのは同じ版の plugins/ndf の中のプラン・Skill の本文だけなので、同じ版で呼ぶ側も直す。利用者の手での移行は要らない。この版より前に工程を通り、判定の材料を持たないまま開いている課題の扱いは未決 2(#2228の要求の移行性)(#2228 を実装する(スプリント m26-2) #2308)

課題と設計

コミット

変更の統計

 scripts/tests/test_validate_manifests_version.py   |  98 ----
 scripts/tests/test_validate_mcp_codex_servers.py   |   3 +-
 scripts/tests/validate_manifests_helpers.py        |  18 -
 scripts/validate-runtime-plugins.sh                |  36 +-
 tests/runtime-smoke/Containerfile.agy              |  30 --
 tests/runtime-smoke/Containerfile.kiro             |  28 -
 tests/runtime-smoke/README.md                      |  14 +-
 tests/runtime-smoke/adapters/agy.sh                |  18 -
 tests/runtime-smoke/adapters/kiro.sh               |  25 -
 .../assertions/assert-authenticated-smoke.sh       |  18 -
 .../assertions/assert-hook-fixtures.sh             |  19 -
 .../runtime-smoke/assertions/assert-kiro-agent.sh  | 390 --------------
 .../assertions/assert-plugin-files.sh              |  80 ---
 tests/runtime-smoke/cli-versions.env               |  13 +-
 225 files changed, 1788 insertions(+), 8371 deletions(-)

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

ステップ exit 最後の行
collect 0

集めた実装の PR

閉じる課題

Closes #2082
Closes #2119
Closes #2143
Closes #2144
Closes #2228
Closes #2231
Closes #2288

手動確認

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

🤖 Generated with Claude Code

takemi-ohama and others added 30 commits October 31, 2026 13:03
本番のプランの verify は verify-install だけを流すため、stage を「配布」にする。
「リリース後テスト」の stage は、まとめのプランで受け入れ条件ごとに確かめて配布の記録の
Pull Request へ記録を書く release-verify だけが持つ。release-verify の依頼文に、スプリントの
Pull Request の「手動確認」でリリース後テストへ回した項目と未検証の項目を行として載せることを足した。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lib/closing.py に閉じる予定の参照(最終工程の後に閉じる: #N)と defer_closing を足し、closing-issues.sh と
closing_issues / closing_refs / closing_numbers が 2 つの形を読む。pr-steps.py と supervise_lib/pr.py は、宛先が
既定ブランチ(決められないときを含む)なら本文を置き換えてから送る(lib/repo.py の merge_closes_issues)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review の on_exit {6: base-sync} を外し、未収束(終了コード 6)も on_fail: abort で止める。
雛形の review を疑似の駆動で流すテストと、契約の fixture を合わせた。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--final-stage(配布 / リリース後テスト / 振り返り。省けば振り返り)を受け、閉じる条件 3 を課題ごとに判定する。
振り返りは課題の本文の「振り返り: <コメントの URL>」の行のうち、識別子が記録の PR の最後の配布の記録のコメントの
識別子以上のものを数える(lib/dist_record.py の dist_comment_id。記録の PR の読みは 1 回のまま)。本文を読めなければ
failed で止まる。リリース後テストは --with-verification の有無にかかわらず条件 2 を見る。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
merge →(release-verify)→ retro → close → refine の並びにし、close は --final-stage 振り返りを明示して渡す。
retro の指示に課題を閉じない旨を足す。契約の写し(plans/close/4-close.json)を新しい並びに合わせる。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pr-steps.py と supervise_lib/pr.py が同じ判定(merge_closes_issues → defer_closing)を持たないようにする。
番号で指した PR の宛先は既存の pr_for_report で読む(REST の退避も同じものを使う)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
閉じる条件 3(最終工程の記録)・--final-stage の値と呼ぶ側の対応・まとめのプランの並び・閉じる予定の参照を
正本へ書く。pr・release-verification・retrospective・release・merged と development-workflow の references は
閉じる条件と順序を写さず正本を指す。用語集の「最終工程の記録」をその実行の振り返りに絞り、docs/glossary.md を作り直す。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2288 を実装する(スプリント m26-2)
- acceptance-check.py record / show が本文の「## 受け入れ条件の確認」の表を書く・読む
- read_unverified はマージ前に確かめた条件を「未実施のリリース後テスト」に載せない
- judge_acceptance はマージ前に確かめた条件に合格の行を求めない
- 記録の無い課題は今までどおり

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
配布先を Claude Code と codex に限る。agy・kiro は cross-review / cross-refactoring の
相手役として起動するだけにする(設計の決定 1)。

- plugins/ndf/dev.agy・各プラグインの dev.kiro・agy-skills.txt・kiro-skills.txt を消す
- build-runtime-plugins.sh・validate-runtime-plugins.sh・validate_manifests.py から agy・kiro の生成と検査を外す
- 一覧の予算・文書の古さの検査・スモーク(matrix・adapter・像・版の一覧)から kiro・agy を外す
- release.runtimes・pace.json の導入の確認・release-verification-steps.py の kiro の導入確認を外す
- .ndf/project.json の required_checks から runtime-smoke (kiro)・(agy) を外す(ruleset は承認ゲート 2)
- 配布先が claude・codex だけであることを確かめる test_distribution_runtimes.py を足す

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- AGENTS.md・README・各プラグインの README・ndf-plugin-reference・versioning-and-distribution・
  plugin-development-guide・project-overview・AUTHORING・スモークの README を 2 ランタイムの配布へ書き直す
- KIRO.md を相手役として起動される Kiro CLI の説明へ縮め、plugins/ndf/docs/kiro-cli.md を消す
- plugins/ndf/README.md に、前の版で agy・Kiro CLI へ入れた手元の残し方と消し方を書く
  (一時の HOME で前の版を入れ、消し方のコマンドと clone を進めた後の kiro の hook を確かめた)
- 消した agy_agents.py への確定仕様のリンクを外す(リンク検査が落ちるため)
- lint: 使わなくなった import と整形

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- backlog-refinement・document-rebuild の配布のテストを claude・codex の manifest に限る
- cross 系・external-ai の同梱のテストが数える manifest を 2 つにする
- 必須のチェックの突き合わせのテストの ruleset の例から runtime-smoke (kiro)・(agy) を外す

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2144 を実装する(スプリント m26-2)
…s.py の PR の読み書きを pr_steps_lib へ分ける(#2228)

- sprint_close_lib/final_stage.py: 閉じる条件 3(final_stage_gap・gap_item と最終工程の定数)
- sprint_close_lib/collect.py: 記録の PR の読み取り(read_record)、スプリントの PR の課題の集め方(sprint_issues)、参照だけの課題(referenced_items)
- pr_steps_lib/gh_pr.py: repo_owner_name・existing_pr・pr_for_report・target_pr・send_body・rest_create
- pr-steps.py が 500 行以下になったため、例外リストの行数の項目を消す

振る舞いは変えない。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KYHP7yPdcB8dBzbZpQCnR4
#2143 を実装する(スプリント m26-2)
衝突 2 件を両方の変更を残して解いた(sprint-close.py の説明文、4-close.json の release-verify の依頼文と close の位置)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
設計の構成要素の契約の写しのパスをリポジトリの根からの形に直す。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2228 を実装する(スプリント m26-2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2231 を実装する(スプリント m26-2)
…ise_pace.py#new_fast_sprint

`new sprint` を起動する長い引数列を tests/sprint_args.py の new_sprint_args へ移した。
既定の名前・課題・版数を持ち、差分(name・issue・design・version と末尾のフラグ)だけを受ける。
test_supervise.py・test_supervise_pace.py・test_supervise_new.py の写し取りをこの補助の呼び出しへ置き換えた。
期待値は変えていない。

Item-Id: I-015
Impl-Runtime: claude
Impl-Model: claude-opus-5-5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takemi-ohama

Copy link
Copy Markdown
Contributor Author

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

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

  • 件数: 採用 0・未確認 14・取り消し 1・見送り 5(うち時間 5)(最終ゲート: 未実行)
  • 公開: 4042a6b を push した
  • 書き直した時刻: 2026-10-31T20:00:48
  • 対象範囲: .github/workflows/runtime-plugin-authenticated-smoke.yml, .github/workflows/runtime-plugin-smoke-latest.yml, .github/workflows/runtime-plugin-smoke.yml, .ndf/pace.json, .ndf/project.json, .ndf/supervise.json, AGENTS.md, KIRO.md, README.md, docs/glossary.md, docs/glossary/glossary.json, docs/ndf-plugin-reference.md, docs/plugin-development-guide.md, docs/project-overview.md, docs/specifications/ndf-backlog-refinement-stage.md, docs/specifications/ndf-cleanup-and-bundle-closing.md, docs/specifications/ndf-sprint-close-referenced-issues.md, docs/specifications/ndf-sprint-misjudgments-unknown-record-and-manual-none.md, docs/specifications/ndf-workflow-development-loop.md, docs/specifications/runtime-plugin-distribution.md, docs/versioning-and-distribution.md, issues/issue-2228-design.md, plugins/mcp/mcp-aws-docs/README.md, plugins/mcp/mcp-bigquery/README.md, plugins/mcp/mcp-chrome-devtools/README.md, plugins/mcp/mcp-dbhub/README.md, plugins/mcp/mcp-devin/README.md, plugins/mcp/mcp-markitdown/README.md, plugins/mcp/mcp-notion/README.md, plugins/mcp/mcp-playwright/README.md, plugins/mcp/mcp-redash/README.md, plugins/mcp/mcp-serena/README.md, plugins/ndf/README.md, plugins/ndf/scripts/acceptance-check.py, plugins/ndf/scripts/hook_lib/worktree.py, plugins/ndf/scripts/lib/acceptance.py, plugins/ndf/scripts/lib/closing-issues.sh, plugins/ndf/scripts/lib/closing.py, plugins/ndf/scripts/lib/dist_record.py, plugins/ndf/scripts/lib/repo.py, plugins/ndf/scripts/pr-steps.py, plugins/ndf/scripts/pr_steps_lib/init.py, plugins/ndf/scripts/pr_steps_lib/gh_pr.py, plugins/ndf/scripts/progress-record.sh, plugins/ndf/scripts/release-steps.py, plugins/ndf/scripts/release-verification-steps.py, plugins/ndf/scripts/release_lib/materials.py, plugins/ndf/scripts/sprint-close.py, plugins/ndf/scripts/sprint_close_lib/init.py, plugins/ndf/scripts/sprint_close_lib/collect.py, plugins/ndf/scripts/sprint_close_lib/final_stage.py, plugins/ndf/scripts/supervise_lib/pr.py, plugins/ndf/scripts/supervise_lib/release_templates.py, plugins/ndf/scripts/supervise_lib/sprint.py, plugins/ndf/scripts/supervise_lib/sprint_close_steps.py, plugins/ndf/scripts/supervise_lib/sprint_routes.py, plugins/ndf/scripts/supervise_lib/templates.py, plugins/ndf/skills/AUTHORING.md, plugins/ndf/skills/backlog-refinement/tests/test_issue_upkeep_layout.py, plugins/ndf/skills/development-workflow/references/glossary.md, plugins/ndf/skills/development-workflow/references/loop.md, plugins/ndf/skills/development-workflow/references/pace.md, plugins/ndf/skills/development-workflow/references/stage-completeness.md, plugins/ndf/skills/merged/SKILL.md, plugins/ndf/skills/pr/SKILL.md, plugins/ndf/skills/progress-tracking/SKILL.md, plugins/ndf/skills/quality-gates/SKILL.md, plugins/ndf/skills/release-verification/SKILL.md, plugins/ndf/skills/release/SKILL.md, plugins/ndf/skills/requirements-design/references/acceptance-criteria.md, plugins/ndf/skills/retrospective/SKILL.md, plugins/ndf/skills/worktree/tests/test_hook_wiring.py, plugins/playwright-kit/README.md, scripts/build-runtime-plugins.sh, scripts/check-cross-skill-refs.py, scripts/check-doc-staleness.py, scripts/check-skill-frontmatter.py, scripts/check-skill-repo-assumptions.py, scripts/ci-heavy-skip.py, scripts/lib/validate_manifests.py, scripts/runtime-smoke-latest.py, scripts/runtime-smoke-test.sh, scripts/validate-runtime-plugins.sh, tests, plugins/mcp/mcp-serena/tests, plugins/ndf/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(項目 I-006, I-011, I-010, I-013, I-015)
  • 着手前のテスト: uv run --frozen --project . --all-extras pytest plugins/mcp/mcp-serena/tests plugins/ndf/scripts/tests plugins/ndf/skills/backlog-refinement/tests/test_issue_upkeep_layout.py plugins/ndf/skills/development-workflow/tests plugins/ndf/skills/merged/tests plugins/ndf/skills/release/tests plugins/ndf/skills/worktree/tests/test_hook_wiring.py 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)
  • 着手前のテストの結果: 通過(505.9 秒 / HEAD 1cc2119)
  • 既存失敗の件数: 0
  • 想定最大時間: 75 分 / 改修計画の時点で使えた時間: 40.05 分
  • 実装担当: claude

改善項目

I-001 — plugins/ndf/scripts/release-steps.py#cmd_notes

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

なぜ: 68 行で、箇条の組み立てと、承認の資料(path がある)・CHANGELOG の 2 つの出力の経路が 1 関数に同居する。承認の経路の中で release_decl(root, a) を 2 回呼び(ref と decl)、metrics の dict は 2 つの経路でほぼ同じ鍵を写している

手順: 1. 承認の経路(verified〜emit)を _emit_approval_notes(root, a, path, prs, data, notes, bullets, risks, migration, skipped, rep_items, gone) として抽出する。その中で release_decl を 1 回だけ呼び、ref の既定値に使い回す
2. 2 つの metrics に共通の鍵(version・prs・lines・migration・unmerged・replaced)を _notes_metrics(a, notes, bullets, migration, skipped, gone) として抽出し、経路ごとの鍵(approval / fallback)だけを足す
3. test_release_notes_changelog.py と test_release_steps.py を流す

I-002 — scripts/check-skill-frontmatter.py#_check_ops

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

なぜ: 58 行に長さの上限・when_to_use のトリガ語・発動制御(disable-model-invocation / user-invocable)・context: fork・未知の鍵の 5 種の検査が並ぶ。fm.get("disable-model-invocation", "").lower() == "true" と fm.get("user-invocable", "").lower() == "false" を前半の if と後半の dmi / uinv で 2 回ずつ評価している。認知的複雑度 26・CC 15 で対象範囲の本体の最大

手順: 1. 関数の先頭で dmi / uinv を 1 回だけ求め、前半の 2 つの if をその変数で書き直す
2. 長さの検査を _check_lengths(s, desc, wtu, add)、発動制御の検査(explicit-only・inject-only・uninvocable・argument-hint)を _check_invocation(s, fm, desc, add) として抽出する
3. check_ops は 2 つと when_to_use・context・未知の鍵の検査を順に呼ぶ形にする
4. scripts/tests/test_skill_frontmatter
*.py と python3 scripts/check-skill-frontmatter.py を流し、出力が変わらないことを確かめる

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

I-003 — plugins/ndf/scripts/sprint-close.py#cmd_close

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method major high claude / kiro 未確認 2

なぜ: 72 行の中に、引数の組み合わせによる停止・PR 一覧が無いときの停止・課題の収集・閉じる処理・結果の分岐(failed / RECORD_UNKNOWN / 最終工程の記録の欠け)が並ぶ。停止の emit(result(TOOL, "stopped", ..., [], {"issues": 0}, next=...), EXIT_UNREADABLE) の形が cmd_close の 2 か所と _stop_no_issues で 3 回写されている

手順: 1. _stop(summary, nxt, metrics)(stopped・items 空・EXIT_UNREADABLE で emit)を抽出し、cmd_close の 2 か所と stop_no_issues の emit を置き換える
2. 課題の収集(given の組み立て〜sprint_issues〜given の追加〜0 件の停止)を _collect_issues(a, root, record_repo, rec, prs) として抽出する
3. 結果の分岐(failed → RECORD_UNKNOWN → 通常)を _emit_close_result(a, items, notes, metrics, summary, count, decisions) として抽出する
4. test_sprint_close
*.py を流す

I-004 — plugins/ndf/scripts/release-verification-steps.py#_build_result

兆候 手法 重要度 等級 提案元 状態 コミット
divergent_change extract_method minor medium claude / codex 未確認 1

なぜ: 利用者の環境の差分の項目化・ランタイムごとの版の判定(ndf があれば ndf だけを --expect と比べる規則を含む)・要約文の組み立てが 1 関数に入り、認知的複雑度 26・引数 7 個。版の判定規則が結果の整形の中に埋もれている

手順: 1. ランタイム 1 件の判定(exit≠0 → failed、版が --expect と違う → version_mismatch、それ以外 ok)を _runtime_result(r, expect) として抽出する
2. 利用者の環境の差分の項目化を _env_items(before, after) として抽出する
3. test_step_scripts.py の verify-install のパラメータ化テスト(ok / version_mismatch / failed / file_mismatch / user_env_changed)を流す

I-005 — plugins/ndf/scripts/pr_steps_lib/gh_pr.py#existing_pr

兆候 手法 重要度 等級 提案元 状態 コミット
duplication consolidate_duplication major high kiro 未確認 2

なぜ: existing_pr と pr_for_report が「gh を呼ぶ → returncode 0 なら JSON を読む(読めなければ StepError)→ rate limit なら repo_owner_name を引いて REST へ退避 → REST の出力を読む」という同じ手順を 2 か所で持ち、REST の戻りを辞書へ詰め直す形も重複している。片方だけ直すと退避の挙動が食い違う

手順: 1. gh の実行・成功時の JSON 読み取り・rate limit 判定・REST 退避の共通部分を _gh_or_rest(args, rest_path, parse) のようなヘルパへ抽出
2. existing_pr と pr_for_report をヘルパ経由に書き換え、REST の戻りの整形だけを各呼び出し側の parse に残す
3. pr_steps 系テスト(test_pr_steps.py)で rate limit 退避の経路を含めて実行

I-006 — plugins/ndf/scripts/sprint_close_lib/collect.py#sprint_issues

兆候 手法 重要度 等級 提案元 状態 コミット
duplication consolidate_duplication major high claude 未確認 1

なぜ: Python から bash の副プロセスで lib/closing-issues.sh を呼び、その出力(タブ区切り)を読み直して重ねを除いている。同じ読み取りは同じプロセスにある lib/closing.py の closing_refs(text, repo) が持ち、test_closing.py の test_closing_issues_sh_reads_the_same_targets_as_closing_refs が両者の一致を固定している。副プロセスの起動・区切りの解析・重ね除きのループ(12 行)が、1 回の関数呼び出しで済む。closing-issues.sh 自体は shell の Skill(merged・workflow-common.sh)が使うので残す

手順: 1. sprint_issues の subprocess.run と出力解析のループを for key in closing.closing_refs(body, repo): if key not in seen: seen.add(key); out.append(key) に置き換える(closing から closing_refs を import に足す)
2. 使われなくなった CLOSING_ISSUES 定数と subprocess・Path の import を消す
3. モジュールの docstring の『closing keywords の読み取りは lib/closing-issues.sh と lib/closing.py が持つ』を lib/closing.py だけにする
4. test_sprint_close_issues.py・test_sprint_close_references.py・test_sprint_close_merge_green.py(スクリプトを丸ごと起動する)と test_closing.py を流して一致を確かめる

I-007 — plugins/ndf/scripts/release-verification-steps.py#_verify_runtimes

兆候 手法 重要度 等級 提案元 状態 コミット
long_parameter_list introduce_parameter_object major medium kiro / codex 未確認 1

なぜ: 引数が 10 個(a, root, src, tmp, runtimes, plugins, rel, prev, ref_rev, where)。cmd_verify_install で組んだ値の束をそのまま横流ししており、_build_result も同じ束の一部(a, ref_rev, prev, ...)を 7 引数で受ける。同じ組がいつも一緒に渡っている

手順: 1. ref/rev/prev/plugins/rel/where/src/tmp をまとめた VerifyContext(dataclass か NamedTuple)を定義
2. cmd_verify_install で 1 度だけ組み、_verify_runtimes と _build_result はそれを受ける形に change_signature
3. test は verify-install の経路を通すものを実行(既存のリリース検証テスト)

I-008 — plugins/ndf/scripts/release-steps.py#cmd_approval_facts

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

なぜ: Git からの対象範囲の取得、PR と CI の取得、機械向け items と提示用の行の生成、承認資料の保存、結果の出力を一つの関数が進める。PR ごとの事実から二種類の出力を作る部分が埋まり、承認資料の表示を直す際にも外部取得と保存の全体を追う必要がある。

手順: 1. test_release_range.py の test_approval_lists_every_pr_with_marks_once と test_release_included.py・test_release_approved_commit.py・test_release_carry.py を基準にする。
2. PR ごとの CI 取得はコマンド側に残し、含む PR、取得済み PR データ、CI 結果、リポジトリ名の4引数から items と行を返す純粋関数を抽出する。
3. cmd_approval_facts のループをその呼び出しへ置き換え、取得順・取得回数、承認対象 SHA、提示物の保存と emit は変更しない。
4. 含む PR の順序、経由・変化なしの印、CI の件数、承認ゲートの終了コード10、前の資料の引継ぎを既存テストで確認する。

I-009 — plugins/ndf/scripts/sprint-close.py#_close_item

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

なぜ: 試行(dry_run)の結果を状態から決める式 "already_closed" if state == "CLOSED" else "would_close" が _judge_and_mark(254 行)と _close_item(293・298 行)の 3 か所に写されている。あわせて {"kind": "issue", "repo": repo, "number": n} と、retry_cmd つきの failed の項目の組み立てが _judge_and_mark・_close_verified・_close_item・close_one で繰り返される。_close_item は認知的複雑度 17・return 7 本

手順: 1. _dry_run_result(state)(CLOSED なら already_closed、それ以外は would_close)を抽出し、3 か所を置き換える
2. _issue_base(repo, n) と _failed(base, reason, ctx)(result=failed・reason・cmd=ctx.retry_cmd)を抽出し、_judge_and_mark・_close_verified・close_item の failed の組み立てを置き換える
3. test_sprint_close
*.py を流す

I-010 — plugins/ndf/scripts/lib/acceptance.py#version_verdicts

兆候 手法 重要度 等級 提案元 状態 コミット
feature_envy move_responsibility major medium codex 未確認 2

なぜ: 受け入れ条件を扱う関数が md のセクション一覧を自分で組み、dist_record._verify_blocks を呼び、その内部辞書の ver・lines を読んで最後のブロックを選んでいる。記録の切り出しに必要な知識が parse_record 側と呼び手に分かれ、非公開の実装へ結合している。

手順: 1. test_release_materials.py の承認資料経路を基準にし、複数ブロック・基底版の一致と不一致・未完了ブロック・コード囲み内の見出しを含む公開関数 version_verdicts の現状出力を固定する。
2. dist_record.py に、本文からリリース後テストのブロックを切り出し、指定の基底版に一致する最後の表本文を返す公開関数を置く。ブロック生成に必要な sections の組み立てを同モジュール内で共有する。
3. acceptance.version_verdicts は公開関数が返す本文を verification_verdicts に渡すだけにし、非公開関数と辞書構造への参照を外す。
4. parse_record の完全な版の一致・配布後のフォールバックと、version_verdicts の基底版による一致は別の規則として維持する。両方の既存テストと固定テストを実行する。

I-011 — plugins/ndf/scripts/lib/closing.py#defer_for_base

兆候 手法 重要度 等級 提案元 状態 コミット
hidden_dependency fix_dependency_direction minor medium claude 未確認 1

なぜ: モジュールの残りは本文の文字列だけを扱うのに、defer_for_base だけが関数の中で import repo(git を読む層)を行い、モジュールの依存を隠している。呼び手の pr-steps.py の upsert と supervise_lib/pr.py の _publish はどちらも repo を読める層で、判定 repo.merge_closes_issues(root, base) を呼び手(または repo 側)に置けば closing.py は純粋な文字列の層に戻る

手順: 1. defer_for_base を lib/repo.py へ移し(closing.defer_closing を呼ぶ形。repo → closing の向きに揃う)、closing.py から消す
2. pr-steps.py と supervise_lib/pr.py の import を from repo import defer_for_base に替える
3. closing.py の docstring から defer_for_base への言及を外す
4. test_closing.py・test_supervise_pr_closing.py・test_pr_steps*.py を流す。モンキーパッチの対象が closing.defer_for_base になっているテストがあれば repo へ付け替える

I-012 — scripts/lib/validate_manifests.py#check_description

兆候 手法 重要度 等級 提案元 状態 コミット
hidden_dependency extract_class major low codex 未確認 1

なぜ: check_description が大域の errors と動的に読んだ VERSION_IN_DESCRIPTION に書き込み・依存し、周辺の関数も大域 root を読む。モジュールの読み込みで sys.argv の取得からファイル走査、結果出力、終了まで実行されるため、検査を同じプロセスで独立に試せず、すべて subprocess 経由になる。

手順: 1. scripts/tests/validate_manifests_helpers.py を使う既存の形・版・MCP 検査のテストを基準とし、成功・複数エラー・版数定義の読み込み失敗の CLI 出力と終了コードを記録する。
2. 同じファイル内に根のパス・診断一覧・版数パターンを保持する検査クラスを抽出し、check_description と関連するパス解決・集計・検査ループをその責務へ移す。
3. sys.argv の読み取り、検査の起動、標準出力・標準エラー、終了コードは main と main に集める。検査順序・失敗時の扱い・引数形式・取得元の規則は維持する。
4. 一時の二つの木に対する検査を独立に呼べることを確認し、全既存 CLI テストを同じ期待値で実行する。manifest 行解析の共通化案と同時に採用する場合は別の一手に分ける。

I-013 — plugins/ndf/scripts/lib/acceptance.py#verification_verdicts

兆候 手法 重要度 等級 提案元 状態 コミット
feature_envy extract_method minor low kiro 未確認 1

なぜ: md.tables の表から見出しの位置(課題/結果/受け入れ条件)を引き、セルの頭を正規表現で切り出し、課題ごとに (all_pass, passed, failed) を畳み込む処理が 1 関数に詰まっており、認知的複雑度 18・分岐 7。行を 1 件ずつ畳む中核が、表の体裁の読み取りと混ざっている

手順: 1. 見出しから列の位置を引く部分を _column_indices として抽出
2. 1 行を (key, 合否, 条件番号) に解く部分を _parse_verdict_row として抽出
3. verification_verdicts は解いた行を畳み込むだけにする
4. test_acceptance_checks.py を手ごとに実行

I-014 — plugins/ndf/scripts/release-steps.py#plan_bump

兆候 手法 重要度 等級 提案元 状態 コミット
long_method extract_method minor low kiro 未確認 1

なぜ: plugin.json 群・marketplace.json・README.md・plugins/ndf/README.md という置き場ごとの版の書き換えが 1 関数に連なり、認知的複雑度 17・分岐 9。ndf 固有の書き換え(README 概要・Codex のパス例・list の出力例・versioning_doc)が末尾にまとまって他の汎用部分と混ざる

手順: 1. plugin.json 群の書き換えを _bump_manifests として抽出
2. README.md と marketplace.json の書き換えを _bump_marketplace_and_readme として抽出
3. ndf 固有の書き換えを _bump_ndf_docs として抽出
4. plan_bump は 3 つを順に呼ぶ
5. test_release_steps.py を手ごとに実行

I-015 — plugins/ndf/scripts/tests/test_supervise_pace.py#new_fast_sprint

兆候 手法 重要度 等級 提案元 状態 コミット
duplication extract_test_helper minor low kiro 未確認 1

なぜ: cli("new", "sprint", ...) の長い引数列(--name/--worktree/--issue/--design/--version/--out ...)が test_supervise.py・test_supervise_pace.py・test_supervise_new.py・test_supervise_design_match.py に写し取られている。指標の重複一覧でも test_supervise.py と test_supervise_pace.py に同型の 9 行が挙がっている

手順: 1. 共通の new sprint 起動を 1 つの補助(既定の引数を持ち、差分だけを **extra で受ける)へ extract_test_helper
2. 各テストはその補助を呼ぶ形へ置き換える(期待値は変えない)
3. 対象の supervise 系テストを実行して緑を確認

レビューで確かめるテストの差分: plugins/ndf/scripts/tests/sprint_args.py, plugins/ndf/scripts/tests/test_supervise.py, plugins/ndf/scripts/tests/test_supervise_new.py, plugins/ndf/scripts/tests/test_supervise_pace.py(機械で期待値が変わったか決まらなかった)

指標の測定

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

時間の上限

値 中身
提案の枠の終わり(監視の上限 = 残り + 余裕) 2026-10-31T19:10:40+00:00
改修計画の枠の終わり(同上) 2026-10-31T19:18:10+00:00
テストの追加の終わり = 実装の終わり − Σ(採っていて未検証の項目の実装の見積り) 2026-10-31T19:33:44+00:00
実装の終わり = 最終ゲートの修正の打ち切り − バッファ − Σ(採っていて未検証の項目の検証の見積り) 2026-10-31T19:34:54+00:00
直しの試行の打ち切り 2026-10-31T19:45:06+00:00
想定最大時間の終わり H(子プロセスはすべてここまでに止まる) 2026-10-31T20:02:15+00:00
確かめの開始の締め切り = H − 確かめの見込み(最終ゲート修正と打ち切りの後の取り消しもここまで) 2026-10-31T19:46:53+00:00
確かめの見込み(秒。最終ゲートの確かめ 1 回。バッファの最終ゲートの全体テスト) 922
最終ゲート修正 1 回の見込み(秒。バッファの final_fix。起動は今 + この値が確かめの開始の締め切り以前のときだけ) 107
指標の測定の上限(秒。提案の枠の中から割く) 225
着手前のテスト 1 回の上限(秒) 1350
範囲テスト 1 回の上限(秒) 1518
手元の全体テスト 1 回の上限(秒) 4644
CI の待ちの上限(秒) 2766
余裕(秒。手順の上限と CLI の上限に足す) 225

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

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

見送った提案

対象 兆候 理由 根拠(MVV) 補足
plugins/ndf/scripts/release-verification-steps.py#_verify_runtimes data_clump duplicate Value 6 / Value 1 C-007 と同じ変更
plugins/ndf/scripts/release-verification-steps.py#_build_result long_method duplicate Value 6 / Value 1 C-016 と同じ変更
scripts/lib/validate_manifests.py#manifest_skill_count duplication budget Value 6 / Value 1 / Value 7 見積り 18.0 分が残りに入らない
plugins/ndf/scripts/lib/closing.py#closing_numbers duplication budget Value 6 見積り 16.9 分が残りに入らない
plugins/ndf/scripts/tests/test_release_range.py#test_range_has_direct_and_sprint_routed_prs_without_release_prs test_bypasses_module_boundary budget Value 10 / Value 1 / Value 6 見積り 9.7 分が残りに入らない
plugins/ndf/scripts/sprint-close.py#_close_item long_parameter_list budget Value 10 / Value 6 見積り 12.4 分が残りに入らない
plugins/ndf/scripts/supervise_lib/release_templates.py#_prepare_steps data_clump budget Value 10 / Value 1 / Value 6 見積り 12.4 分が残りに入らない

takemi-ohama and others added 3 commits October 31, 2026 20:02
衝突 3 件を解いた。README 2 本はスプリントの側(agy・Kiro CLI への配布の終了)を残し、
最後に配った版を v10.27.4 へ直した。dev.agy/plugin.json は配布の終了で消した側を残した。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KYHP7yPdcB8dBzbZpQCnR4
c823010 は cross-refactoring の締め切りを過ぎたとして着手前の木(1cc21190)へ戻したが、
その木は develop(v10.27.4)を取り込む前のもので、develop の変更まで巻き戻していた。
改修 14 件は 2d4602d で CI の 23 件がすべて通っているため、2d4602d6 の木へ戻す。
最終ゲートが締め切りで取り消す動きは別に起票する。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KYHP7yPdcB8dBzbZpQCnR4

@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

修正を要する指摘は2件です。

差分の外を指す指摘

  • plugins/ndf/scripts/sprint-close.py:235 [major] [major / 正確性] リリース後テストの表が導入確認(課題列が「—」)だけの場合、全条件を「マージ前」と記録した課題もここで一律に kept_open となり、新設した judge_acceptance の免除判定へ到達できません。課題行が無い表は空の判定一覧として課題別の確認へ渡し、未確認の条件を持つ課題だけを開いたままにしてください。
  • plugins/ndf/README.md:65 [major] [major / データ保全] Kiro の削除案内どおり ndf.json を丸ごと消すと、旧installerが保持していた利用者独自の mcpServers・hook・その他の設定も失われます。削除前に設定ファイルを退避し、利用者管理の項目を残すエージェントへ移す手順を案内してください。

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

Kiro の観点で全 227 ファイルを確認。Kiro CLI / agy への配布終了(docs・.ndf・CI・installer・manifests・tests)は触れたファイル全体で整合し、削除物への参照残りは無い(plugins/ndf/docs/kiro-cli.md への参照 0、validate_manifests.py / check-skill-frontmatter.py に kiro/agy の扱い無し、README の移行アンカー #agykiro-cli-への配布の終了 は実在)。#2228 の deferred-closing は closing.py の CLOSING(キーワードのみ)と _ANY_CLOSING(deferred も一致)の使い分けが正しく、defer_closing は deferred 済み本文に冪等、_publish のタブ分割と found 空の分岐も正。sprint-close の閉じる条件 3(振り返りの記録)は retrospective が書く行と _RETRO_LINE / dist_comment_id の読みが整合する。critical / major の指摘は無し。script 群の構造改善は既存の cross-refactoring 計画(rf2318)と重複するため指摘しない。

…する案内を足す (#2318)

- sprint-close: 見出しが読めて課題を指す行が無い表は、すべての条件をマージ前に確かめた課題だけを課題ごとの判定へ進める。他は今までどおり「条件と課題の対応が読めない」で開いたまま
- README: 前の installer が引き継いだ利用者の mcpServers・hook を消す前に退避して写す手順を足す

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

Copy link
Copy Markdown
Contributor Author

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

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

レビュー本文の指摘への返事:

  • 対応しました。(a67db968)
  • 対応しました。(a67db968)

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

round 1 の 2 件(導入の確認だけの表で全条件をマージ前に確かめた課題を閉じる・Kiro の ndf.json の退避)は a67db96 で直っていることを確かめた。今回見た範囲では、指摘の基準(critical / 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 2 | kiro | APPROVE

Kiro の観点で round 2 の差分 228 ファイルを確認。critical / major は無い。round 2 の fix(a67db968)は round 1 codex の 2 件へ正しく対応している。(1) sprint-close: 見出しが読める・課題行の無いリリース後テストの表で、本文の『## 受け入れ条件の確認』の全条件がマージ前の課題だけを判定へ進める分岐が、judge_acceptance(None, criteria, pre_merge) の『全条件が pre_merge なら行が無くても満たす』規則と整合し、_all_pre_merge と _judge_and_mark が同じ judge_acceptance を使うため判定が一致する。他の課題は従来どおり NO_MAPPING の kept_open のまま。verdict_table_readable / _column_indices で『課題を指す行が無い』と『表が読めない』を分けており、空 dict({}) は verdicts is not None を通して課題ごとの経路へ進む。spec(ndf-cleanup-and-bundle-closing.md・ndf-sprint-close-acceptance-criteria.md I2・progress-tracking SKILL.md)と実装・テストが一致する。(2) README: 旧 installer が ndf.json に引き継いだ利用者の mcpServers・hook を消す前に cp で退避し別エージェントへ写す非破壊の案内を足している。配布終了(claude・codex のみ)は supervise.json の release.runtimes・smoke matrix・required-checks の guard テストで整合し、test_distribution_runtimes.py の否定テスト(復元すると検出)で artifacts の残りが無いことを確かめている。cross-refactoring 由来の構造改善(revert と revert-of-revert で refactored 状態に戻る)は rf2318 計画の範囲のため再指摘しない。修正を要する指摘は無い。

@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

閉じる条件 3(振り返りの記録)が、他のリポジトリのスプリント課題を、まとめのプランでは一度も閉じられない形になっている。修正を要する指摘はこの 1 件。

@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

修正を要する指摘は1件です。

Comment thread plugins/ndf/scripts/sprint-close.py Resolved
全条件がマージ前かの判定(_all_pre_merge)が本文を読んだ直後に _judge_and_mark が同じ
gh issue view --json state,body を読み直し、課題ごとに CLI の起動と API の要求が 1 回ずつ余計だった。
判定と NO_MAPPING で残す分岐を _judge_and_mark の 1 回の読みへ寄せる(PR #2318 round 3 の指摘)。

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

Copy link
Copy Markdown
Contributor Author

🔧 /ndf:fix サマリ | round 3 | commit 511b277

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

@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 4 | codex | APPROVE

指定範囲の228ファイルを確認し、既存指摘と重複しないcritical・majorの新しい指摘はありません。判断の根拠: Value 1・3・6・10。

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

Kiro の観点で round 4 の差分 228 ファイルを確認。critical / major の新しい指摘は無い。Kiro CLI / agy の配布終了は触れた範囲全体で整合する。(1) 配布の設定: smoke matrix(runtime-plugin-smoke / -smoke-latest)・authenticated-smoke の choices・.ndf/supervise.json の release.runtimes・.ndf/project.json の required_checks と delivery.target・.ndf/pace.json の fast/auto の verify(--runtimes claude,codex)が claude・codex だけに揃い、test_check_required_checks.py の REQUIRED_10/17 と一致する。(2) 削除の完了: 削除した dev.agy / dev.kiro / docs/kiro-cli.md / agy_agents.py / 各 manifests を参照する配布コード・import は残らず(build-runtime-plugins.sh から sync_agy_* と write_kiro_mcp_installer を除去、-kiro の case も除去)、plugins//manifests は claude-skills.txt・codex-skills.txt のみ、validate_manifests.py は claude・codex のみを検査する。release-verification-steps.py は --runtimes を claude,codex に限り verify_claude/verify_codex のみを持つため pace の verify が通る。(3) 以前のラウンドの fix は現在の head でも残る: ndf.json を消す前に cp で退避し別エージェントへ写す非破壊の案内(round 1 codex)、sprint-close の _close_verified が状態と本文を 1 回の読みで判定する(round 1 の API 重複)。(4) closing.py の DEFERRED と closing-issues.sh の KEYWORD が同じ『最終工程の後に閉じる:』を読み、acceptance.py の _column_indices / _parse_verdict_row / verdict_table_readable への分割は判定の規則を変えない。round 3 で claude / codex が挙げた閉じる条件 3(他のリポジトリのスプリント課題を final_stage.py では閉じられない)は、スナップショットに既出で、修正担当が設計の選択(I7 の方針変更か progress-tracking 条件 3 の新規則か)として要ユーザ判断で見送っている。重複指摘は避ける。残る dev.agy / dev.kiro への言及(worktree-guard.sh の説明コメント・conftest.py の collect_ignore_glob・ht_bump.py)は差分の外で、実害の無い後方互換の入口・空振りする glob であり critical / major の基準に当たらない。

@takemi-ohama

Copy link
Copy Markdown
Contributor Author

🔧 /ndf:fix サマリ | commit (なし)

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

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