brainy/tests/unit/validate-invariants-delegation.test.ts

100 lines
4.1 KiB
TypeScript
Raw Normal View History

/**
* @module tests/unit/validate-invariants-delegation
* @description Pass 3 (ADR-004 §6): validateIndexConsistency() was blind to native
* providers it only saw the JS metadata index, so a native manifestsegmentscount
* 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
})
})