Context
#14117 made the data-integrity immune loop LIVE (detect → diagnose → escalate) but coverage-signal-only. The dimension-consistency producer (buildDimensionConsistencyDiagnosis, #14102) and its fact-gatherer (auditCollectionVectorDimensions, #14115) both exist and are unit-proven, but are not yet wired into the running DataIntegrityDiagnosisService. This ticket is Slice A — the pure runner-seam; the live-Chroma fact-gathering binding is split to #14130 (Slice B).
Scope (Slice A — runner-seam, pure)
DataIntegrityDiagnosisService gains an OPTIONAL injected dimensionGatherer (set-once class field, like coverageGatherer); gatherAndDiagnose gathers dimension samples; buildDiagnoses runs the dimension producer alongside coverage. Absent gatherer → dimension skipped (backward-compatible). Unit-testable with a mock gatherer — no live Chroma.
Secondary-signal degradation: an absent gatherer (Slice B / #14130 not wired) OR a throwing gatherer yields empty samples → dimension skipped for the cycle, and the PRIMARY coverage probe still runs. A dimension-probe issue never escalates to probe-unavailable.
Design notes (carried into #14130, Slice B)
- Offline/live asymmetry: coverage reads the sqlite snapshot offline;
auditCollectionVectorDimensions needs a live Chroma collection handle (collection.get({include:['embeddings']})). A read-only .get does not call the embedder, so it is not gated by the slow embed-canary.
expectedDimension SSOT leaf: vectorDimension (ai/config.template.mjs:340, default 4096).
- Producer contract:
samples: [{collection, expectedDimension, mismatchedVectorCount}] → a diagnosis when any mismatchedVectorCount > 0, else null (never a false escalation).
Acceptance Criteria (Slice A)
Related
#14130 (Slice B — the Orchestrator live-Chroma binding), #14109 (the runner-integration pattern, merged via #14117), #14102 (the producer), #14115 (the gatherer), #14039 (v13.1 epic).
Authored by Vega (Claude Opus 4.8, Claude Code).
Context
#14117 made the data-integrity immune loop LIVE (detect → diagnose → escalate) but coverage-signal-only. The dimension-consistency producer (
buildDimensionConsistencyDiagnosis, #14102) and its fact-gatherer (auditCollectionVectorDimensions, #14115) both exist and are unit-proven, but are not yet wired into the runningDataIntegrityDiagnosisService. This ticket is Slice A — the pure runner-seam; the live-Chroma fact-gathering binding is split to #14130 (Slice B).Scope (Slice A — runner-seam, pure)
DataIntegrityDiagnosisServicegains an OPTIONAL injecteddimensionGatherer(set-once class field, likecoverageGatherer);gatherAndDiagnosegathers dimension samples;buildDiagnosesruns the dimension producer alongside coverage. Absent gatherer → dimension skipped (backward-compatible). Unit-testable with a mock gatherer — no live Chroma.Secondary-signal degradation: an absent gatherer (Slice B / #14130 not wired) OR a throwing gatherer yields empty samples → dimension skipped for the cycle, and the PRIMARY coverage probe still runs. A dimension-probe issue never escalates to
probe-unavailable.Design notes (carried into #14130, Slice B)
auditCollectionVectorDimensionsneeds a live Chroma collection handle (collection.get({include:['embeddings']})). A read-only.getdoes not call the embedder, so it is not gated by the slow embed-canary.expectedDimensionSSOT leaf:vectorDimension(ai/config.template.mjs:340, default 4096).samples: [{collection, expectedDimension, mismatchedVectorCount}]→ a diagnosis when anymismatchedVectorCount > 0, elsenull(never a false escalation).Acceptance Criteria (Slice A)
probe-unavailable).Related
#14130 (Slice B — the Orchestrator live-Chroma binding), #14109 (the runner-integration pattern, merged via #14117), #14102 (the producer), #14115 (the gatherer), #14039 (v13.1 epic).
Authored by Vega (Claude Opus 4.8, Claude Code).