Skip to content

課題を閉じる時点を 1 つにし、最終の工程を通ってから閉じる #2228

Open
2 of 6 issues completed

Description

@takemi-ohama

依頼(原文)

この課題は、起票者(AI)が子の 2 件(#2082・#2119)をまとめて起こした親の課題である。利用者の指示の原文は課題にも記録にも見当たらない(2026-10-31 の利用者の方針 5 点〔--loop を残す・codex / agy / kiro への配布を cross 系に絞る・全工程で統一した JSON レポート・並列に強く・テストを削る〕には、課題を閉じる時点の項目が無い)。マイルストーン「26 自律実行の信頼性」の説明の主題 2 と、起票時の本文を写す。

課題を閉じる時点を 1 つにし、工程を通ってから閉じる(親 B)

(書き手: 起票者〔マイルストーンの説明に AI が書いた主題。利用者の発言の原文ではない〕、日付: 2026-10-31)

起票時の本文(題「課題を閉じる時点を 1 つにし、最終の工程を通ってから閉じる」):

何が困るか

課題が工程の途中で閉じる。閉じる経路が 3 つあり、どれも工程の通過を見ない。

子 閉じる経路
#2082 既定ブランチ宛の実装 PR の本文のclosing keywordsで、GitHub がマージの時点に閉じる
#2119 sprint-close.py が工程の通過を見ない。雛形の supervise_lib/sprint.close_plan は release-verify → close → retro の順で、振り返りの前に閉じる(progress-tracking/SKILL.md の「振り返りを通る変更では、retrospective が記録を投稿した後に閉じる」と食い違う)

修正レイヤー

課題を閉じる時点の正本。 progress-tracking の「スプリントを閉じる」を正本とし、sprint-close.py の入口で工程の通過を確かめる。sprint.close_plan の順序と、pr の宛先の表(closing keywordsを使う条件)をそれに従わせる。

完了条件

  • 最終の工程を通っていない課題は、どの経路でも閉じない
  • 閉じる順序が progress-tracking と雛形で一致する
  • 工程の通過は親 A のレポートから判定できる(A に依存)

(書き手: 起票者、日付: 2026-10-31。利用者の指示の原文として扱わない。引用の中の「closing keywords」は、原文では用語集で廃した語で書かれていたものを用語集の語へ置き換えた)

子の課題:

起票者の推定

利用者の指示の原文が無いため、題・本文の条件はどれも起票者の推定である。そのうち要求の形を決める条件を並べる。承認ゲート 1 で利用者が確かめるまで、利用者の決定として扱わない。

# 条件 推した出所 この要求での扱い
S1 閉じる時点の正本は progress-tracking の「スプリントを閉じる」の 1 か所である 本文の「修正レイヤー」 受け入れ条件 1
S2 工程の通過を確かめるのは sprint-close.py の入口である(呼ぶ側の手順の並びに頼らない) 本文の「修正レイヤー」、#2119 の起票者の推定 (a) 受け入れ条件 2・3
S3 まとめのプラン(supervise.py new close)の並びを、振り返り → 課題を閉じる → 棚卸しにする 本文の「何が困るか」、#2119 の受け入れ条件 3・4 受け入れ条件 5・6
S4 既定ブランチ宛の Pull Request の本文には、マージで課題を閉じる closing keywords(PR 本文に Closes #123 のように書くと、マージ時にその課題を自動で閉じる GitHub の機能)を残さない 本文の「何が困るか」の #2082 の行、#2082 の起票者の推定の 1 案目。#2082 の 2 案目(自動で閉じるのを前提にし、閉じた後でも受け入れ条件に印を付けられるようにする)は、「最終の工程を通っていない課題は、どの経路でも閉じない」と両立しない 受け入れ条件 7・8・9。2 案目は採らない
S5 工程の通過は親 A(#2227)のレポートから判定できる 本文の「完了条件」3 点目 前提 3・未決 1。判定の材料を何にするかは設計で決める
S6 閉じる経路は 3 つある 本文の「何が困るか」1 行目。表には 2 行しか無い 前提 1 で、この要求が扱う経路を 3 つに数え直す

目的

  • 課題が閉じた時点で、その実行の最終工程(棚卸しの前に最後に通る工程)が終わっているようにする。閉じた課題は棚卸しの対象から外れ、不合格の条件や未通過の工程が見えなくなるためである(sprint-close: 最終工程を通っていない課題を、リリース後テストの前に閉じないようにする #2119 の s2086 の経緯)
  • 閉じる時点の決まりを 1 か所に置き、スクリプト・まとめのプラン・Pull Request の本文の規則がそれに従うようにする。今は文書の決まりと雛形の並びが食い違い、決まりを守るのは呼ぶ側(conductor・引継ぎ文書)の手順の並びに頼っている

前提

対象範囲

含む:

  • progress-tracking の「スプリントを閉じる」を閉じる時点の正本として、「最終工程を終えてから閉じる」の判定の材料と順序を書く
  • sprint-close.py の入口で、課題ごとに最終工程を終えたかを判定し、終えていない課題を閉じない
  • まとめのプラン(supervise_lib/sprint.py の close_plan と sprint_close_steps.py)の並びを正本に合わせる
  • pr の宛先の表と「closing keywords は本文だけに書く」を、既定ブランチ宛の Pull Request で closing keywords を残さない形にする。closing keywords を持たない Pull Request から閉じる課題を集める手段(--issues か、それに代わるもの)を sprint-close.py に持たせる
  • 正本を写している文書(retrospective・release-verification・release・development-workflow の references)の参照の付け替え

含まない:

  • 利用者が手で gh issue close や GitHub の画面で閉じること(NDF の経路ではない)
  • 棚卸しが「やらない」と決めた課題を not planned で閉じること(backlog-refinement の no-work.md。工程を通らずに閉じるのが意図の経路で、最終工程の判定の対象にしない)
  • check-trigger.py が Pull Request を閉じること(課題ではない)
  • 親 A(全工程の結果を統一した JSON レポートにし、失敗・未収束・未記録を ok で返さない #2227)の結果 JSON の形式そのものの変更
  • 他のリポジトリ(例: volareinc/carmo-screening)の既存の課題・Pull Request の書き直し

ドメインイベント

# イベント 引き金 失敗したとき 順序の前提
E1 課題の Pull Request・スプリントの Pull Request がマージされた 承認ゲート 2 の後のマージ 宛先が既定ブランチで本文に closing keywords が残っていた → GitHub が課題を閉じる(受け入れ条件 7・8 で起きなくする) —
E2 配布(開発版・本番)を終え、配布の記録を記録の Pull Request に置いた release 配布が失敗した → 閉じる条件 1 を満たさず、課題は開いたまま残る(今と同じ) E1
E3 リリース後テストの結果を記録した release-verification(リリース後テストを通る経路のとき) 不合格・保留の行がある → 課題は閉じない(今の閉じる条件 2) E2
E4 振り返りの記録を記録の Pull Request のコメントに投稿した retrospective(振り返りを通る経路のとき) 投稿できなかった → 最終工程を終えていないと判定され、課題は閉じない(受け入れ条件 2) E3(通るとき)、無ければ E2
E5 sprint-close.py が課題ごとに最終工程を終えたかを判定した 最終工程を担う Skill・まとめのプランの close のステップ・conductor の手打ち 判定の材料が読めない → 終えたとは読まず、閉じない(受け入れ条件 3)。終えていない → kept_open と通っていない工程を返す(受け入れ条件 2) — (呼ぶ側の順序に頼らない。E4 の前に打たれても閉じない)
E6 判定を通った課題のボードを Done にし、課題を閉じた E5 閉じられなかった → failed と打ち直すコマンド(今と同じ) E5
E7 棚卸しを始めた まとめのプランの refine のステップ・工程表の次の工程 — E6

用語

用語 意味
最終工程 用語集の語。棚卸しの前にその実行で最後に通る工程(前提 2)
スプリント課題 用語集の語。sprint-close.py が閉じる対象にする課題
closing keywords 用語集の語。Pull Request の本文に Closes #123 のように書くと、マージ時に GitHub がその課題を閉じる機能
参照だけの課題 用語集の語。スプリントの Pull Request が番号で参照し、スプリント課題に入らない開いた課題
通過記録 用語集の語。進捗記録が実際に書かれた工程を課題ごとに残したファイル。工程に入った時点の記録である

受け入れ条件

各条件の末尾の括弧は、確かめる時期と手段を表す。

  • 1. progress-tracking の「スプリントを閉じる」が、課題を閉じてよい条件として「その課題の最終工程を終えたこと」と、それを判定する材料(未決 1 で決めるもの)を定める。retrospective・release-verification・release・pr・development-workflow の references は閉じる時点と順序の決まりを写さず、この節を指す(マージ前: grep で、閉じる時点の決まりを持つ文書がこの節の 1 か所であることを見る)
  • 2. 最終工程を終えていない課題(例: 振り返りを通るモードで振り返りの記録が無い)を含めて sprint-close.py --record-pr <記録のPR> --issues <番号> を打つ → --with-verification の有無にかかわらず、その課題は閉じず、ボードも Done にならず、結果 JSON の items に kept_open と、終えていない工程の名前を含む reason で載る(マージ前: gh と判定の材料を差し替えたテスト)
  • 3. 最終工程を終えたかを判定する材料が読めない(置き場が無い・読めない・ok の結果が無い)課題で同じコマンドを打つ → 終えたとは読まず、その課題は閉じず、kept_open か failed で理由つきで載り、結果 JSON の status は ok にならない(全工程の結果を統一した JSON レポートにし、失敗・未収束・未記録を ok で返さない #2227 の読む側の規則に従う)(マージ前: テスト)
  • 4. 最終工程を終え、リリース後テストの行がすべて合格の課題で --with-verification を付けて打つ → 今と同じく受け入れ条件へ [x] を付けてボードを Done にし、閉じる(退行しない)。--record-pr 0 と --record-pr unknown の今の扱いも変わらない(マージ前: 既存のテストと追加のテスト)
  • 5. 振り返りを通るモードで supervise.py new close が書くまとめのプランの steps の id を、next のつながりの順に並べる → リリース後テスト(配布の記録があるとき)→ 振り返り → 課題を閉じる → 棚卸しの順になり、progress-tracking の「スプリントを閉じる」の表と一致する(マージ前: プランを組んで並びを見るテスト)
  • 6. 振り返りを通らないモード・経路(light、振り返りを通らない operation)のまとめのプランでも、課題を閉じるステップはその経路の最終工程のステップの後、棚卸しのステップの前にある(マージ前: テスト)
  • 7. 開発の起点(.ndf/worktree.json の base_branch、無ければ既定ブランチ)が既定ブランチと同じ構成で、課題の Pull Request を NDF の手順(pr-steps.py create / update)で作る → でき上がった Pull Request の本文に、マージで課題を閉じる closing keywords(Closes / Fixes / Resolves と活用形)が残らない(既定ブランチ宛の実装 PR の本文の閉じる語で、マージの時点に課題が閉じ、仕上げの工程と受け入れ条件のチェックが閉じた課題に残る #2082 の受け入れ条件 1)(マージ前: 一時のリポジトリの構成で pr-steps.py を流すテスト)
  • 8. 上と同じ構成で、スプリントの Pull Request(既定ブランチ宛)を NDF の手順で作る → 同じく closing keywords が本文に残らない。その Pull Request だけから成るスプリントで sprint-close.py --record-pr <記録のPR> --prs <番号> --dry-run を打つ → 対象の課題が kept_open(参照だけの課題)や終了コード 2(集めた課題が 0 件)にならず、閉じる対象(最終工程を終えていれば would_close)として判定される(既定ブランチ宛の実装 PR の本文の閉じる語で、マージの時点に課題が閉じ、仕上げの工程と受け入れ条件のチェックが閉じた課題に残る #2082 の受け入れ条件 2・3)(マージ前: テスト)
  • 9. 開発の起点が既定ブランチと違う構成(このリポジトリの develop 宛)では、今と同じく本文の closing keywords が残り、sprint-close.py がそこから課題を集める(退行しない。既定ブランチ宛の実装 PR の本文の閉じる語で、マージの時点に課題が閉じ、仕上げの工程と受け入れ条件のチェックが閉じた課題に残る #2082 の受け入れ条件 4)(マージ前: 既存のテストと追加のテスト)
  • 10. 子の 2 件(既定ブランチ宛の実装 PR の本文の閉じる語で、マージの時点に課題が閉じ、仕上げの工程と受け入れ条件のチェックが閉じた課題に残る #2082・sprint-close: 最終工程を通っていない課題を、リリース後テストの前に閉じないようにする #2119)が、それぞれの受け入れ条件を満たして閉じている(子の課題で確かめ、この課題では閉じていることを見る)
  • 11. この版の後の最初のスプリントの仕上げで、引継ぎ文書や conductor の手順の並びに関わらず、どの課題もその最終工程の記録より前に閉じない(リリース後: スプリントの課題の closedAt と、振り返りの記録のコメントの投稿時刻(振り返りを通らない経路ではその経路の最終工程の記録の時刻)を比べる)

非機能の条件

大項目 条件
運用・保守性 閉じる時点の決まりは progress-tracking の 1 か所、判定は sprint-close.py(とそれが使う lib)の 1 か所に置く。まとめのプランと Skill の本文に、閉じてよいかの判定を書き分けない(MVV の Value 6)
移行性 sprint-close.py の閉じる条件が増える(契約の変更)。呼ぶのは同じ版の plugins/ndf の中のプラン・Skill の本文だけなので、同じ版で呼ぶ側も直す。利用者の手での移行は要らない。この版より前に工程を通り、判定の材料を持たないまま開いている課題の扱いは未決 2

影響

対象 影響
公開インタフェース 変わる。sprint-close.py の閉じる条件・kept_open の理由・(足すなら)引数と、pr-steps.py が作る本文の closing keywords の扱い。読み手は同じ版の plugins/ndf の中だけで、版をまたぐ互換の経路は持たない(互換なし)
データ 課題の本文・ボードの形は変えない。判定の材料の置き場を新しく足すかは未決 1
既存の振る舞い 今は呼べば閉じていた課題が、最終工程を終えるまで kept_open で残る(意図した変化)。既定ブランチ宛の Pull Request の本文から closing keywords が消え、マージで課題が閉じなくなる(意図した変化)

検証手段

項目 手段
テスト uv run --frozen --project . --all-extras pytest plugins/ndf/scripts/tests -q -n 4(sprint-close.py の判定・まとめのプランの並び・pr-steps.py の本文の単体テストと、gh を差し替えた結合テスト)
静的解析 CI の既存のチェック(python3 scripts/check-skill-frontmatter.py・python3 plugins/ndf/scripts/instructions-check.py --root . ほか)
手動確認 リリース後テストで、この版の後の最初のスプリントの仕上げの結果 JSON と、課題の closedAt・振り返りの記録の投稿時刻を見る(受け入れ条件 11)。既定ブランチが起点のリポジトリのスプリントが同じ期間にあれば、課題がマージの時点で OPEN のまま残ったことも見る(#2082 の受け入れ条件 5)

前提とする取り決め

項目 参照先 / 決めたこと
プロジェクト構造 判定のコードは plugins/ndf/scripts/(sprint-close.py と lib/)、プランの組み立ては supervise_lib/、決まりの正本は plugins/ndf/skills/progress-tracking/SKILL.md。Skill ごとの scripts/ に同じ役割の関数を置かない(lib/README.md の「置いてよいもの・いけないもの」)
コーディング規約 結果 JSON は lib/step_result.py の形(#2227 の後の形)。.md の文言を照合するテストは書かない(AGENTS.md の DON'T)
テスト戦略 判定とプランの並びは単体テスト、sprint-close.py と pr-steps.py は gh を差し替えた結合テスト(tdd-cycle の testing-levels)

境界

区分 内容
常に行う 既存のテスト全体の実行、正本を写している文書の付け替え、まとめのプランと sprint-close.py の同時の更新
確認してから行う sprint-close.py の閉じる条件・引数の変更と、pr-steps.py が作る本文の変更(契約の変更)。承認ゲート 1 の設計と承認ゲート 2 で人が見る
行わない 他のリポジトリの既存の課題・Pull Request の書き直し、#2227 の結果 JSON の形式の変更、棚卸しの not planned の閉じ方の変更

未決

項目 誰が決めるか 期限
1. 最終工程を「終えた」と判定する材料を何にするか。候補: (a) #2227 の結果 JSON(最終工程を担う Skill・ステップの ok の結果)、(b) 最終工程の成果物(振り返りの記録のコメント・リリース後テストの記録・配布の記録)が記録の Pull Request にあること、(c) 通過記録に「工程を出た」記録を足す。通過記録はリポジトリの外の手元のファイルで、別の機械・別のセッションからは読めないことを考える 設計(承認ゲート 1 で利用者が確かめる) 設計 PR
2. この版より前に工程を通り、判定の材料を持たないまま開いている課題を、この版の sprint-close.py がどう扱うか(kept_open で残して手で閉じるか、移行の手段を持つか) 設計 設計 PR
3. 既定ブランチ宛の Pull Request の本文に closing keywords が書かれたとき、止めるか参照(Refs #N)へ置き換えるか(#2082 は「問わない」としている)と、閉じる課題を集める手段を --issues にするか本文の別の記法にするか 設計 設計 PR
4. 最終工程を担う Skill(retrospective など)が「スプリントを閉じる」を呼ぶ今の形を残すか、まとめのプランの close のステップだけにするか 設計 設計 PR

進行

モード: — / 進め方: auto

  • 要求と受け入れ条件 — 2026-10-31 11:33
  • 作業場所の用意 — 2026-10-31 13:00
  • 設計 — 2026-10-31 11:47
  • 素材の収集と出典の確定
  • ドキュメント再構成
  • ドキュメントレビュー
  • 計画 — 2026-10-31 13:00
  • 実装 — 2026-10-31 13:01
  • 構造改善 — 2026-10-31 18:37
  • 実装レビュー — 2026-10-31 22:28
  • 完了判定 — 2026-10-31 16:12
  • Pull Request — 2026-10-31 16:25
  • 確定仕様化 — 2026-11-01 00:29
  • 後片付け — 2026-11-01 00:28
  • 配布 — 2026-11-01 00:00
  • 体裁レビュー
  • リリース後テスト — 2026-11-01 00:28
  • 振り返り — 2026-11-01 01:03
  • 棚卸し — 2026-11-01 01:16

振り返り: #2320 (comment)

状況(2026-11-01、v10.27.6)

リリース後テストの取り直し(2026-11-01 17:39 JST)

記録: #2328 (comment)

Activity

  1. added 6 commits that reference this issue on Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: ndf-skillNDF の Skill 本体priority: high実害・安全機構の欠落など、優先して対応する

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions