Resolves #15126
SessionService.findSessionsToSummarize() now folds each Chroma page directly into bounded per-session maps instead of retaining every memory and summary metadata row until the all-time scans finish. Pagination, timestamp normalization, eligibility gates, candidate ordering, and last-summary-row semantics remain in place.
Evidence: L2 — a deterministic page-expiry fixture consumes 8,005 memory rows across 5 pages and 2,001 summary rows across 2 pages while retaining only 5 distinct session aggregates plus the active page; current-session, externally-active, reconciled, mismatch, missing-summary, newest-first, churn, future-skew, and unparseable-timestamp behavior is covered. L2 required — this is an internal service allocation-shape change with no user-facing runtime surface. No residuals.
Deltas from ticket
None substantive. The regression fixture additionally pins the existing current-session and externally-active exclusions so parity does not depend on the older live A2A fixture.
Test Evidence
npm run agent-preflight -- --no-fix ai/services/memory-core/SessionService.mjs test/playwright/unit/ai/services/memory-core/SessionService.SummarizePagination.spec.mjs — passed.
node --check on both changed modules — passed.
npm run test-unit -- test/playwright/unit/ai/services/memory-core/SessionService.SummarizePagination.spec.mjs test/playwright/unit/ai/services/memory-core/SessionService.ChurnCooldown.spec.mjs --workers=1 — 8/8 passed against an ephemeral Chroma instance.
- Full
npm run test-unit — 7,077 passed, 5 skipped, 27 failed; all 3 tests in the touched pagination spec passed. The remaining failures span live-fixture/environment surfaces. Baseline was not established, so they are disclosed rather than labeled pre-existing.
- Isolated legacy
QueryReRanker.spec.mjs --grep findSessionsToSummarize — 3/5 passed. One failing external-activity assertion stops before the touched method; the stale-session fixture no longer returns the caller-supplied session id from its tool write. The new hermetic fixture pins both eligibility boundaries directly.
- Surface:
SessionService.findSessionsToSummarize() — memory and summary discovery now aggregate page-locally; returned candidate semantics stay covered by deterministic unit tests.
- Non-CI coverage: None found — this internal Memory Core service path has focused unit coverage and no whitebox E2E surface.
Post-Merge Validation
Authored by Emmy (GPT-5.6 Sol, Codex Desktop). Session f95e01ff-ba36-409a-98af-573263fab247.
Resolves #15126
SessionService.findSessionsToSummarize()now folds each Chroma page directly into bounded per-session maps instead of retaining every memory and summary metadata row until the all-time scans finish. Pagination, timestamp normalization, eligibility gates, candidate ordering, and last-summary-row semantics remain in place.Evidence: L2 — a deterministic page-expiry fixture consumes 8,005 memory rows across 5 pages and 2,001 summary rows across 2 pages while retaining only 5 distinct session aggregates plus the active page; current-session, externally-active, reconciled, mismatch, missing-summary, newest-first, churn, future-skew, and unparseable-timestamp behavior is covered. L2 required — this is an internal service allocation-shape change with no user-facing runtime surface. No residuals.
Deltas from ticket
None substantive. The regression fixture additionally pins the existing current-session and externally-active exclusions so parity does not depend on the older live A2A fixture.
Test Evidence
npm run agent-preflight -- --no-fix ai/services/memory-core/SessionService.mjs test/playwright/unit/ai/services/memory-core/SessionService.SummarizePagination.spec.mjs— passed.node --checkon both changed modules — passed.npm run test-unit -- test/playwright/unit/ai/services/memory-core/SessionService.SummarizePagination.spec.mjs test/playwright/unit/ai/services/memory-core/SessionService.ChurnCooldown.spec.mjs --workers=1— 8/8 passed against an ephemeral Chroma instance.npm run test-unit— 7,077 passed, 5 skipped, 27 failed; all 3 tests in the touched pagination spec passed. The remaining failures span live-fixture/environment surfaces. Baseline was not established, so they are disclosed rather than labeled pre-existing.QueryReRanker.spec.mjs --grep findSessionsToSummarize— 3/5 passed. One failing external-activity assertion stops before the touched method; the stale-session fixture no longer returns the caller-supplied session id from its tool write. The new hermetic fixture pins both eligibility boundaries directly.SessionService.findSessionsToSummarize()— memory and summary discovery now aggregate page-locally; returned candidate semantics stay covered by deterministic unit tests.Post-Merge Validation
dev.Authored by Emmy (GPT-5.6 Sol, Codex Desktop). Session f95e01ff-ba36-409a-98af-573263fab247.