brainy/tests/integration/find-triple-composition.test.ts
David Snelling af96064655 test(8.0): asOf() error-path spot-checks + find() triple-composition correctness + scale-bench harness
- db-mvcc proof 9: asOf(-1|1.5|future) → RangeError, bad snapshot path → descriptive
  error, use-after-release() throws on get/find/related (Y.15 error-path coverage).
- find-triple-composition: proves vector ∩ metadata ∩ graph returns exactly the
  entity satisfying all three and excludes those failing any one (decoys, wrong category).
- find-composition-scale.js: parameterized latency harness (vector/metadata/graph/
  vector+metadata/triple) with non-empty asserts; precomputed vectors, no model load.
2026-06-15 11:55:26 -07:00

67 lines
3.4 KiB
TypeScript

/**
* @module tests/integration/find-triple-composition
* @description Correctness of Triple-Intelligence composition in `find()`: a single
* query combining vector similarity, metadata filtering, and graph traversal must
* return exactly the entities satisfying ALL three constraints — never silently drop
* a row that each pairwise query would return. Guards the headline 8.0 query surface.
*/
import { describe, it, expect, afterEach } from 'vitest'
import { Brainy } from '../../src/brainy.js'
import { NounType, VerbType } from '../../src/types/graphTypes.js'
/** Deterministic 384-dim vector; same seed ⇒ identical vector (distance 0). */
function vec(seed: number): number[] {
return Array.from({ length: 384 }, (_, i) => ((seed * 31 + i * 7) % 100) / 100)
}
describe('find() Triple-Intelligence composition', () => {
const brains: Brainy[] = []
afterEach(async () => {
for (const b of brains.splice(0)) await b.close()
})
async function open(): Promise<Brainy> {
const b = new Brainy({ storage: { type: 'memory' }, eagerEmbeddings: false, requireSubtype: false, silent: true })
await b.init()
brains.push(b)
return b
}
it('returns the entity satisfying vector ∩ metadata ∩ graph; excludes those failing any one', async () => {
const brain = await open()
const hub = await brain.add({ vector: vec(1), type: NounType.Document, metadata: { role: 'hub', category: 9 } })
// Connected neighbours of the hub:
const n1 = await brain.add({ vector: vec(10), type: NounType.Document, metadata: { role: 'n1', category: 3 } })
const n2 = await brain.add({ vector: vec(11), type: NounType.Document, metadata: { role: 'n2', category: 3 } })
const n3 = await brain.add({ vector: vec(12), type: NounType.Document, metadata: { role: 'n3', category: 7 } })
// Decoys: vector-identical to n1 (seed 10) and category 3, but NOT connected to the hub.
const decoys: string[] = []
for (let i = 0; i < 5; i++) {
decoys.push(await brain.add({ vector: vec(10), type: NounType.Document, metadata: { role: 'decoy', category: 3 } }))
}
await brain.relate({ from: hub, to: n1, type: VerbType.References, weight: 1 })
await brain.relate({ from: hub, to: n2, type: VerbType.References, weight: 1 })
await brain.relate({ from: hub, to: n3, type: VerbType.References, weight: 1 })
const roles = (r: Array<{ metadata?: any }>) => new Set(r.map((x) => x.metadata?.role))
// Sanity: each single/pairwise constraint behaves.
const graphOut = await brain.find({
connected: { from: hub, via: VerbType.References, direction: 'out', depth: 1 }, limit: 50
})
expect(roles(graphOut)).toEqual(new Set(['n1', 'n2', 'n3']))
// Full triple: near vec(10) (n1 + decoys) AND category 3 (n1, n2, decoys) AND connected to hub (n1,n2,n3).
// The intersection is exactly {n1}. Decoys fail graph; n2 fails vector(distance); n3 fails category.
const triple = await brain.find({
vector: vec(10),
where: { category: 3 },
connected: { from: hub, via: VerbType.References, direction: 'out', depth: 1 },
limit: 50
})
const got = roles(triple)
expect(got.size).toBeGreaterThan(0) // composition must not be empty
expect(got.has('n1')).toBe(true) // n1 satisfies all three — must be present
expect(got.has('decoy')).toBe(false) // decoys fail the graph constraint
expect(got.has('hub')).toBe(false) // hub is category 9
})
})