From 06ebecb329c38453970f2f19a26119908d531d52 Mon Sep 17 00:00:00 2001 From: Hare Date: Thu, 28 May 2026 22:25:28 +0900 Subject: [PATCH] ticket: close spawnpod initial run confirmation --- .../artifacts/.gitkeep | 0 .../item.md | 4 +- .../resolution.md | 84 ++++++++++++++++ .../thread.md | 99 +++++++++++++++++++ .../thread.md | 7 -- 5 files changed, 185 insertions(+), 9 deletions(-) rename work-items/{open => closed}/20260527-000012-spawnpod-initial-run-confirmation/artifacts/.gitkeep (100%) rename work-items/{open => closed}/20260527-000012-spawnpod-initial-run-confirmation/item.md (99%) create mode 100644 work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/resolution.md create mode 100644 work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/thread.md delete mode 100644 work-items/open/20260527-000012-spawnpod-initial-run-confirmation/thread.md diff --git a/work-items/open/20260527-000012-spawnpod-initial-run-confirmation/artifacts/.gitkeep b/work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/artifacts/.gitkeep similarity index 100% rename from work-items/open/20260527-000012-spawnpod-initial-run-confirmation/artifacts/.gitkeep rename to work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/artifacts/.gitkeep diff --git a/work-items/open/20260527-000012-spawnpod-initial-run-confirmation/item.md b/work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/item.md similarity index 99% rename from work-items/open/20260527-000012-spawnpod-initial-run-confirmation/item.md rename to work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/item.md index 48c02cd6..93e63b85 100644 --- a/work-items/open/20260527-000012-spawnpod-initial-run-confirmation/item.md +++ b/work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/item.md @@ -2,12 +2,12 @@ id: 20260527-000012-spawnpod-initial-run-confirmation slug: spawnpod-initial-run-confirmation title: SpawnPod: initial Run delivery confirmation -status: open +status: closed kind: task priority: P2 labels: [migrated] created_at: 2026-05-27T00:00:12Z -updated_at: 2026-05-28T13:05:40Z +updated_at: 2026-05-28T13:24:48Z assignee: null legacy_ticket: tickets/spawnpod-initial-run-confirmation.md --- diff --git a/work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/resolution.md b/work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/resolution.md new file mode 100644 index 00000000..93e63b85 --- /dev/null +++ b/work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/resolution.md @@ -0,0 +1,84 @@ +--- +id: 20260527-000012-spawnpod-initial-run-confirmation +slug: spawnpod-initial-run-confirmation +title: SpawnPod: initial Run delivery confirmation +status: closed +kind: task +priority: P2 +labels: [migrated] +created_at: 2026-05-27T00:00:12Z +updated_at: 2026-05-28T13:24:48Z +assignee: null +legacy_ticket: tickets/spawnpod-initial-run-confirmation.md +--- + +## Migration reference + +- legacy_ticket: tickets/spawnpod-initial-run-confirmation.md +- migrated_from: TODO.md / tickets directory migration on 2026-05-27 + +# SpawnPod: initial Run delivery confirmation + +## 背景 + +`SpawnPod` は child Pod を起動し、初回 task を `Method::Run` として送る。しかし、実例として `impl-llm-worker-stream-continuation` を再作成した際、runtime registry / socket / process は生きている一方で、初回 task の session log が materialize されず、Pod は `idle` のままだった。 + +確認された状態: + +- `/pods.json` に live allocation がある +- `//status.json` は `state: "idle"` と runtime `segment_id` を持つ +- `/pods//metadata.json` は pending segment のまま +- 対応する session / segment `.jsonl` が存在しない +- `ReadPodOutput` は no new assistant text + +`SpawnPod` の送信側は `send_run` で `Method::Run` を write してすぐ切断し、`TurnStart` 等の ack を待っていない。一方 server 側は接続直後に `Snapshot` を書いてから method を読むため、client がすぐ close すると server が snapshot write で失敗し、method を読む前に connection handler が終了する race があり得る。 + +この場合 `SpawnPod` は成功を返すが、child Pod は初回 task を実行していない。 + +同種の問題は child Pod の通知経路でも既に踏んでおり、送信側が write 後にすぐ切断せず、receiver 側の acknowledgement / observable event を待つ形にして解消している。`SpawnPod` の初回 task delivery も同じ性質の race と見なす。 + +追加確認として、Pod socket server は接続直後に replayed `Alert` と connect-time `Snapshot` を送ってから client `Method` を読む。したがって one-shot / send-only client は初期 event を消化してから Method を送る必要がある。 + +- `send_run_and_confirm` は `Method::Run` を送った後に event を読む実装になっており、Snapshot が大きい場合や Run payload が大きい場合に双方向で詰まる余地がある。 +- `connect_and_send` / `fetch_history` は既に Snapshot まで drain / read しており、この系統の問題は対策済み。 +- `probe_socket` は最初の event だけを見て `Snapshot` でなければ status を取らないため、replayed `Alert` が先に来る live Pod で reachable だが status unknown になる可能性がある。 +- `PodClient::connect` は background reader を起動するため、通常の TUI attach / interactive client では初期 Snapshot を詰まらせにくい。 + +## 方針 + +`SpawnPod` は child process / socket の起動だけでなく、初回 task が controller に受理され、少なくとも `UserMessage` または `TurnStart` が観測できるまで確認してから成功を返す。 + +既存の `SendToPod` / `SpawnPod` が使う run delivery confirmation ロジックを、接続直後の `Alert` / `Snapshot` drain を含む形へ共通化・安全化する。 + +## 要件 + +- `SpawnPod` の初回 task 送信は fire-and-forget にしない。 + - `Method::Run` 送信後、`UserMessage` / `TurnStart` / `InvokeStart` など、run が受理されたことを示す event を待つ。 + - timeout 時は `SpawnPod` を失敗扱いにする。 +- 初回 task delivery に失敗した場合、process / registry / delegated scope の扱いを明確にする。 + - cleanup するか、attach 可能な idle Pod として残すかを実装で決める。 + - 少なくとも成功扱いで返さない。 +- Server が connection 開始時に `Alert` / `Snapshot` を書く設計と競合しない。 + - client 側が `Alert` / `Snapshot` を読みながら `Method::Run` ack を待つ形にする。 + - `send_run_and_confirm` は connect-time `Snapshot` を消化してから `Method::Run` を送る。 +- live Pod status probe は replayed `Alert` によって status 取得を落とさない。 + - `probe_socket` は first event だけで判断せず、`Snapshot` まで初期 event を読む。 +- `SpawnPod` 成功後は、child Pod の metadata が pending でも、初回 run が開始済みであることを確認できる。 + - session log materialization のタイミングそのものは別設計でもよい。 +- `SendToPod` と `SpawnPod` の run delivery confirmation ロジックを可能な範囲で共通化する。 + +## 完了条件 + +- `SpawnPod` が初回 task の受理確認を待つ。 +- 初回 task が実行されない race を再現する test または regression test がある。 +- connect-time `Alert` / `Snapshot` がある状態でも `send_run_and_confirm` が詰まらず、受理 event を観測する regression test がある。 +- `probe_socket` が replayed `Alert` の後の `Snapshot` から status を取得できる regression test がある。 +- `SpawnPod` が success を返した後、child Pod が idle pending のまま task 未実行になる状態が起きない。 +- delivery timeout / failure 時の error message が人間に分かる。 +- `cargo fmt --check` と関連 crate の test が通る。 + +## 範囲外 + +- `tui -r` picker に live pending Pod を表示する修正。 +- session log の SegmentStart materialization 方針変更。 +- spawned child Pod panel UI。 diff --git a/work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/thread.md b/work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/thread.md new file mode 100644 index 00000000..2457d91b --- /dev/null +++ b/work-items/closed/20260527-000012-spawnpod-initial-run-confirmation/thread.md @@ -0,0 +1,99 @@ + + +## Migrated + +Migrated from tickets/spawnpod-initial-run-confirmation.md. No legacy review file was present at migration time. + +--- + + + +## Closed + +--- +id: 20260527-000012-spawnpod-initial-run-confirmation +slug: spawnpod-initial-run-confirmation +title: SpawnPod: initial Run delivery confirmation +status: closed +kind: task +priority: P2 +labels: [migrated] +created_at: 2026-05-27T00:00:12Z +updated_at: 2026-05-28T13:24:48Z +assignee: null +legacy_ticket: tickets/spawnpod-initial-run-confirmation.md +--- + +## Migration reference + +- legacy_ticket: tickets/spawnpod-initial-run-confirmation.md +- migrated_from: TODO.md / tickets directory migration on 2026-05-27 + +# SpawnPod: initial Run delivery confirmation + +## 背景 + +`SpawnPod` は child Pod を起動し、初回 task を `Method::Run` として送る。しかし、実例として `impl-llm-worker-stream-continuation` を再作成した際、runtime registry / socket / process は生きている一方で、初回 task の session log が materialize されず、Pod は `idle` のままだった。 + +確認された状態: + +- `/pods.json` に live allocation がある +- `//status.json` は `state: "idle"` と runtime `segment_id` を持つ +- `/pods//metadata.json` は pending segment のまま +- 対応する session / segment `.jsonl` が存在しない +- `ReadPodOutput` は no new assistant text + +`SpawnPod` の送信側は `send_run` で `Method::Run` を write してすぐ切断し、`TurnStart` 等の ack を待っていない。一方 server 側は接続直後に `Snapshot` を書いてから method を読むため、client がすぐ close すると server が snapshot write で失敗し、method を読む前に connection handler が終了する race があり得る。 + +この場合 `SpawnPod` は成功を返すが、child Pod は初回 task を実行していない。 + +同種の問題は child Pod の通知経路でも既に踏んでおり、送信側が write 後にすぐ切断せず、receiver 側の acknowledgement / observable event を待つ形にして解消している。`SpawnPod` の初回 task delivery も同じ性質の race と見なす。 + +追加確認として、Pod socket server は接続直後に replayed `Alert` と connect-time `Snapshot` を送ってから client `Method` を読む。したがって one-shot / send-only client は初期 event を消化してから Method を送る必要がある。 + +- `send_run_and_confirm` は `Method::Run` を送った後に event を読む実装になっており、Snapshot が大きい場合や Run payload が大きい場合に双方向で詰まる余地がある。 +- `connect_and_send` / `fetch_history` は既に Snapshot まで drain / read しており、この系統の問題は対策済み。 +- `probe_socket` は最初の event だけを見て `Snapshot` でなければ status を取らないため、replayed `Alert` が先に来る live Pod で reachable だが status unknown になる可能性がある。 +- `PodClient::connect` は background reader を起動するため、通常の TUI attach / interactive client では初期 Snapshot を詰まらせにくい。 + +## 方針 + +`SpawnPod` は child process / socket の起動だけでなく、初回 task が controller に受理され、少なくとも `UserMessage` または `TurnStart` が観測できるまで確認してから成功を返す。 + +既存の `SendToPod` / `SpawnPod` が使う run delivery confirmation ロジックを、接続直後の `Alert` / `Snapshot` drain を含む形へ共通化・安全化する。 + +## 要件 + +- `SpawnPod` の初回 task 送信は fire-and-forget にしない。 + - `Method::Run` 送信後、`UserMessage` / `TurnStart` / `InvokeStart` など、run が受理されたことを示す event を待つ。 + - timeout 時は `SpawnPod` を失敗扱いにする。 +- 初回 task delivery に失敗した場合、process / registry / delegated scope の扱いを明確にする。 + - cleanup するか、attach 可能な idle Pod として残すかを実装で決める。 + - 少なくとも成功扱いで返さない。 +- Server が connection 開始時に `Alert` / `Snapshot` を書く設計と競合しない。 + - client 側が `Alert` / `Snapshot` を読みながら `Method::Run` ack を待つ形にする。 + - `send_run_and_confirm` は connect-time `Snapshot` を消化してから `Method::Run` を送る。 +- live Pod status probe は replayed `Alert` によって status 取得を落とさない。 + - `probe_socket` は first event だけで判断せず、`Snapshot` まで初期 event を読む。 +- `SpawnPod` 成功後は、child Pod の metadata が pending でも、初回 run が開始済みであることを確認できる。 + - session log materialization のタイミングそのものは別設計でもよい。 +- `SendToPod` と `SpawnPod` の run delivery confirmation ロジックを可能な範囲で共通化する。 + +## 完了条件 + +- `SpawnPod` が初回 task の受理確認を待つ。 +- 初回 task が実行されない race を再現する test または regression test がある。 +- connect-time `Alert` / `Snapshot` がある状態でも `send_run_and_confirm` が詰まらず、受理 event を観測する regression test がある。 +- `probe_socket` が replayed `Alert` の後の `Snapshot` から status を取得できる regression test がある。 +- `SpawnPod` が success を返した後、child Pod が idle pending のまま task 未実行になる状態が起きない。 +- delivery timeout / failure 時の error message が人間に分かる。 +- `cargo fmt --check` と関連 crate の test が通る。 + +## 範囲外 + +- `tui -r` picker に live pending Pod を表示する修正。 +- session log の SegmentStart materialization 方針変更。 +- spawned child Pod panel UI。 + + +--- diff --git a/work-items/open/20260527-000012-spawnpod-initial-run-confirmation/thread.md b/work-items/open/20260527-000012-spawnpod-initial-run-confirmation/thread.md deleted file mode 100644 index 8870382b..00000000 --- a/work-items/open/20260527-000012-spawnpod-initial-run-confirmation/thread.md +++ /dev/null @@ -1,7 +0,0 @@ - - -## Migrated - -Migrated from tickets/spawnpod-initial-run-confirmation.md. No legacy review file was present at migration time. - ----