Context
Slice A (the runner-seam) wired the dimension-consistency producer into DataIntegrityDiagnosisService through an OPTIONAL injected dimensionGatherer (pure + unit-tested, no live Chroma). This is Slice B: the live-Chroma binding that injects a real dimension gatherer so the signal goes LIVE on the hourly data-integrity sweep.
The work
A dataIntegrityDimensionGatherer getter on Orchestrator (sibling of the existing dataIntegrityCoverageGatherer) that:
- connects a live Chroma client via
ai/services/shared/vector/chromaClientPrimitives.mjs (the dummy embedding fn is needed only for schema hydration; a read-only .get does not call the embedder, so it is not gated by the slow embed-canary),
- resolves the live collection handles for
['neo-agent-memory','neo-agent-sessions'],
- calls
auditCollectionVectorDimensions per collection with the vectorDimension SSOT leaf (ai/config.template.mjs:340, default 4096) read at the use-site,
- returns
samples: [{collection, expectedDimension, mismatchedVectorCount}],
- and is injected into the runner construction alongside the already-injected
coverageGatherer.
The getter MUST return [] on a connection failure (never throw): the runner treats an absent/failing dimension gatherer as "skip dimension this cycle" without suppressing the proven coverage signal (Slice A's gatherDimensionSamples already degrades this way; the getter must not defeat it by throwing).
Acceptance Criteria
Related
Slice A runner-seam (the immediately-preceding ticket), the dimension producer / the gatherer it consumes, #14117 (the live loop), #14039 (v13.1 epic), #14081 (binary-split rebatch — a realistic wrong-dimension source).
Authored by Vega (Claude Opus 4.8, Claude Code).
Context
Slice A (the runner-seam) wired the dimension-consistency producer into
DataIntegrityDiagnosisServicethrough an OPTIONAL injecteddimensionGatherer(pure + unit-tested, no live Chroma). This is Slice B: the live-Chroma binding that injects a real dimension gatherer so the signal goes LIVE on the hourly data-integrity sweep.The work
A
dataIntegrityDimensionGatherergetter onOrchestrator(sibling of the existingdataIntegrityCoverageGatherer) that:ai/services/shared/vector/chromaClientPrimitives.mjs(the dummy embedding fn is needed only for schema hydration; a read-only.getdoes not call the embedder, so it is not gated by the slow embed-canary),['neo-agent-memory','neo-agent-sessions'],auditCollectionVectorDimensionsper collection with thevectorDimensionSSOT leaf (ai/config.template.mjs:340, default 4096) read at the use-site,samples: [{collection, expectedDimension, mismatchedVectorCount}],coverageGatherer.The getter MUST return
[]on a connection failure (never throw): the runner treats an absent/failing dimension gatherer as "skip dimension this cycle" without suppressing the proven coverage signal (Slice A'sgatherDimensionSamplesalready degrades this way; the getter must not defeat it by throwing).Acceptance Criteria
DataIntegrityDiagnosisService.Related
Slice A runner-seam (the immediately-preceding ticket), the dimension producer / the gatherer it consumes, #14117 (the live loop), #14039 (v13.1 epic), #14081 (binary-split rebatch — a realistic wrong-dimension source).
Authored by Vega (Claude Opus 4.8, Claude Code).