LearnNewsExamplesServices
Frontmatter
id13503
titleAdd Chroma vector-index coverage audit
stateClosed
labels
bugaiarchitecturemodel-experience
assigneesneo-gpt
createdAtJun 19, 2026, 4:45 AM
updatedAtJun 19, 2026, 5:29 PM
githubUrlhttps://github.com/neomjs/neo/issues/13503
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 19, 2026, 5:29 PM

Add Chroma vector-index coverage audit

Closed v13.1.0/archive-v13-1-0-chunk-4 bugaiarchitecturemodel-experience
neo-gpt
neo-gpt commented on Jun 19, 2026, 4:45 AM

Context

The #13496 diagnostic ledger proved that query health and stored-vector exportability can diverge. PR #13502 / #13501 adds a bounded API sampling probe, which catches the severe Memory Core failure mode but can miss partial drift.

Live latest-open sweep: checked the latest 20 open issues on 2026-06-19; no equivalent vector-index coverage audit ticket was present. Existing related tickets were the broader #13496 and the API-sampling leaf #13501.

A2A in-flight claim sweep: checked the latest 30 incoming messages on 2026-06-19; no competing claim for a metadata-vs-vector-index coverage audit was present.

Local exact sweep: rg "vector-index coverage|vector index coverage|metadata.*vector.*index|index_metadata.pickle|stored-vector drift|stored vector drift|HNSW.*metadata" resources/content/issues resources/content/discussions found older query-path context in #12450, but no equivalent diagnostic leaf.

Release classification: boardless (post-release hardening / repair diagnostic; not a release blocker).

The Problem

checkChromaIntegrity.mjs can now sample stored-embedding exportability through the Chroma API, but sampling does not prove full collection coverage. The live local store demonstrates why:

neo-knowledge-base
  metadata rows:       30466
  vector index ids:    30000
  missing from vector:   466

With a small sample, KB looked healthy even though hundreds of metadata rows are absent from the vector index. Memory Core collections are worse:

neo-agent-memory:   18848 metadata rows vs 4931 vector ids
neo-agent-sessions:  1073 metadata rows vs 103 vector ids
neo-native-graph:     716 metadata rows vs 357 vector ids

This means the current API sampling leaf is necessary but not sufficient for repair planning. Operators need an exact local coverage audit before choosing repair, rebuild, or restore.

The Architectural Reality

ai/scripts/maintenance/checkChromaIntegrity.mjs is already the copy-first, read-only local Chroma integrity diagnostic. It copies chroma.sqlite3 before running SQLite pragmas and keeps the expensive checks out of hot healthcheck paths.

ADR 0017 defines the unified Chroma store as one flat local/cloud topology, with separation at collection, metadata, export, and backup layers. A local metadata-vs-vector-index coverage audit belongs in the maintenance diagnostic because it validates the collection/export layer without changing daemon topology or mutating the store.

Implementation sequencing: this leaf should wait until #13502 lands or deliberately branch on top of it, because #13502 introduces the adjacent stored-embedding exportability reporting surface.

The Fix

Extend the Chroma integrity diagnostic with an exact local coverage audit:

  • Read collection metadata row ids from the copied SQLite snapshot.
  • Read the corresponding HNSW index_metadata.pickle for each vector segment in the unified persist directory.
  • Report, per collection id, metadata row count, vector index id count, overlap, missing-from-vector count, extra-in-vector count, and bounded sample ids.
  • Surface duplicate same-name collection rows, especially when one row has missing vector metadata.
  • Keep the audit read-only and operator-invoked only; do not add this to KB/MC healthchecks.
  • Make the result available in JSON and concise human output.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
checkChromaIntegrity.mjs JSON result Existing maintenance diagnostic Add exact metadata/vector-index coverage rows per canonical collection id If a vector index metadata file is absent or unreadable, report that as a failed coverage row without throwing away SQLite findings Script usage block and PR body Focused unit coverage with temp SQLite/pickle fixtures
Human CLI output Existing printHuman() diagnostic surface Summarize metadata rows, vector ids, missing/extra counts, and duplicate collection rows Keep output bounded with sample ids rather than dumping full missing-id sets Script output Unit coverage plus local smoke
Repair planning under #13496 #13496 diagnostic ledger Provide exact drift counts before any mutation path is selected If local filesystem access is unavailable, fall back to #13501 API sampling and state reduced evidence class Ticket/PR body Local read-only diagnostic run

Decision Record impact

aligned-with ADR 0017 (learn/agentos/decisions/0017-chroma-single-flat-unified-store.md): audits collection-scoped vector coverage inside the unified store without adding a daemon, path split, or hot healthcheck dependency.

Acceptance Criteria

  • The diagnostic reports exact metadata-vs-vector-index coverage for canonical Chroma collections.
  • Duplicate same-name collection rows are visible in the output.
  • Missing vector index metadata files are reported as coverage failures, not swallowed.
  • JSON output includes counts and bounded sample ids for missingFromVector and extraInVector.
  • Human output remains concise enough for operator use.
  • Unit coverage uses isolated temp fixtures; no live Chroma mutation is required.
  • Existing SQLite quick_check / integrity_check and API sampling probes continue to work.

Out of Scope

  • Repairing or rebuilding any collection.
  • Re-embedding Memory Core rows.
  • Changing Chroma daemon launch topology.
  • Adding the coverage audit to hot healthchecks.
  • Closing the broader #13496 repair ticket.

Related

Related: #13496 Related: #13501 Related: #13502 Related: #13467

Handoff Retrieval Hint: query_raw_memories("Chroma metadata vector index coverage index_metadata.pickle stored-vector drift #13496")