/** * Metadata cold-read guard (verifyMetadataLive) — a downstream deployment * reported cold `find({ where })` returning a silent `[]` on a freshly-opened * brain (a native metadata index that reports data but has not loaded its field * postings). This guard, the field-index counterpart of verifyGraphAdjacencyLive, * probes a known persisted value on the first filtered find(): if the index does * not serve it, brainy rebuilds and re-probes, and raises a loud * MetadataIndexNotReadyError only if the rebuild still can't serve — never a * silent empty result that misrepresents existing data. * * The 8.0 JS index cold-loads correctly, so we simulate the cold native failure * mode by intercepting the provider's getIdsForFilter/rebuild. */ import { describe, it, expect, beforeEach } from 'vitest' import { Brainy, NounType, MetadataIndexNotReadyError } from '../../src/index.js' const V = () => Array.from({ length: 384 }, (_, i) => Math.sin(i * 0.1) + 0.001) describe('Metadata cold-read guard (#venue silent-[])', () => { let brain: any beforeEach(async () => { brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' } }) await brain.init() await brain.add({ vector: V(), type: NounType.Concept, metadata: { status: 'active' } }) await brain.add({ vector: V(), type: NounType.Concept, metadata: { status: 'archived' } }) await brain.flush() }) it('warm brain: filtered find is correct and the guard does not rebuild', async () => { const mi = brain.metadataIndex let rebuilds = 0 const origRebuild = mi.rebuild.bind(mi) mi.rebuild = async () => { rebuilds++ return origRebuild() } const res = await brain.find({ where: { status: 'active' }, limit: 100 }) expect(res.length).toBe(1) expect(rebuilds).toBe(0) // served live — no rebuild expect(brain._metadataVerified).toBe(true) // one-shot latched mi.rebuild = origRebuild }) it('cold index: verifyMetadataLive self-heals via rebuild — find({where}) is correct, NOT silent []', async () => { const mi = brain.metadataIndex const origGetIds = mi.getIdsForFilter.bind(mi) const origRebuild = mi.rebuild.bind(mi) let cold = true brain._metadataVerified = false // re-arm the one-shot for this scenario mi.getIdsForFilter = async (...a: any[]) => (cold ? [] : origGetIds(...a)) mi.rebuild = async () => { await origRebuild() cold = false // the rebuild warms the postings } try { const res = await brain.find({ where: { status: 'active' }, limit: 100 }) expect(res.length).toBe(1) // self-healed — the known entity is returned } finally { mi.getIdsForFilter = origGetIds mi.rebuild = origRebuild } }) it('unrecoverably cold index: find({where}) throws MetadataIndexNotReadyError — never a silent []', async () => { const mi = brain.metadataIndex const origGetIds = mi.getIdsForFilter.bind(mi) const origRebuild = mi.rebuild.bind(mi) brain._metadataVerified = false mi.getIdsForFilter = async () => [] // always cold; rebuild can't fix it mi.rebuild = async () => {} try { await expect(brain.find({ where: { status: 'active' }, limit: 100 })).rejects.toBeInstanceOf( MetadataIndexNotReadyError ) } finally { mi.getIdsForFilter = origGetIds mi.rebuild = origRebuild } }) it('a query with no filter does not trigger the metadata probe', async () => { const mi = brain.metadataIndex let probes = 0 const origGetIds = mi.getIdsForFilter.bind(mi) mi.getIdsForFilter = async (...a: any[]) => { probes++ return origGetIds(...a) } brain._metadataVerified = false // A pure vector query (no where/type) must not run verifyMetadataLive's probe. await brain.find({ vector: V(), limit: 5 }) expect(brain._metadataVerified).toBe(false) // guard never ran mi.getIdsForFilter = origGetIds void probes }) })