A maintainer reviewing Discussion #9739 independently noticed that SessionService.findSessionsToSummarize() paginates safely but retains every fetched memory and summary metadata object until each full scan completes. A 2026-07-13 code-level V-B-A confirmed the observation in current dev.
This is a bounded Memory Core performance hardening ticket. It does not change which sessions qualify for summarization or how summaries are generated.
Live duplicate sweep: latest 20 open issues plus recent all-state A2A claims checked at 2026-07-13T10:46Z. Targeted GitHub, Knowledge Base, Memory Core, and archived-ticket searches found no equivalent issue. Historical #7864 added configurable pagination and the safety break; it did not address full-scan retention.
The Problem
findSessionsToSummarize() scans the all-time memory collection and existing session summaries in pages. The method currently:
concatenates every memory metadata row into allMetadatas;
groups that complete array into per-session count/last-activity state;
concatenates every summary metadata row into allSummaryMetadatas;
groups that complete array into the summary-count map.
The safety ceiling permits up to 1000 pages — documented in code as as many as 2 million records — so peak retained JS metadata grows with total collection size even though the decision only needs:
per-session memory count;
per-session newest activity timestamp;
per-session last summarized memoryCount.
No production OOM is asserted here; the verified defect is the unnecessary O(total records) retention shape on an all-time maintenance scan.
The Architectural Reality
ai/services/memory-core/SessionService.mjs#findSessionsToSummarize owns the candidate calculation.
Chroma pagination remains the correct collection-read boundary.
Existing churn gates, current-session exclusion, externally-active session handling, timestamp normalization, and count-mismatch semantics are already encoded after the scan and must remain byte-for-byte equivalent at the returned session-id boundary.
summarizeSessions() already caps the drain per sweep through maxSessionsPerSummarySweep; that bounds work after discovery but does not bound discovery retention.
The Agent OS structure map was executed on 2026-07-13. This is an in-place method/spec change; no new service or directory is needed.
The Fix
Aggregate each page into the final bounded maps as it arrives:
Memory pages update Map<sessionId, {count, lastActivity}> directly, then release the page.
Summary pages update Map<sessionId, memoryCount> directly, then release the page.
Preserve the configured page size, offset progression, short-page termination, empty-page termination, safety break, and existing timestamp resolver.
Keep candidate filtering and return semantics unchanged.
Add a many-page fixture that proves retention is proportional to distinct sessions plus one page, not total memory rows.
Contract Ledger Matrix
Target Surface
Source of Authority
Proposed Behavior
Fallback / Edge Case
Docs
Evidence
findSessionsToSummarize() return value
Existing method contract and focused specs
Same candidate ids for the same memory/summary pages
Collection error preserves current caller-visible failure behavior
Method JSDoc
Before/after parity fixture
Memory scan aggregation
Memory metadata sessionId, timestamp, name
Incremental count + latest timestamp per session
Rows without sessionId remain ignored
Method JSDoc
Many-page bounded-retention spec
Summary scan aggregation
Summary metadata sessionId, memoryCount
Incremental latest map equivalent to current scan order
Context
A maintainer reviewing Discussion
#9739independently noticed thatSessionService.findSessionsToSummarize()paginates safely but retains every fetched memory and summary metadata object until each full scan completes. A 2026-07-13 code-level V-B-A confirmed the observation in current dev.This is a bounded Memory Core performance hardening ticket. It does not change which sessions qualify for summarization or how summaries are generated.
Live duplicate sweep: latest 20 open issues plus recent all-state A2A claims checked at 2026-07-13T10:46Z. Targeted GitHub, Knowledge Base, Memory Core, and archived-ticket searches found no equivalent issue. Historical
#7864added configurable pagination and the safety break; it did not address full-scan retention.The Problem
findSessionsToSummarize()scans the all-time memory collection and existing session summaries in pages. The method currently:allMetadatas;allSummaryMetadatas;The safety ceiling permits up to 1000 pages — documented in code as as many as 2 million records — so peak retained JS metadata grows with total collection size even though the decision only needs:
memoryCount.No production OOM is asserted here; the verified defect is the unnecessary O(total records) retention shape on an all-time maintenance scan.
The Architectural Reality
ai/services/memory-core/SessionService.mjs#findSessionsToSummarizeowns the candidate calculation.summarizeSessions()already caps the drain per sweep throughmaxSessionsPerSummarySweep; that bounds work after discovery but does not bound discovery retention.The Agent OS structure map was executed on 2026-07-13. This is an in-place method/spec change; no new service or directory is needed.
The Fix
Aggregate each page into the final bounded maps as it arrives:
Map<sessionId, {count, lastActivity}>directly, then release the page.Map<sessionId, memoryCount>directly, then release the page.Contract Ledger Matrix
findSessionsToSummarize()return valuesessionId,timestamp,namesessionIdremain ignoredsessionId,memoryCountsessionIdremain ignoredDecision Record impact
None. This is an allocation-shape optimization inside the accepted Memory Core session-summary contract.
Decision Record
Not needed. Discussion
#9739is the observation source, not an architectural graduation authority for this repair.Acceptance Criteria
allMetadatasorallSummaryMetadatasfull-scan arrays.Out of Scope
#12823.#13592.Avoided Traps
maxSessionsPerSummarySweeplimits processing, not the full pre-scan.Related
All-time scan restoration:
#12823Bounded summary drain:
#13592Temporal-pyramid consumer: #12679
Observation source: Discussion
#9739Origin Session ID: 837ad74b-c2d2-413d-9aab-b7165a93a82a
Retrieval Hint:
SessionService findSessionsToSummarize allMetadatas pagination 2M retentionRetrieval Hint:
Discussion 9739 nested Memory Core scalability observation