7.8 KiB
7.8 KiB
Review: 親が投げたターンのみを子→親 callback の対象にする
対象コミット: 8019d0d update: 親にターン完了を通達する経路の整理
前提・要件の確認
- TurnEnded を親由来 turn の
Finishedに限定: 満たされている。controller_loopでrun.is_parent_originated()を取り、drive_turnのparent_originated引数として伝搬。drive_turn内Finished分岐 (controller.rs:796) でparent_originated && Finished双方が立ったときのみPodEvent::TurnEndedをfire_and_forget。 - 「親由来」の判定が
PendingRunバリアントベース (Run/InterruptAndRun/Resume= true、RunForNotification= false): 満たされている。PendingRun::is_parent_originated()(controller.rs:108-113) のマッチがチケットの表と一致。pending_run_parent_origin_tableテスト (controller.rs:1043-1048) で 4 バリアントすべてを assert。 - Errored を同スコープに揃える: 満たされている。
drive_turnのErr(e)分岐 (controller.rs:822-830) をif parent_originated { ... }でゲート。Event::Errorのローカル broadcast (controller.rs:818-821) は無条件のままで「Event::Errorローカル通知は維持」の要件も満たす。Err(PodError::Worker(WorkerError::Cancelled)) if pause_requested分岐 (controller.rs:806-814) は元からErroredを上げない設計で、本チケットでは触れていないため変更なし。妥当。 PodEvent::ShutDownは対象外、従来通り: 満たされている。controller_loopの loop 終了後 (controller.rs:734-745) のsend_pod_event(ShutDown)にはparent_originatedもdrive_turnも介在しない。発火条件不変を確認。ScopeSubDelegatedは対象外: 満たされている。spawn/tool.rs:278が発火元で、drive_turnのゲートとは無関係。今回の diff でcontroller.rsのみが変更されており影響しない。- 親側受信処理は変更しない: 満たされている。
diff は
crates/pod/src/controller.rsのみ。apply_event_side_effects/NotifyBuffer/ history append 経路は変更なし。
完了条件の確認
- SpawnPod 初回 Run / SendToPod 完了 → 親 history に 1 件 append:
PendingRun::Run/InterruptAndRun経路でparent_originated=trueとなり、上記 TurnEnded ゲートを通過。受信側を変更していないため挙動成立。 - 孫 PodEvent / 他 Notify 起点の auto-kick 完了 → 親 history に何も append しない:
PendingRun::RunForNotification経路でparent_originated=false→ 親へ何も飛ばない → 親側で受信しないので append も起こらない。 - 親由来 turn の worker エラー →
Erroredが親に届く /RunForNotificationの worker エラー → 届かない:Erroredゲートで確認済み。 - ユニットテスト 4 種: 仕様マップは以下の通り。
- 「
PendingRun::Run完了 → 親に届く」 →parent_originated_finished_fires_turn_ended(controller.rs:1052-) でparent_originated=true+Finishedを駆動し、Unix socket でPodEvent::TurnEndedを受信。 - 「
PendingRun::RunForNotification完了 → 親に届かない」 →non_parent_originated_finished_stays_silent(controller.rs:1080-) でparent_originated=false+Finishedを駆動し accept timeout を期待。 - 「
PendingRun::Resume完了 → 親に届く」 → 直接的な統合テストは無いが、pending_run_parent_origin_tableでPendingRun::Resume.is_parent_originated() == trueを assert +parent_originated=true経由のdrive_turn動作をparent_originated_finished_fires_turn_endedで検証しており、Resume → true → 親に届くの合成は閉じている。フォローアップ参照。 - 「
RunForNotification起点 turn の Errored → 親に届かない」 →non_parent_originated_worker_error_stays_silent(controller.rs:1146-) で確認。
- 「
- ローカルで
cargo test -p pod --libを実行し 173/173 パス、新規 5 ケースもすべて green。
アーキテクチャ・スコープ
- 起源情報はすでに
controller_loopがPendingRunで表現済みで、新規追加はis_parent_originated()1 メソッドのみ。enum バリアント追加や別構造体の導入は無く、表現を最短ルートで再利用しており設計を歪めていない。 drive_turnの引数増 (1 個追加) は#[allow(clippy::too_many_arguments)]配下で、シグネチャの煩雑さは既存水準を踏み越えていない。代替案としてPendingRun自体をdrive_turnに渡す案も考えられるが、現状drive_turnは具体的なpod_futureを呼び出し側で生成する形のため、bool 引数の方が責務境界がクリーンで妥当。- 変更ファイルは
crates/pod/src/controller.rsのみ。protocol / event 側 / 親側受信ロジックには触れず、ファイアウォール的に発火源だけを絞る意図と一致。 controller.rsの 264 行追加のうち約 220 行がテストモジュール + テストヘルパ (DriveTurnEnv/make_env/recv_pod_event)、本体ロジックは 44 行程度。スコープ外変更や別件リファクタの紛れ込みは無い。- LLM provider policy / crate 命名 /
cargo add規約に関わる変更は無く、該当無し。
指摘事項
Non-blocking / Follow-up
- 完了条件 4 番目で
PendingRun::Resume完了の単体テストが明記されているが、現状のdrive_turnテストではparent_originated: boolのみが入力次元のため、Resume → trueの対応関係はpending_run_parent_origin_tableの 1 行 assert に依存している。設計上は同値だが、ticket 文言との対応をより明示するためにparent_originated_finished_fires_turn_endedのResume命名バリアント (例:resume_finished_fires_turn_endedをpod.resume()future ではなくparent_originated=trueで駆動) を追加するか、ヘルパ + parameterized 化しておくと将来の読み手が辿りやすい。 DriveTurnEnvのrecv_pod_eventは 2 秒タイムアウトで OK、negative side は 200ms で accept がエラーになることを「届かなかった」と判定している。基本問題ないが、CI で I/O が詰まると false-positive で pass する余地はある (届くべき送信が来なかったのを「来なかったので OK」と読み違える)。本チケットの 2 種類の negative テスト両方がFinished/Errを即時返すasync { ... }future を使っており実 IO レイテンシは無いため実害は小さい。
Nits
DriveTurnEnvのフィールドコメント (_method_tx) は select! arm がNoneを観測しないようにする意図を 1 行で説明していて読みやすい。継続コード変更で気づきにくくなるポイントなので、もしmake_env経由のテストを増やしていく場合はこのコメントを残す方針で。parent_originatedという命名は明快。is_parent_originatedヘルパの doc コメントがRunForNotificationの意味も列挙しており、enum の意味論を 1 か所で説明する役割を果たせている。
判断
Approve — 要件 5 点・完了条件 4 点はいずれも実装とテストで充足。設計は既存の PendingRun 表現を再利用する最短手で、スコープ外変更や API 表面の過剰な拡張は無い。Resume 単体テスト不在は厳密には完了条件 4 番目との突き合わせで指摘可能だが、pending_run_parent_origin_table + parent_originated=true の挙動テストの合成で要件は閉じており blocking ではない。