fix(cli): scope async delegation delivery to session - #64240
Conversation
…atch identity Three-layer companion to the salvaged CLI drain-ownership fix (#64240): 1. restore_undelivered_completions stamps restored=True (in-memory only) on every durable completion re-enqueued at process start. 2. drain_notifications' legacy unfiltered branch re-queues restored events instead of consuming them — a fresh process can no longer adopt a dead session's delegation results (#64484). Same-process keyless events keep the legacy behavior. 3. delegate_tool's async dispatch now falls back to the parent agent's durable session_id when the approval-context key resolves empty (the CLI case), so the CLI's new positive-ownership drain can actually claim its own completions instead of failing closed on ''.
|
Merged via #64593 — your commit cherry-picked onto current main with authorship preserved (rebase-merge). Two companion layers added on top: (1) |
…atch identity Three-layer companion to the salvaged CLI drain-ownership fix (NousResearch#64240): 1. restore_undelivered_completions stamps restored=True (in-memory only) on every durable completion re-enqueued at process start. 2. drain_notifications' legacy unfiltered branch re-queues restored events instead of consuming them — a fresh process can no longer adopt a dead session's delegation results (NousResearch#64484). Same-process keyless events keep the legacy behavior. 3. delegate_tool's async dispatch now falls back to the parent agent's durable session_id when the approval-context key resolves empty (the CLI case), so the CLI's new positive-ownership drain can actually claim its own completions instead of failing closed on ''.
…atch identity Three-layer companion to the salvaged CLI drain-ownership fix (NousResearch#64240): 1. restore_undelivered_completions stamps restored=True (in-memory only) on every durable completion re-enqueued at process start. 2. drain_notifications' legacy unfiltered branch re-queues restored events instead of consuming them — a fresh process can no longer adopt a dead session's delegation results (NousResearch#64484). Same-process keyless events keep the legacy behavior. 3. delegate_tool's async dispatch now falls back to the parent agent's durable session_id when the approval-context key resolves empty (the CLI case), so the CLI's new positive-ownership drain can actually claim its own completions instead of failing closed on ''.
Summary
Problem
#60869 added session-aware async completion filtering to the process registry and routed gateway/TUI callers, but the classic CLI retained two unsafe call sites:
Because the process notification queue is profile-global, a sibling classic CLI process could claim and acknowledge a completion dispatched by another session. The origin session would then never receive it.
This is a focused follow-up to #58684 and #60869. Non-delegation process and watch notifications retain their existing behavior; ownership filtering applies only to
async_delegationevents in the registry.Verification
Manual regression on macOS:
1and the recorded owner PID matched the origin process.The repository-wide wrapper was also sampled but is not a clean macOS gate in this checkout because unrelated Linux-only tests require
systemctl. The focused CLI/process/session suites above are clean.Tested on macOS 26.3.1 with Python 3.11.