fix(gateway): freshness-gate resume_pending against per-message zombies - #56264
Merged
Conversation
A crash-interrupted session marked resume_pending is returned by get_or_create_session so its transcript reloads intact. The idle/daily reset policy (#54442) keys on updated_at, which is bumped to now on every message — so a zombie session that keeps receiving messages never trips it and resumes stale context forever (context bleed reported on Telegram and Feishu). Gate the resume_pending branch on last_resume_marked_at (set once at resume-mark, never bumped per-message) against the auto-continue freshness window. If resume has been pending past the window, fall through to auto-reset with reason "resume_pending_expired". A window <= 0 disables the gate (opt-out for the pre-fix always-fresh behaviour). Also hoist auto_continue_freshness_window() into gateway/session.py as the single source of truth; gateway/run._auto_continue_freshness_window() now delegates to it (keeps the existing import/patch surface). Fixes #46934 Co-authored-by: Hermes Agent <noreply@nousresearch.com>
Collaborator
This was referenced Jul 1, 2026
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
A crash-interrupted session marked
resume_pendingnow falls through to a fresh session once resume has been pending past the freshness window — closing the zombie-session context bleed reported on Telegram and Feishu.Root cause:
#54442added_should_reset()to theresume_pendingbranch, but that policy keys onupdated_at, which is bumped tonowon every message. A zombie session that keeps receiving messages therefore never goes idle and resumes its stale transcript forever.Changes
gateway/session.py: gate theresume_pendingbranch onlast_resume_marked_at(set once at resume-mark, never bumped per-message) vs the auto-continue freshness window. Past the window → auto-reset with reason"resume_pending_expired". Window<= 0disables the gate (opt-out).gateway/session.py: hoistauto_continue_freshness_window()here as the single source of truth.gateway/run.py:_auto_continue_freshness_window()now delegates to the session-module helper (import/patch surface preserved).tests/gateway/test_clean_shutdown_marker.py: 3 tests — fresh returns same session, per-message zombie (freshupdated_at, stale mark) resets, window=0 opt-out.Validation
updated_at, resume pending > window)HERMES_AUTO_CONTINUE_FRESHNESS=0Targeted tests: 86/86 green (incl.
test_restart_resume_pending,_auto_continue_freshness_windowhelper tests). E2E verified against real imports with a tempHERMES_HOME.Salvaged from #46963 by @annguyenNous (authorship preserved). Supersedes #43392.
Fixes #46934
Infographic