Skip to content

実行をまたいで残る状態(待ち行列・一時の worktree)に寿命と持ち主を持たせ、並行する実行が互いを塞がないようにする #2229

Closed
2 of 2 issues completed

Description

@takemi-ohama

何が困るか

実行をまたいで残る状態(投稿の待ち行列・一時の worktree・状態ファイル)に寿命と持ち主が無い。並行する実行が残骸を積み、次の実行を塞ぐ。手で片付ける側が、実行中のものを消すおそれもある。

子 残るもの 起きたこと
#2084 cross-review の投稿の待ち行列の先頭に残る、前の実行の 422 の指摘 review が止まり続ける(carmo PR #352、2026-10-21)
#2085 /tmp/ndf-worktrees/ の rf* と状態ファイル 2026-10-23 にホストのディスクが埋まった。2026-10-31 時点でマージ済みの rf 4 本(2.0G)が残る

関連: #2221(承認の後の別のセッションのマージで止まる)、#2164・#2165(並行するプランの版数と触るファイル)。

修正レイヤー

実行をまたいで残る状態の寿命と持ち主を持つ層。 一時の置き場は lib/worktree_base.py に掃除を寄せ、merged-steps.py から呼ぶ。待ち行列は lib/post_queue.py の失敗の分類で、前の実行が積んだ項目の扱いを決める。

完了条件

  • 状態ごとに持ち主(実行)と寿命が決まり、持ち主の終わった状態は自動で片付く
  • 実行中の状態を、別の実行の片付けが消さない
  • 前の実行の残りが、次の実行を止めない

要求と受け入れ条件

この節が要求の正である。上の「何が困るか」から「完了条件」までは起票時の文で、条件は下の「起票者の推定」の表で扱いを決め、受け入れ条件は下の AC1〜AC16 で置き換える。

依頼(原文)

  • 状態ごとに持ち主(実行)と寿命が決まり、持ち主の終わった状態は自動で片付く
  • 実行中の状態を、別の実行の片付けが消さない
  • 前の実行の残りが、次の実行を止めない

