fix(tui): enforce notification session ownership across all drain paths - #63317
Closed
abhibansal-sg wants to merge 1 commit into
Closed
fix(tui): enforce notification session ownership across all drain paths#63317abhibansal-sg wants to merge 1 commit into
abhibansal-sg wants to merge 1 commit into
Conversation
2 tasks
yingliang-zhang
added a commit
to yingliang-zhang/hermes-agent
that referenced
this pull request
Jul 15, 2026
Adapt the strongest NousResearch#63317 live-loop handoff regression and cover lineage lookup failure plus addressed live-loop orphans. Co-authored-by: Abhinav Bansal <abhibansal-sg@users.noreply.github.com>
Contributor
Author
|
Closing in favor of #54785, which carries this ownership-routing fix forward on current main (our live-loop regression coverage already adopted there). |
teknium1
pushed a commit
that referenced
this pull request
Jul 16, 2026
Adapt the strongest #63317 live-loop handoff regression and cover lineage lookup failure plus addressed live-loop orphans. Co-authored-by: Abhinav Bansal <abhibansal-sg@users.noreply.github.com>
This was referenced Jul 16, 2026
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
Adapt the strongest NousResearch#63317 live-loop handoff regression and cover lineage lookup failure plus addressed live-loop orphans. Co-authored-by: Abhinav Bansal <abhibansal-sg@users.noreply.github.com>
randlee
pushed a commit
to randlee/hermes-agent
that referenced
this pull request
Aug 11, 2026
Adapt the strongest NousResearch#63317 live-loop handoff regression and cover lineage lookup failure plus addressed live-loop orphans. Co-authored-by: Abhinav Bansal <abhibansal-sg@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Background-process completion notifications now deliver only to the session that owns them; a multi-session
tui_gatewayprocess can no longer inject one session's process output into another session's conversation.Closes #35652.
Changes
owns_eventcallback /session_keyequality) inProcessRegistry.drain_notifications()to every session-scoped notification type — previously onlytype == "async_delegation"was filtered (bug: delegate_task async results delivered to wrong session/thread #58684/Desktop async delegation completions can revive an old session while follow-up prompts create a new session #55578 scope), so plaincompletion/watch_match/watch_disabledevents were consumed by whichever session's post-turn drain or poller woke first._session_owns_notification_event, compression-lineage aware) before the TUI live poller creates a conversation turn from a completion — "not provably elsewhere" is no longer sufficient.processtool log/poll), and callback exceptions fail closed with requeue.Behaviour
Before: with two live sessions in one
hermes dashboard/--tuiprocess, session A'sterminal(background=true, notify_on_complete=true)completion could surface as an[IMPORTANT: Background process …]turn in session B while A was live — exactly the residual drain path flagged by @gvago (second unscoped drain site) and reproduced by @Evisolpxe in #35652. On the reporting machine this fired 6 times in one evening, deterministically, from the busiest session's post-turn drain.After: completions route to their owning session only; foreign events are requeued for their owner; ownerless events surface in the registry, never in a chat. Verified live on the reproduction machine in both directions (own-process → own-session, and the original steal topology with the thief session mid-turn): 6 leaks/evening → 0.
Validation
scripts/run_tests.sh tests/test_tui_gateway_server.py tests/tui_gateway/)git diff --checkExecution-context review of every modified call site:
drain_notifications()stays synchronous in its caller with non-blocking queue ops; the poller/shutdown/post-turn drains run on their existing per-session daemon threads; a slow lineage DB lookup delays only that session's poller, never the JSON-RPC loop; raw-key matches avoid DB access entirely.Infographic