fix(tui): keep background notifications in owning session (#42674) - #42731
fix(tui): keep background notifications in owning session (#42674)#42731raywcm wants to merge 3 commits into
Conversation
…aned events Two complementary fixes for cross-session background-process notification leakage in the TUI/Desktop multi-session path (NousResearch#42674, NousResearch#35652). 1. Poller orphan guard: after _notification_event_belongs_elsewhere returns False, check whether the event has a non-empty session_key that differs from the current session. If so the owner session is gone — drop the event instead of hijacking it into an unrelated session transcript. 2. Post-turn drain filter: the existing drain_notifications() pops every event from the global queue regardless of ownership. Added _drain_owned_notifications() which applies the same ownership routing used by the poller (consume own, requeue foreign-live, drop orphan), and wired it into the post-turn safety drain. Complementary to PR NousResearch#42731 which addresses a separate code path in the same bug class. Together they close NousResearch#42674.
|
Thanks for isolating the post-turn drain path. The premise is still valid on current main: Problems
Suggested changes
Automated hermes-sweeper review. |
…aned events Two complementary fixes for cross-session background-process notification leakage in the TUI/Desktop multi-session path (NousResearch#42674, NousResearch#35652). 1. Poller orphan guard: after _notification_event_belongs_elsewhere returns False, check whether the event has a non-empty session_key that differs from the current session. If so the owner session is gone — drop the event instead of hijacking it into an unrelated session transcript. 2. Post-turn drain filter: the existing drain_notifications() pops every event from the global queue regardless of ownership. Added _drain_owned_notifications() which applies the same ownership routing used by the poller (consume own, requeue foreign-live, drop orphan), and wired it into the post-turn safety drain. Complementary to PR NousResearch#42731 which addresses a separate code path in the same bug class. Together they close NousResearch#42674.
…aned events Two complementary fixes for cross-session background-process notification leakage in the TUI/Desktop multi-session path (#42674, #35652). 1. Poller orphan guard: after _notification_event_belongs_elsewhere returns False, check whether the event has a non-empty session_key that differs from the current session. If so the owner session is gone — drop the event instead of hijacking it into an unrelated session transcript. 2. Post-turn drain filter: the existing drain_notifications() pops every event from the global queue regardless of ownership. Added _drain_owned_notifications() which applies the same ownership routing used by the poller (consume own, requeue foreign-live, drop orphan), and wired it into the post-turn safety drain. Complementary to PR #42731 which addresses a separate code path in the same bug class. Together they close #42674.
|
Closing as superseded by #65419 (merged) — the post-turn drain now passes session_key + the compression-chain-aware owns_event callback + skip_poll_observed=False, which covers everything _drain_owned_notifications() did plus lineage resolution and a requeue-when-running guard. Your diagnosis of the bare drain_notifications() call was correct a month before the rest of us got there — thanks @raywcm, and sorry this sat long enough to be fixed out from under it. |
…aned events Two complementary fixes for cross-session background-process notification leakage in the TUI/Desktop multi-session path (NousResearch#42674, NousResearch#35652). 1. Poller orphan guard: after _notification_event_belongs_elsewhere returns False, check whether the event has a non-empty session_key that differs from the current session. If so the owner session is gone — drop the event instead of hijacking it into an unrelated session transcript. 2. Post-turn drain filter: the existing drain_notifications() pops every event from the global queue regardless of ownership. Added _drain_owned_notifications() which applies the same ownership routing used by the poller (consume own, requeue foreign-live, drop orphan), and wired it into the post-turn safety drain. Complementary to PR NousResearch#42731 which addresses a separate code path in the same bug class. Together they close NousResearch#42674.
…aned events Two complementary fixes for cross-session background-process notification leakage in the TUI/Desktop multi-session path (NousResearch#42674, NousResearch#35652). 1. Poller orphan guard: after _notification_event_belongs_elsewhere returns False, check whether the event has a non-empty session_key that differs from the current session. If so the owner session is gone — drop the event instead of hijacking it into an unrelated session transcript. 2. Post-turn drain filter: the existing drain_notifications() pops every event from the global queue regardless of ownership. Added _drain_owned_notifications() which applies the same ownership routing used by the poller (consume own, requeue foreign-live, drop orphan), and wired it into the post-turn safety drain. Complementary to PR NousResearch#42731 which addresses a separate code path in the same bug class. Together they close NousResearch#42674.
What does this PR do?
Fixes a Desktop/TUI cross-session notification path for background process completions.
The poller path already skips events whose
session_keybelongs to another live session, but the post-turn safety drain still calledprocess_registry.drain_notifications()directly. That method drains the global process completion queue, so a turn finishing in session B could consume and dispatch anotify_on_completeevent that was started by session A.This PR adds a small TUI-owned drain helper that filters drained events with the same ownership check used by the poller, requeues foreign live-session events, and only dispatches notifications owned by the current session (plus global/orphan notifications).
Related Issue
Fixes #42674
Related to #35652, but this targets the post-turn drain path rather than the between-turn poller path.
Type of Change
Changes Made
tui_gateway/server.py_drain_owned_notifications()to drain only notifications owned by the current TUI session.tests/test_tui_gateway_server.pyHow to Test
notify_on_complete=True.Local verification performed:
I could not run the full pytest suite in this PRoot environment because cloning/extracting the full repository repeatedly timed out; the patch was prepared via GitHub Contents API against
mainand syntax-checked locally.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/AFor New Skills
N/A
Screenshots / Logs
Syntax checks: