Problem
The orchestrator's periodic session-summary sweep re-summarizes the same ~9 sessions every run, indefinitely — continuous local-LLM (gemma) inference with zero progress (pending-session-summary:283 never moves). Operator-reported (2026-06-20): machine fans pinned, ~25-min back-to-back runs over an identical session set (1cf2ad9f, d13c94dd, 7a73e53f, f76d5307, 596639bf, c43c9892, af356ab3, f191cbb2, default-session).
Root cause
SessionService.findSessionsToSummarize (drift detection) flags a session for (re)summarization when its memory count ≠ the summary's recorded memoryCount (SessionService.mjs:451), assuming "once updated, the counts match, and it won't run again."
- The drift computes the session count by paginating Chroma (
:348-367) — the full count.
- But
summarizeSession writes that memoryCount from a single, un-paginated .get (:474 → :677).
Chroma caps each .get at summarizationBatchLimit (ChromaManager.mjs:333) — precisely why the drift paginates. So for sessions past that cap, summarizeSession undercounts → count !== memoryCount is permanently true → the session re-summarizes every sweep.
Bonus defect: the same un-paginated fetch means large sessions are summarized from only the first page — truncated summaries.
Evidence
get_rem_pipeline_state: 1,354 summaries ARE in Chroma (983 digested + 371 undigested) → the drift finds the summaries; it's a count mismatch, not a missing summary (rules out a persistence/Case-A theory).
#9959 (the prior "re-summarized over and over" ticket) is closed — it fixed the externally-active-session exclusion, a different cause.
Fix
- Paginate
summarizeSession's memory fetch (mirror the drift's pagination) → memoryCount = the true full count (reconciles with the drift) and summaries stop truncating.
- Reproducing unit test: a session whose summary
memoryCount < its real count must re-flag on current code and must NOT after the fix. (If the residual is a count-criteria mismatch rather than the cap, escalate to a timestamp-watermark drift signal — the summary already records timestamp: lastActivity at :677.)
Acceptance Criteria
Decision Record impact
none.
Related
- Surfaced by @tobiu (2026-06-20 orchestrator logs: same-session re-loop, fans pinned).
#9959 (closed, different cause: active-session exclusion).
Problem
The orchestrator's periodic session-summary sweep re-summarizes the same ~9 sessions every run, indefinitely — continuous local-LLM (gemma) inference with zero progress (
pending-session-summary:283never moves). Operator-reported (2026-06-20): machine fans pinned, ~25-min back-to-back runs over an identical session set (1cf2ad9f,d13c94dd,7a73e53f,f76d5307,596639bf,c43c9892,af356ab3,f191cbb2,default-session).Root cause
SessionService.findSessionsToSummarize(drift detection) flags a session for (re)summarization when its memory count ≠ the summary's recordedmemoryCount(SessionService.mjs:451), assuming "once updated, the counts match, and it won't run again.":348-367) — the full count.summarizeSessionwrites thatmemoryCountfrom a single, un-paginated.get(:474→:677).Chroma caps each
.getatsummarizationBatchLimit(ChromaManager.mjs:333) — precisely why the drift paginates. So for sessions past that cap,summarizeSessionundercounts →count !== memoryCountis permanently true → the session re-summarizes every sweep.Bonus defect: the same un-paginated fetch means large sessions are summarized from only the first page — truncated summaries.
Evidence
get_rem_pipeline_state: 1,354 summaries ARE in Chroma (983 digested + 371 undigested) → the drift finds the summaries; it's a count mismatch, not a missing summary (rules out a persistence/Case-A theory).#9959(the prior "re-summarized over and over" ticket) is closed — it fixed the externally-active-session exclusion, a different cause.Fix
summarizeSession's memory fetch (mirror the drift's pagination) →memoryCount= the true full count (reconciles with the drift) and summaries stop truncating.memoryCount< its real count must re-flag on current code and must NOT after the fix. (If the residual is a count-criteria mismatch rather than the cap, escalate to a timestamp-watermark drift signal — the summary already recordstimestamp: lastActivityat:677.)Acceptance Criteria
summarizeSessionfetches all of a session's memories (paginated);memoryCountequals the drift's full count.UNIT_TEST_MODE(never barenpx playwright test— it resolvesstoragePaths.graphto the live graph).Decision Record impact
none.Related
#9959(closed, different cause: active-session exclusion).