- 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.
67 lines
3.4 KiB
TypeScript
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
|
|
})
|
|
})
|