Skip to content

Fix #39704: Guard session transcript rewrite on successful rotation - #41000

Closed
iamlukethedev wants to merge 1 commit into
NousResearch:mainfrom
iamlukethedev:fix/39704-session-hygiene-overwrite
Closed

iamlukethedev wants to merge 1 commit into
NousResearch:mainfrom
iamlukethedev:fix/39704-session-hygiene-overwrite

Conversation

@iamlukethedev

Copy link
Copy Markdown
Contributor

Fixes #39704: Session Hygiene compression overwrites original messages when _session_db is None, permanently deleting 200+ messages.

Problem

  • Gateway Session Hygiene compression checks if session rotation succeeded by comparing old/new session IDs
  • When _session_db is None, compress_context() skips rotation, leaving session ID unchanged
  • BUT rewrite_transcript() was called UNCONDITIONALLY on the original session
  • Result: 200+ original messages deleted and replaced with ~7 compressed messages (irreversible data loss)

Root Cause

  • Line 9314 comment said 'Write to NEW session so old transcript stays intact'
  • But line 9327 rewrite_transcript() was unconditional while rotation was conditional
  • When rotation failed, transcript was still overwritten

Solution

  • Move rewrite_transcript() INSIDE the if-block confirming successful rotation
  • Only rewrite when _hyg_new_sid != session_entry.session_id
  • When rotation fails, keep compressed in memory only, don't persist to DB
  • Add warning when rotation fails

Tests

  • 4 new tests verify rotation guard works correctly
  • All 152 compression tests pass
  • No regressions in agent context compression

…l rotation

Fixes NousResearch#39704: Session Hygiene compression overwrites original messages when
_session_db is None, permanently deleting hundreds of messages.

PROBLEM:
- Gateway Session Hygiene compression via _compress_context() checks if session
  rotation succeeded by comparing old and new session IDs (line 9319)
- When _session_db is None, compress_context() skips rotation entirely, leaving
  the session ID unchanged
- However, rewrite_transcript() was called UNCONDITIONALLY (line 9327), even when
  rotation failed
- This resulted in the original session's messages (200+ messages) being deleted
  and replaced with ~7 compressed messages — irreversible data loss

ROOT CAUSE:
- The comment at line 9314 said 'Write compressed messages into the NEW session
  so the old transcript stays intact' but the code didn't follow this intent
- rewrite_transcript() was unconditional while session rotation was conditional

SOLUTION:
- Move rewrite_transcript() INSIDE the if-block that confirms successful rotation
- Only rewrite the transcript when _hyg_new_sid != session_entry.session_id
  (session was actually rotated)
- When rotation fails, keep compressed messages in memory only (for current API
  call) but do NOT persist to database
- Add warning log when rotation fails due to unavailable _session_db

TESTS:
- 4 new tests verify:
  * rewrite_transcript only called after successful rotation
  * rewrite_transcript called when session ID changes
  * session rotation skipped when _session_db is None
  * original messages preserved when rotation fails
- All 152 compression-related tests pass
- No regressions in agent context compression
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery tool/memory Memory tool and memory providers P1 High — major feature broken, no workaround labels Jun 7, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Automated hermes-sweeper review: this PR's fix is now implemented on current main.

Evidence:

  • gateway/run.py:9274 computes the hygiene compression session id and gateway/run.py:9297 calls rewrite_transcript() only when rotation occurred or in-place compaction succeeded; the no-rotation branch preserves the original transcript and logs a warning.
  • tests/gateway/test_session_hygiene.py:399 covers the no-rotation regression and asserts rewrite_transcript is not called.
  • The implementing commit is 4c349e85f8e88acb5f970705a3fd16a469d76d25 (fix(gateway): preserve transcript when hygiene auto-compress can't rotate), which is present on current main.

Thanks for the report and patch — the current mainline fix also accounts for the in-place compaction success path while preserving the same data-loss guard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P1 High — major feature broken, no workaround sweeper:implemented-on-main Sweeper: behavior already present on current main tool/memory Memory tool and memory providers type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Session Hygiene compression overwrites original messages when _session_db is None

3 participants