(書き手: 起票者、日付: 2026-10-31。この課題の「完了条件」。利用者の指示の原文としては扱わない)

  1. 並列実行に強い作りにする。実行をまたいで残る状態に寿命と持ち主を持たせ、承認の後の別のマージで止まらない(親 C・承認ゲート 2 の後に別のセッションが develop へマージすると、配布物の変わらない文書だけの PR でも承認を取り直す #2221)

(書き手: 不明、日付: 2026-10-31。マイルストーン「26 自律実行の信頼性」の説明の主題 3。2026-10-31 の新方針「並列に強く」を書き写した文と見られるが、利用者の原文を確かめられない)

子の課題の由来: #2085 は「利用者からの依頼(2026-10-23、Mac のディスクの空きが頻繁に無くなる件の調査)」と本文にあるが、依頼の原文は課題に無い。#2084 は carmo-screening #338 の振り返り(2026-10-21)で起票者が書いた。

起票者の推定

題・本文のうち、利用者の指示の原文に無く起票者が推して足した条件。承認ゲート 1 で利用者が確かめるまで、利用者の決定として扱わない。この課題には利用者の原文が無いため、条件はすべてここに並ぶ。

# 条件 推した出所 この要求での扱い
S1 状態ごとに持ち主(実行)と寿命を決める 完了条件 1 AC1
S2 持ち主の終わった状態は自動で片付く 完了条件 1 AC2〜AC6。人の操作を要さない時点で片付ける(前提 3)
S3 実行中の状態を、別の実行の片付けが消さない 完了条件 2 AC7〜AC10
S4 前の実行の残りが、次の実行を止めない 完了条件 3 AC11〜AC15
S5 子の #2084・#2085 をこの課題の 1 つの設計で直す 本文の表(子) 前提 1
S6 一時の置き場の掃除を lib/worktree_base.py に寄せ、merged-steps.py から呼ぶ 修正レイヤー 採らない(要求としては)。置き場と呼び出し元は設計が決める。merged-steps.py cleanup が片付けの時点の 1 つであることだけを AC2 で求める
S7 待ち行列は lib/post_queue.py の失敗の分類で、前の実行が積んだ項目の扱いを決める 修正レイヤー 採らない(要求としては)。直す場所は設計が決める。振る舞いは AC11〜AC14
S8 #2221・#2164・#2165 は関連であって、この課題で直さない 本文の「関連」 含まない

目的

  • cross-review・cross-refactoring・merged を並行して回しても、ある実行が残した状態が別の実行を止めず、ディスクを埋めず、作業中の変更を消さない状態にする(Mission の「人の判断が要る所だけで止まる」。手で残骸を片付ける操作を無くす)

前提

対象範囲

含む:

含まない:

ドメインイベント

# イベント 引き金 失敗したとき 順序の前提
E1 実行が残る状態を作り、持ち主を記録した cross-review / cross-refactoring の開始、セッションの開始、worktree-deps.sh の起動、テストの開始 持ち主を記録できない → 前提 4 で「終わっていない」とみなして残る。作れなければ今までどおりその実行が失敗を返す —
E2 実行が終わった 正常終了・異常終了・プロセスが止められた trap などの後始末が走らずに終わる → E4 の片付けが拾う(AC5・AC6) E1
E3 Pull Request がマージされた、または閉じられた 人か conductor の操作(merged を通るとは限らない) — E1
E4 片付けが、持ち主の終わった状態を外した 前提 3 の時点 git が拒む・削除に失敗する → kept と理由を返し、ほかの状態の片付けを続ける E2 か E3
E5 片付けが、持ち主の生きている状態・作業の残る状態を残した E4 と同じ時点 生きているかを判定できない → 残す(前提 4) E1
E6 次の実行が、以前の実行が積んだ投稿の項目を送ろうとして、GitHub が位置エラー(422 line could not be resolved)で拒んだ post_review の flush — 以前の実行の E1(積んだ)
E7 その項目を待ち行列から外し、控えか総評に残した E6 外せない → 今回分の送りも止まり failed になる(今の不具合。AC11 で塞ぐ) E6
E8 次の実行が、以前の実行の残したレビュー worktree を見つけた cross-review / cross-refactoring の開始 使えない形で残っている → 外すか作り直す(AC15) 以前の実行の E1

用語

用語 意味
残る状態 NDF の実行が作り、その実行が終わった後もディスクに残るもの(レビュー worktree・状態ファイル・一時ファイル・投稿キューの項目)(#2229)
状態の持ち主 残る状態を作った実行。持ち主が生きている間は、別の実行がその状態を消さない(#2229)
状態の寿命 残る状態を片付けてよくなる条件(持ち主のプロセスの終わり・Pull Request が閉じたこと・送り終えたこと など)。状態の種類ごとに 1 つ決める(#2229)
以前の実行 今の実行より前に同じ Pull Request・同じリポジトリで回った、終わった実行。supervise.py の run --from の「前の実行」とは別(#2229)

受け入れ条件

持ち主と寿命:

  • AC1: NDF が実行をまたいで残す状態(対象範囲の 5 種と投稿キューの項目)が 1 か所の一覧にあり、各行に置き場・持ち主・寿命・片付ける時点が書かれている。一覧に無い種類の残る状態を NDF のスクリプトが作ると、テストが落ちる

持ち主の終わった状態は自動で片付く:

実行中の状態を別の実行が消さない:

以前の実行の残りが次の実行を止めない:

退行しないこと:

  • AC16: 既存のテスト(plugins/ndf 一式)が通る。merged-steps.py cleanup の結果の JSON の形(items の kind・state・理由)は、足す値を除いて変わらない

非機能の条件

大項目 条件
運用・保守性 片付けで外したもの・残したものは、1 件ずつ置き場・removed / kept・理由が結果の JSON の items に出る。残したものは、人が手で外す前に理由を読める
性能・拡張性 片付けが GitHub へ問い合わせるのは、レビュー worktree 1 本につき Pull Request の状態の照会 1 回まで(一時ファイルの片付けは GitHub を呼ばない)
システム環境 Linux(devbase のコンテナ。/tmp が書き込み層で再起動しても消えない)と macOS の両方で同じに動く。一時の置き場は NDF_WORKTREE_BASE → tempfile.gettempdir() の順のまま

影響

対象 影響
公開インタフェース 変わる(互換あり)。merged-steps.py cleanup の items に rf<n> などの行が増える。投稿キューは、以前の実行の位置エラーの項目を外すようになる。引数は変わらない
データ 状態に持ち主を記録する形が足される(形は設計が決める)。持ち主の記録が無い既存の残骸は、前提 4 と AC3〜AC6 の判定に従う
既存の振る舞い merged の後片付けで rf<n> が外れる。cross-review / cross-refactoring / merged の実行の後に、持ち主の終わった一時のものが消える

検証手段

項目 手段
テスト uv run --frozen --project . --all-extras pytest plugins/ndf -q -n 4
静的解析・型検査 CI の既存のジョブ(python3 scripts/check-skill-frontmatter.py・python3 plugins/ndf/scripts/instructions-check.py --root .)。新しい検査は足さない
手動確認 配布の後、手元の devbase のコンテナで /tmp/ndf-worktrees/devbasex--ai-plugins/ の rf*(2026-10-31 時点で 4 本 2.0G)と ndf-worktree-*.json(79 件)・ndf-deps.*(26 件)が、cross-review か merged を 1 回回した後に、持ち主の生きているもの・作業の残るものを除いて消えたことを数えて確かめる(リリース後テスト)

前提とする取り決め

項目 参照先 / 決めたこと
プロジェクト構造 AGENTS.md。NDF の共通のコードは plugins/ndf/scripts/lib/、Skill 固有は各 Skill の scripts/。cross-review と cross-refactoring で同じ役割の関数を分けない(Value 6)
コーディング規約 AGENTS.md の「最小限のコード実装」。結果は統一の JSON レポート(tool・status・items)で返す
テスト戦略 片付けの判定(持ち主の生存・PR の状態・変更の有無)は、一時の git リポジトリと偽の gh を使う単体テストで確かめる。待ち行列は既存の test_a_position_rejection_of_an_earlier_item_is_not_taken_as_ours を AC11 の形へ書き換える。.md の文言を照合するテストは書かない

境界

区分 内容
常に行う 既存テストの実行、片付けの前の未コミットの変更・未 push のコミットの確認、残したものの理由の出力
確認してから行う 結果の JSON の形の変更、持ち主の記録の形(承認ゲート 1 の設計で人が見る)
行わない --force / -D での削除、open の Pull Request の worktree と開発 worktree の削除、常駐のプロセス・cron の追加、#2221・#2164・#2165 の修正

未決

項目 誰が決めるか 期限
AC11 で外した項目を dropped/ の控えに残すか総評へ移すか 設計(design) 設計 PR
持ち主の記録の形と、終わったかの判定の手段(プロセスの生存・PR の状態・時刻) 設計(design) 設計 PR
fix-pr<n>-*・ndf-tests-* の寿命(時刻で切るか、持ち主の終わりで切るか) 設計(design) 設計 PR
AC1 の一覧の置き場(コードの表か確定仕様か) 設計(design) 設計 PR

進行

モード: — / 進め方: auto

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

振り返り: #2282 (comment)

リリース後テスト(v10.27.2)で残ったこと

AC1〜AC16 はすべてテストで合格。AC3〜AC5 の手動確認(手元の残骸が片付けの後に減ること)は保留(記録: #2281 (comment) )。

  • 10.27.2 の片付けは、持ち主の記録の無い残骸を最後に動いた時刻から 24 時間(寿命の窓)残す。2026-10-31 20:08 JST の時点の残骸(/tmp/ndf-worktrees/devbasex--ai-plugins/ の rf 6 本・pr 3 本、ndf-worktree-*.json 68 件、ndf-deps.* 57 件)はすべて窓の中で、削除を止めた判定の再現では全件 kept だった
  • 確かめ直す時点: 持ち主の記録が残る rf2312 が窓を出る 2026-11-02 02:29 JST より後に、cross-review か merged を 1 回回してから件数を数える。合格の行を同じ記録の PR(Release: ndf v10.27.2 #2281)へ足し、sprint-close.py --record-pr 2281 --with-verification で閉じる
  • 2026-11-01 17:23 JST の時点の残骸は rf 3 本・pr 2 本(1.5G)、ndf-worktree-*.json 30 件、ndf-deps.* 5 件。削除を止めた片付けの模擬では、rf2268 は窓を出て removed、pr2277・pr2278 は Pull Request が open のため kept(AC7)、rf2283 は未コミットの変更 1 件のため kept(AC10)、rf2312 は finished_at が無いまま持ち主の窓の中で kept(cross-refactoring の init が着手前テストの打ち切りで止まると、持ち主の記録が残り次の実行を 24 時間断る #2321 に当たる見込み)

Activity

  1. added 6 commits that reference this issue on Oct 31, 2026
  2. takemi-ohama commented on Nov 1, 2026

    @takemi-ohama
    ContributorAuthor

    スプリントの終わりの工程を通りました

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

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions