/** * @module tests/unit/validate-invariants-delegation * @description validateIndexConsistency() was blind to native * providers — it only saw the JS metadata index, so a native manifest↔segments↔count * divergence read as "healthy". It now feature-detects + aggregates each provider's * validateInvariants(), and repairIndex() maps a failing invariant with heal:'rebuild' * to that provider's rebuild(). "healthy-while-broken must be impossible." */ import { describe, it, expect, beforeEach } from 'vitest' import { Brainy, NounType } from '../../src/index.js' import type { ProviderInvariantReport } from '../../src/index.js' const healthyReport = (provider: string): ProviderInvariantReport => ({ provider, healthy: true, serving: true, invariants: [{ name: 'manifest-residency', holds: true, detail: 'ok', heal: 'none' }], checkedAt: 1, durationMs: 1 }) const brokenReport = (provider: string): ProviderInvariantReport => ({ provider, healthy: false, serving: true, invariants: [ { name: 'manifest-residency', holds: true, detail: 'ok', heal: 'none' }, { name: 'posted-count-floor', holds: false, detail: 'posted 2304 < canonical 2354', expected: 2354, actual: 2304, heal: 'rebuild' } ], checkedAt: 1, durationMs: 2 }) describe('validateIndexConsistency delegates to provider validateInvariants() (Pass 3)', () => { let brain: any beforeEach(async () => { process.env.BRAINY_DETERMINISTIC_EMBEDDINGS = 'true' brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, dimensions: 384 }) await brain.init() await brain.add({ data: 'x', type: NounType.Concept }) await brain.flush() }) it('a broken provider report makes the store unhealthy and names the failing invariant', async () => { brain.index.validateInvariants = async () => brokenReport('vector') const v = await brain.validateIndexConsistency() expect(v.healthy).toBe(false) expect(v.recommendation).toMatch(/posted-count-floor/) expect(v.recommendation).toMatch(/posted 2304 < canonical 2354/) expect(v.recommendation).toMatch(/repairIndex\(\)/) expect(v.providers?.some((p: ProviderInvariantReport) => p.provider === 'vector' && !p.healthy)).toBe(true) delete brain.index.validateInvariants }) it('all-healthy provider reports do not flip the store unhealthy', async () => { brain.index.validateInvariants = async () => healthyReport('vector') brain.graphIndex.validateInvariants = async () => healthyReport('graph') const v = await brain.validateIndexConsistency() expect(v.healthy).toBe(true) expect(v.providers?.length).toBe(2) delete brain.index.validateInvariants delete brain.graphIndex.validateInvariants }) it('a validateInvariants() that THROWS is surfaced as unhealthy, never swallowed', async () => { brain.index.validateInvariants = async () => { throw new Error('provider blew up') } const v = await brain.validateIndexConsistency() expect(v.healthy).toBe(false) expect(v.recommendation).toMatch(/validate-invariants-threw/) delete brain.index.validateInvariants }) it('providers without validateInvariants() are omitted (JS baseline unchanged)', async () => { const v = await brain.validateIndexConsistency() expect(v.providers).toBeUndefined() expect(typeof v.healthy).toBe('boolean') }) it('repairIndex() rebuilds a provider whose failing invariant asks for it', async () => { let rebuilt = false brain.index.validateInvariants = async () => (rebuilt ? healthyReport('vector') : brokenReport('vector')) const origRebuild = brain.index.rebuild.bind(brain.index) brain.index.rebuild = async (...a: any[]) => { rebuilt = true; return origRebuild(...a) } await brain.repairIndex() expect(rebuilt).toBe(true) // After repair, the store validates healthy again. const v = await brain.validateIndexConsistency() expect(v.providers?.find((p: ProviderInvariantReport) => p.provider === 'vector')?.healthy).toBe(true) brain.index.rebuild = origRebuild delete brain.index.validateInvariants }) })