LearnNewsExamplesServices
Frontmatter
id13074
titleRelocate MC healthcheck migration-census to an on-demand surface (compute slice of #12768)
stateClosed
labels
enhancementai
assigneesneo-opus-grace
createdAtJun 13, 2026, 9:29 AM
updatedAtJun 21, 2026, 2:17 AM
githubUrlhttps://github.com/neomjs/neo/issues/13074
authorneo-opus-grace
commentsCount0
parentIssue12768
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 13, 2026, 4:20 PM

Relocate MC healthcheck migration-census to an on-demand surface (compute slice of #12768)

neo-opus-grace
neo-opus-grace commented on Jun 13, 2026, 9:29 AM

Context

The compute slice of #12768 ("Trim the Memory Core healthcheck to a lean liveness probe"), companion to the context-tax slice #13069 (PR #13071). Where #13069 removed two static/redundant fields, this removes the healthcheck's per-call batch-scan.

The Problem

The healthcheck payload runs the migration census on every call: #checkChromaMigrationState#scanChromaMetadata batch-reads the full memory + summary Chroma collections (batchSize 2000, ~17.9k records), an O(records) cost on a probe that fires at boot, self-repair, and monitoring intervals. The census is operator-scraped — no programmatic consumer reads healthcheck.migration — so it does not belong on the hot path.

The Fix

Mirror the established on-demand pattern (graphLifecycleReport.mjs + GraphService.getLifecycleCensus):

  • Add HealthService.getMigrationCensus({includeChroma}) — cheap SQLite untagged-userId counts always; the O(records) ChromaDB scan only when includeChroma is set.
  • Add ai/scripts/maintenance/migrationCensusReport.mjs (+ npm run ai:migration-census-report) — a thin operator entrypoint; --chroma opts into the scan, --json emits raw.
  • Remove the migration field + the Step-1.5 payload.migration.chromadb mutation from #performHealthCheck. The private census methods + buildChromaMigrationStats remain (now reached via getMigrationCensus).

Contract Ledger

Field Value
Target Surface ai/services/memory-core/HealthService.mjs (getMigrationCensus), ai/scripts/maintenance/migrationCensusReport.mjs (NEW), package.json
Source of Authority #12768 (parent trim ticket — AC: "migration census moved to an on-demand surface; healthcheck no longer batch-scans collections per call")
Proposed Behavior Healthcheck no longer runs the census/batch-scan; operators get it on demand via the script/method; cheap SQLite default, Chroma scan opt-in
Fallback Graph not mounted / Chroma unreachable → available: false (substrate-readiness, not error), surfaced by the report
Evidence New migrationCensusReport.spec.mjs green; HealthService.spec.mjs green (no payload.migration assertions existed)

Acceptance Criteria

  • getMigrationCensus({includeChroma}) on HealthService — cheap SQLite always, Chroma scan opt-in.
  • migrationCensusReport.mjs + ai:migration-census-report npm script, mirroring graphLifecycleReport.
  • migration field + Step-1.5 batch-scan removed from the healthcheck; the private methods + buildChromaMigrationStats retained.
  • Unit specs: new script spec (parseArgs / formatCensus / runReport) + HealthService.spec.mjs green.

Out of Scope (remains in #12768)

  • features.wake.gateReason trim — a different block (buildWakeFeaturesBlock), debatable (a tripped-gate reason is arguably wanted in-band), with a test asserting current behavior. Left for a separate decision in #12768.

Related

Refs #12768 (parent trim umbrella; delivers its migration-census AC). Mirrors graphLifecycleReport / GraphService.getLifecycleCensus.

Release classification: post-release (token/compute-cost observability hygiene; nothing v13.x-blocking).

Authored by Claude Opus 4.8 (Claude Code, @neo-opus-grace / Grace).

tobiu closed this issue on Jun 13, 2026, 4:20 PM
tobiu referenced in commit 3a12797 - "refactor(memory-core): relocate healthcheck migration-census to an on-demand surface (#13074) (#13075) on Jun 13, 2026, 4:20 PM