Skip to content

fix(agent): clear _previous_summary on session end to prevent cross-contamination (#38788)#39725

Closed
dusterbloom wants to merge 1 commit into
NousResearch:mainfrom
dusterbloom:fix/session-isolation-cross-contamination
Closed

fix(agent): clear _previous_summary on session end to prevent cross-contamination (#38788)#39725
dusterbloom wants to merge 1 commit into
NousResearch:mainfrom
dusterbloom:fix/session-isolation-cross-contamination

Conversation

@dusterbloom

Copy link
Copy Markdown
Contributor

Summary

Fixes #38788 — Context compaction cross-contamination where cron session summaries leak into unrelated live conversations.

Root Cause

ContextCompressor.on_session_end() is inherited as a no-op from ContextEngine. When a cron or background session compresses and rotates, _previous_summary survives session end. The memory manager's on_session_switch path exposes it to the next live session, causing compaction summaries to leak across session boundaries.

The comment at run_agent.py:2773-2777 already acknowledges this class of bug ("engines that accumulate per-session state... leak that state"), but the fix only called on_session_end — it didn't make on_session_end actually clear the state.

Fix

Override on_session_end() in ContextCompressor to clear _previous_summary = None. This is a 3-line change.

Verification

Quint Formal Spec

  • Bug model: specs/session_isolation.qnt — Quint finds the violation in 13ms (3 states)
  • Fix model: specs/session_isolation_fixed.qnt — Quint passes 100K+ traces with zero violations

Unit Tests

  • test_on_session_end_clears_previous_summary: summary is None after session end
  • test_on_session_end_preserves_other_state: global state (token tracking, compression count) is preserved
  • Full compressor test suite: 93 passed, 0 regressions

Spec Design (Socratic Flow)

The formal spec was developed through an interactive Socratic specification process:

  1. Should Session A's summary be visible to Session B? → No (default isolation)
  2. Should compaction summaries be treated like memory? → No (session-scoped)
  3. Where should isolation live? → Correct by construction, not convention
  4. Compromise for this codebase? → Per-agent instances already exist; fix the cleanup gap
  5. Where to store summaries? → As messages with session_id (already done)
  6. Design choice: clear state on session end (structural fix, not query filter)

See specs/session_isolation.qnt and specs/session_isolation_fixed.qnt for the formal models.

…ontamination (NousResearch#38788)

ContextCompressor.on_session_end() is inherited as a no-op from
ContextEngine. When a cron or background session compresses and
rotates, _previous_summary survives session end. The memory manager
exposes it to the next live session via on_session_switch, causing
cron compaction summaries to leak into unrelated conversations.

Fix: override on_session_end() in ContextCompressor to clear
_previous_summary. This is a 3-line change that closes the only
path by which per-session compaction state crosses session
boundaries.

Verified with:
- Quint formal spec: bug found in 13ms across 3 states; fix
  passes 100K+ traces with zero violations
- 2 unit tests: summary cleared + other state preserved
- Full compressor test suite: 93 passed, 0 regressions

Closes NousResearch#38788
@daimon-nous daimon-nous Bot added type/bug Something isn't working P1 High — major feature broken, no workaround comp/agent Core agent loop, run_agent.py, prompt builder labels Jun 5, 2026
@teknium1

teknium1 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Merged via #41717 (commit cca3b77) — your on_session_end() clear approach landed as the defense-in-depth layer, with your authorship preserved via rebase. Rewrote the implementation cleanly (the original diff inserted the method mid-on_session_reset and bundled the Quint spec files, which we don't ship in-repo). It's paired with @basilalshukaili's point-of-use guard in compress() as the primary fix — E2E confirmed the two layers cover genuinely different leak paths. Thanks!

#41717

@teknium1 teknium1 closed this Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P1 High — major feature broken, no workaround type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Context compaction cross-contamination — cron session summaries leak into unrelated live conversations

2 participants