Resolves #13462
Reworks the session-summary maintenance path so the periodic sweep no longer combines an expensive correlated graph count with completed coordinator rows that suppress repair. The scheduler count now materializes distinct memory and summary-evidence session sets once: direct SESSION_SUMMARY artifacts and summary-backed REM SESSION projections (properties.chromaId LIKE 'summary_%') both count as graph-visible summary evidence, while minimal SESSION placeholders remain countable as unsummarized. The drift sweep can explicitly reclaim completed SummarizationJobs rows only when drift detection already selected the session as missing or outdated, and the summary child emits normal lifecycle progress on the stderr stream captured by the orchestrator log.
Evidence: L2 (focused unit coverage plus read-only local graph probes) -> L3 required (post-merge live daemon run showing the local pending-session-summary lease makes progress). Residual: post-merge validation below.
Related: #12065
Deltas from ticket
The ticket mentioned possible watchdog/config follow-up. This PR deliberately leaves that out: the low-risk fix is to remove the no-progress coordinator/projection drift and expose child-run diagnostics first. Provider or Chroma stall root cause work remains a separate lane if live validation still shows long-running synthesis after this lands.
During review/exploration we verified that SESSION_SUMMARY and SESSION are not competing spellings of the same label. SESSION_SUMMARY is the direct summary artifact written by SessionService.summarizeSession(). SESSION is the REM/provenance projection written by MemorySessionIngestor from Chroma summary rows, with a separate minimal-placeholder mode for never-summarized sessions. This PR keeps both labels and constrains the telemetry predicate to summary-backed SESSION rows only.
Test Evidence
npm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/scheduling/SessionSummaryBacklogCount.spec.mjs test/playwright/unit/ai/services/memory-core/SessionService.ResumeValidation.spec.mjs test/playwright/unit/ai/daemons/orchestrator/scheduling/summary.spec.mjs -> 31 passed.
git diff --check -> clean.
- Pre-push freshness check:
merge-base HEAD origin/dev == origin/dev; outgoing log contained only 74438b151 fix(ai): repair session summary drift (#13462).
Post-Merge Validation
Commits
74438b151 - repair session-summary drift and focused tests.
Authored by Euclid (GPT-5, Codex Desktop). Session 019ed42c-f8fc-7e01-a1a1-a8b5bbf58b64.
Resolves #13462
Reworks the session-summary maintenance path so the periodic sweep no longer combines an expensive correlated graph count with completed coordinator rows that suppress repair. The scheduler count now materializes distinct memory and summary-evidence session sets once: direct
SESSION_SUMMARYartifacts and summary-backed REMSESSIONprojections (properties.chromaId LIKE 'summary_%') both count as graph-visible summary evidence, while minimalSESSIONplaceholders remain countable as unsummarized. The drift sweep can explicitly reclaim completedSummarizationJobsrows only when drift detection already selected the session as missing or outdated, and the summary child emits normal lifecycle progress on the stderr stream captured by the orchestrator log.Evidence: L2 (focused unit coverage plus read-only local graph probes) -> L3 required (post-merge live daemon run showing the local
pending-session-summarylease makes progress). Residual: post-merge validation below.Related: #12065
Deltas from ticket
The ticket mentioned possible watchdog/config follow-up. This PR deliberately leaves that out: the low-risk fix is to remove the no-progress coordinator/projection drift and expose child-run diagnostics first. Provider or Chroma stall root cause work remains a separate lane if live validation still shows long-running synthesis after this lands.
During review/exploration we verified that
SESSION_SUMMARYandSESSIONare not competing spellings of the same label.SESSION_SUMMARYis the direct summary artifact written bySessionService.summarizeSession().SESSIONis the REM/provenance projection written byMemorySessionIngestorfrom Chroma summary rows, with a separate minimal-placeholder mode for never-summarized sessions. This PR keeps both labels and constrains the telemetry predicate to summary-backedSESSIONrows only.Test Evidence
npm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/scheduling/SessionSummaryBacklogCount.spec.mjs test/playwright/unit/ai/services/memory-core/SessionService.ResumeValidation.spec.mjs test/playwright/unit/ai/daemons/orchestrator/scheduling/summary.spec.mjs-> 31 passed.git diff --check-> clean.merge-base HEAD origin/dev == origin/dev; outgoing log contained only74438b151 fix(ai): repair session summary drift (#13462).Post-Merge Validation
orchestrator.logincludes pending drain, drift start, processed/skipped counts, and no repeated no-progresspending-session-summarylease caused by completed coordinator rows./opt/homebrew/bin/npm run ai:sync-github-workflowafter the summary lane clears and verify any deferral is transient rather than repeatedly blocked by the same completed-job drift.Commits
74438b151- repair session-summary drift and focused tests.Authored by Euclid (GPT-5, Codex Desktop). Session 019ed42c-f8fc-7e01-a1a1-a8b5bbf58b64.