LearnNewsExamplesServices
Frontmatter
id9959
titlefix(memory): periodic summarization must skip externally active sessions
stateClosed
labels
bugairegressionarchitectureperformancemodel-experience
assigneesneo-gpt
createdAtApr 13, 2026, 12:25 PM
updatedAt3:18 PM
githubUrlhttps://github.com/neomjs/neo/issues/9959
authortobiu
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[x] 9961 Pre-Task Retrospective Query — Active Memory Consumption
closedAtJun 6, 2026, 7:01 PM

fix(memory): periodic summarization must skip externally active sessions

Closed v13.0.0/archive-v13-0-0-chunk-4 bugairegressionarchitectureperformancemodel-experience
tobiu
tobiu commented on Apr 13, 2026, 12:25 PM

Current Verified State (2026-06-06)

This issue was originally filed for two Memory Core defects:

  1. StorageRouter.injectQueryReRanker() crashed when ChromaDB query results were empty, malformed, or failed during embedding.
  2. SessionService.findSessionsToSummarize() selected the current in-process session for summarization when the summary was missing.

Those original defects are already resolved by merged PR #9960 (merged 2026-04-13). Current source confirms:

  • ai/services/memory-core/managers/StorageRouter.mjs wraps Pass 1 semantic retrieval in try/catch, logs fallback, and reads searchResult?.ids?.[0].
  • ai/services/memory-core/SessionService.mjs excludes sessionId === this.currentSessionId before both missing-summary and count-mismatch cases.
  • test/playwright/unit/ai/services/memory-core/QueryReRanker.spec.mjs covers the defensive re-ranker path and in-process active-session exclusion.

The remaining live bug is narrower: periodic child-process summarization can still select sessions that are active in another harness or MCP process, because the child process has no request-bound session context for those externally active sessions.

Problem

The orchestrator summary task runs ai/scripts/lifecycle/summarize-sessions.mjs as a spawned child process:

  • ai/daemons/orchestrator/TaskDefinitions.mjs points the summary task at summarize-sessions.mjs.
  • summarize-sessions.mjs initializes Memory_SessionService in the child process and calls summarizeSessions({ includeAll: false }).
  • findSessionsToSummarize() excludes only this.currentSessionId, which resolves to RequestContextService.getSessionId() || this._legacySessionId.

In the spawned child path, this.currentSessionId is the child process's local legacy/request session, not the session IDs currently accumulating memories in other live harnesses. A periodic sweep can therefore see memory-count drift for an active external session and re-summarize it repeatedly before that session has actually ended.

Impact:

  • incomplete mid-flight summaries can be written for still-running sessions;
  • LLM summarization tokens are spent on active sessions rather than completed work;
  • future agents may retrieve stale or partial summaries while the raw memory stream is still growing.

Accepted Scope

Define and implement a cross-process active-session predicate for periodic drift-detection summarization.

This ticket is about automatic periodic sweeps. Explicit/manual summarization of a named sessionId must remain allowed when deliberately requested.

Contract Ledger

Surface Contract
SessionService.findSessionsToSummarize(includeAll = false) Must exclude sessions that are active in another harness/process, not only the child process currentSessionId. The predicate must be source-backed and testable.
SessionService.summarizeSessions({ includeAll, sessionId }) Explicit sessionId summarization remains intentional and may summarize the active session when the caller names it directly. The cross-process skip applies only to drift-detection candidate selection.
ai/scripts/lifecycle/summarize-sessions.mjs Periodic child-process summarization must use the same skip predicate before broad drift summarization. Pending explicit jobs may still drain through their existing explicit-session path.
SummarizationJobs / resume state Do not finalize or mark a still-active session as completed merely because a periodic child processed it. Preserve resume_session semantics and cross-check the pending-aware summarization barrier from #11676.
Observability Logs or returned summaries should make it clear when a drift candidate was skipped because it is externally active.
Tests Add focused coverage for a no-request-context child-process shape where a session is active elsewhere, plus a counter-test proving explicit summarizeSessions({ sessionId }) still works.

Acceptance Criteria

  • Periodic drift detection skips sessions active in another harness/process.
  • The active-session predicate does not depend only on the spawned child's currentSessionId.
  • Explicit/manual summarizeSessions({ sessionId }) semantics are preserved.
  • Pending summarization jobs keep their explicit-session behavior unless the implementation proves a specific active-session finalization conflict and documents that policy.
  • Focused tests cover the spawned child / no request context case.
  • Focused tests cover that explicit named-session summarization remains possible.
  • Logs or returned metadata identify externally-active skips well enough for operator diagnosis.

Out of Scope

  • Re-implementing the original StorageRouter re-ranker crash fix from PR #9960.
  • Re-implementing the in-process currentSessionId exclusion from PR #9960.
  • Replacing the summarization job coordinator or SummarizationJobs schema wholesale.
  • Changing summary visibility / tenant filtering semantics.
  • Running broad full-suite summarization or closing historical sessions manually.

Verification Anchors

  • Merged original fix: PR #9960.
  • Current revalidation comment: https://github.com/neomjs/neo/issues/9959#issuecomment-4636388490
  • Relevant source:
    • ai/services/memory-core/managers/StorageRouter.mjs
    • ai/services/memory-core/SessionService.mjs
    • ai/scripts/lifecycle/summarize-sessions.mjs
    • ai/daemons/orchestrator/TaskDefinitions.mjs
    • test/playwright/unit/ai/services/memory-core/QueryReRanker.spec.mjs

Origin Session IDs:

  • Original issue: 598f1a53-952e-4356-8c6f-ada3e71b6152
  • 2026-05-27 revalidation: 6ca1b510-51c3-4fac-aa39-a0fd6941318c
tobiu assigned to @tobiu on Apr 13, 2026, 12:25 PM
tobiu added the bug label on Apr 13, 2026, 12:25 PM
tobiu added the ai label on Apr 13, 2026, 12:25 PM
tobiu referenced in commit 16faf1b - "fix: Memory Core semantic search crash & active session summarization leak (#9959) on Apr 13, 2026, 12:26 PM
tobiu cross-referenced by PR #9960 on Apr 13, 2026, 12:28 PM
tobiu referenced in commit 3bc5098 - "fix: Memory Core semantic search crash & active session summarization leak (#9959) (#9960) on Apr 13, 2026, 12:31 PM
tobiu marked this issue as blocking #9961 on Apr 13, 2026, 1:13 PM
tobiu unassigned from @tobiu on Jun 6, 2026, 1:26 AM