LearnNewsExamplesServices
Frontmatter
id13667
titleExclude archived/orphaned sessions from the session-summary-pending count
stateClosed
labels
enhancementaimodel-experience
assigneesneo-opus-vega
createdAtJun 20, 2026, 11:04 PM
updatedAtJun 20, 2026, 11:19 PM
githubUrlhttps://github.com/neomjs/neo/issues/13667
authorneo-opus-vega
commentsCount0
parentIssue13647
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 20, 2026, 11:19 PM

Exclude archived/orphaned sessions from the session-summary-pending count

Closed v13.1.0/archive-v13-1-0-chunk-4 enhancementaimodel-experience
neo-opus-vega
neo-opus-vega commented on Jun 20, 2026, 11:04 PM

Context

Carved from #13647 (parent; epic #13624) so the delivering PR has an honest standalone close-target. The session-summary-pending marker getPendingSessionSummaryCount (ai/daemons/orchestrator/scheduling/summary.mjs) over-counts orphaned sessions. Confirmed by a cross-store V-B-A (#13647 issuecomment-4759938336) and a live orchestrator run after #13656 merged: the miniSummary aged-drain processed 1344 rows → 1335 missing-content (orphaned — graph AGENT_MEMORY nodes whose Chroma content is gone: GC'd or partial-write-crash).

Live latest-open sweep: checked the latest 20 open issues at ~2026-06-20T21:05Z — no equivalent found.

The Problem

Of 285 graph-pending sessions: 238 orphaned (no recoverable Chroma content → unsummarizable), 45 Chroma-summarized-but-graph-unprojected, 2 genuinely pending. The drift sweep finds only ~40 candidates/run and processing them never moves the marker — the orphans are structurally non-drainable. Counting them produces the misleading "backlog doesn't drain (283→284)" telemetry, but orphaned content can never be summarized — it is an integrity concern, not summary-pending work.

The Architectural Reality

getPendingSessionSummaryCount is a graph-only SQL anti-join over Nodes (AGENT_MEMORY minus SESSION_SUMMARY ∪ SESSION-with-chromaId LIKE 'summary_%'). It is telemetry-only — it feeds the periodic-sweep trigger reason and does NOT gate the sweep — and runs inside getDueTask, a pure-sync projection (registry contract: no I/O, no async), so it cannot query Chroma. The graph carries archivedAt/archivedReason on AGENT_MEMORY nodes; the miniSummary backfill (#13656) already archives no-content rows.

The Fix

Add archivedAt IS NULL to the marker's memory_sessions CTE: a session counts while it has any un-archived memory node; a fully-archived (orphaned) session drops out. Mirrors the archived-skip #13656 added to the backfill fetch. Couples with the orphan archival (grace's axis-3 #13639 + #13656): as orphans are archived, the marker excludes them → it reflects drainable truth instead of inflating on records the drain can never drain.

Decision Record impact

aligned-with ADR-0019 — graph-only, reuses the existing archivedAt convention; introduces no new config leaf.

Acceptance Criteria

  • getPendingSessionSummaryCount excludes sessions whose memory nodes are all archived; a session with any un-archived node still counts.
  • Unit test (archived excluded; live + mixed-node sessions counted) in SessionSummaryBacklogCount.spec.mjs.

Out of Scope

  • The 45 projection-lag (Chroma-summarized-but-graph-unprojected) — separate projection-health concern, stays on #13647.
  • The orphan archival itself (grace's axis-3 #13639 / #13656).
  • WHY 1335 are missing-content (expected GC vs data-loss bug) — axis-3 integrity question, routed to grace.
  • #13647's gate-hardening ACs (future-skewed / unparseable timestamp edges on findSessionsToSummarize).

Related

Parent: #13647. Epic: #13624. Couples: #13639 (axis-3 archival), #13656 (miniSummary archival, mirrored pattern).

Origin Session ID: c4fcedd0-c449-4f8c-b368-e3ac0c0509ff Retrieval Hint: "getPendingSessionSummaryCount archivedAt orphaned session-summary marker measurement-truth #13647"