2025-09-11 16:23:32 -07:00
/ * *
* Triple Intelligence Scale Tests - 1 M + Items
*
* These tests verify that Triple Intelligence maintains O ( log n ) performance
* at scale with real data , no mocks , no stubs .
* /
import { describe , it , expect , beforeAll , afterAll } from 'vitest'
import { Brainy } from '../../src/brainy.js'
import { TripleIntelligenceSystem } from '../../src/triple/TripleIntelligenceSystem.js'
describe ( 'Triple Intelligence Performance at Scale' , ( ) = > {
let brain : Brainy
let triple : TripleIntelligenceSystem
const TEST_SIZE = process . env . CI ? 100000 : 1000000 // Smaller on CI
beforeAll ( async ( ) = > {
console . log ( ` \ n🚀 Initializing Brainy with ${ TEST_SIZE . toLocaleString ( ) } items... ` )
const startTime = Date . now ( )
// Initialize Brainy with all required indexes
feat(8.0)!: flip requireSubtype default to true (BRAINY-8.0-SUBTYPE-CONTRACT § C-1)
Brainy 8.0 makes subtype required by default on every public write path
(`add`, `addMany`, `update`, `relate`, `relateMany`, `updateRelation`,
import). Per the locked C-1 contract, every entity and relation gets a
non-empty subtype string by the time the storage layer sees it.
OPT-OUT REMAINS FULLY SUPPORTED
The runtime flag is still consumer-controlled. Three opt-out paths
cover migration / legacy fixtures / typed escape:
- `new Brainy({ requireSubtype: false })` — last-resort: turn off the
contract entirely. Recommended only for migration windows or test
fixtures that legitimately can't supply a subtype.
- `new Brainy({ requireSubtype: { except: [NounType.Thing, ...] } })` —
per-type allowlist: strict everywhere except the listed types.
- `brain.requireSubtype(type, options)` — per-type registration with
optional vocabulary. Composes with the brain-wide flag.
Default is now `true`. Opt-out is explicit and documented; nothing
silently degrades.
TEST SWEEP
Bulk-applied `requireSubtype: false` to every `new Brainy({...})` call
site across 120 test files. Three sed patterns covered the shapes:
- `new Brainy({` → `new Brainy({ requireSubtype: false,`
- `new Brainy<T>({` → `new Brainy<T>({ requireSubtype: false,`
- `new Brainy()` → `new Brainy({ requireSubtype: false })`
tests/helpers/test-factory.ts → createTestConfig() defaults
`requireSubtype: false` so test files using the helper inherit the
opt-out without per-site edits.
The test sites that DO exercise subtype semantics (the
subtype-and-facets suite, the strict-mode-self-test suite, the verb-
subtype-and-enforcement suite, etc.) already pass real subtypes — they
were the 7.30.x acceptance tests for this contract. Those tests
continue to pass unchanged.
CHANGES
src/brainy.ts
- normalizeConfig() — `requireSubtype` default `false` → `true`.
Comment refreshed to document the three opt-out paths.
tests/* (120 files)
- Bulk-edited brain construction sites. No functional test changes; the
opt-out preserves the test author's original intent.
tests/helpers/test-factory.ts
- createTestConfig() base config gains `requireSubtype: false`.
NO-OP for consumers who were already passing subtype on every write.
For consumers who weren't, the upgrade path is one of the three opt-out
forms above. Migration recipe documented in 8.0 release notes (next
commit).
VERIFICATION
- npx tsc --noEmit: clean
- npm test: 1408 / 1409 (same pre-existing race-condition outstanding;
no other regressions from the flip)
2026-06-09 14:58:25 -07:00
brain = new Brainy ( { requireSubtype : false } )
2025-09-11 16:23:32 -07:00
await brain . init ( {
enableMetadataIndex : true ,
enableGraphIndex : true ,
dimensions : 1536 ,
storage : {
type : 'memory' // Use in-memory for speed
}
} )
// Generate and add test data
console . log ( '📊 Generating test data...' )
const batchSize = 1000
const categories = [ 'tech' , 'science' , 'health' , 'business' , 'education' ]
const tags = Array . from ( { length : 100 } , ( _ , i ) = > ` tag ${ i } ` )
for ( let i = 0 ; i < TEST_SIZE ; i += batchSize ) {
const batch = [ ]
for ( let j = 0 ; j < batchSize && i + j < TEST_SIZE ; j ++ ) {
const idx = i + j
batch . push ( {
id : ` item- ${ idx } ` ,
data : ` This is item ${ idx } containing information about ${ categories [ idx % categories . length ] } ` ,
metadata : {
category : categories [ idx % categories . length ] ,
value : idx ,
timestamp : Date.now ( ) - idx * 1000 ,
tags : [ tags [ idx % 100 ] , tags [ ( idx + 50 ) % 100 ] ] ,
score : Math.random ( ) * 100 ,
active : idx % 2 === 0
}
} )
}
// Add batch
await brain . addMany ( batch )
if ( i % 10000 === 0 ) {
console . log ( ` Added ${ i . toLocaleString ( ) } / ${ TEST_SIZE . toLocaleString ( ) } items... ` )
}
}
// Add some relationships for graph testing
console . log ( '🔗 Creating graph relationships...' )
for ( let i = 0 ; i < 10000 ; i ++ ) {
const sourceId = ` item- ${ Math . floor ( Math . random ( ) * TEST_SIZE ) } `
const targetId = ` item- ${ Math . floor ( Math . random ( ) * TEST_SIZE ) } `
await brain . relate ( {
from : sourceId ,
to : targetId ,
type : 'references' ,
metadata : { strength : Math.random ( ) }
} )
}
// Get the Triple Intelligence system
triple = brain . getTripleIntelligence ( )
const elapsed = Date . now ( ) - startTime
console . log ( ` ✅ Setup complete in ${ ( elapsed / 1000 ) . toFixed ( 1 ) } s \ n ` )
} , 300000 ) // 5 minute timeout for setup
afterAll ( async ( ) = > {
await brain ? . close ( )
} )
it ( 'should perform vector search in O(log n) time' , async ( ) = > {
const query = {
similar : 'technology and artificial intelligence' ,
limit : 10
}
// Warm up
await triple . find ( query )
// Measure
const startTime = performance . now ( )
const results = await triple . find ( query )
const elapsed = performance . now ( ) - startTime
// For 1M items, log2(1M) ≈ 20
// HNSW should complete in roughly 20 * 5ms = 100ms
const expectedTime = Math . log2 ( TEST_SIZE ) * 5
console . log ( ` Vector search: ${ elapsed . toFixed ( 2 ) } ms (expected < ${ expectedTime . toFixed ( 2 ) } ms) ` )
expect ( elapsed ) . toBeLessThan ( expectedTime * 2 ) // Allow 2x margin
expect ( results ) . toHaveLength ( 10 )
expect ( results [ 0 ] . vectorScore ) . toBeDefined ( )
expect ( results [ 0 ] . score ) . toBeGreaterThan ( 0 )
} )
it ( 'should perform range queries in O(log n) time' , async ( ) = > {
const query = {
where : {
value : { $gt : TEST_SIZE / 2 , $lt : TEST_SIZE / 2 + 10000 } ,
category : 'tech'
} ,
limit : 20
}
// Warm up
await triple . find ( query )
// Measure
const startTime = performance . now ( )
const results = await triple . find ( query )
const elapsed = performance . now ( ) - startTime
// B-tree range queries should be O(log n)
const expectedTime = Math . log2 ( TEST_SIZE ) * 3
console . log ( ` Range query: ${ elapsed . toFixed ( 2 ) } ms (expected < ${ expectedTime . toFixed ( 2 ) } ms) ` )
expect ( elapsed ) . toBeLessThan ( expectedTime * 2 )
expect ( results . length ) . toBeGreaterThan ( 0 )
expect ( results . length ) . toBeLessThanOrEqual ( 20 )
// Verify results match criteria
for ( const result of results ) {
expect ( result . metadata . value ) . toBeGreaterThan ( TEST_SIZE / 2 )
expect ( result . metadata . value ) . toBeLessThan ( TEST_SIZE / 2 + 10000 )
expect ( result . metadata . category ) . toBe ( 'tech' )
}
} )
it ( 'should perform complex multi-field queries efficiently' , async ( ) = > {
const query = {
where : {
category : { $in : [ 'tech' , 'science' ] } ,
score : { $gt : 50 } ,
active : true ,
tags : { $contains : 'tag10' }
} ,
limit : 50
}
const startTime = performance . now ( )
const results = await triple . find ( query )
const elapsed = performance . now ( ) - startTime
const expectedTime = Math . log2 ( TEST_SIZE ) * 5
console . log ( ` Complex query: ${ elapsed . toFixed ( 2 ) } ms (expected < ${ expectedTime . toFixed ( 2 ) } ms) ` )
expect ( elapsed ) . toBeLessThan ( expectedTime * 3 ) // Complex queries get more margin
expect ( results . length ) . toBeGreaterThan ( 0 )
// Verify all results match ALL criteria
for ( const result of results ) {
expect ( [ 'tech' , 'science' ] ) . toContain ( result . metadata . category )
expect ( result . metadata . score ) . toBeGreaterThan ( 50 )
expect ( result . metadata . active ) . toBe ( true )
expect ( result . metadata . tags ) . toContain ( 'tag10' )
}
} )
it ( 'should perform graph traversal in O(1) per node' , async ( ) = > {
const query = {
connected : {
from : 'item-1000' ,
direction : 'out' ,
depth : 2
} ,
limit : 30
}
const startTime = performance . now ( )
const results = await triple . find ( query )
const elapsed = performance . now ( ) - startTime
// Graph traversal with adjacency lists should be very fast
// O(1) per node lookup, limited by depth
const expectedTime = 50 // Should be constant time-ish
console . log ( ` Graph traversal: ${ elapsed . toFixed ( 2 ) } ms (expected < ${ expectedTime . toFixed ( 2 ) } ms) ` )
expect ( elapsed ) . toBeLessThan ( expectedTime * 2 )
expect ( results . length ) . toBeGreaterThan ( 0 )
expect ( results [ 0 ] . depth ) . toBeDefined ( )
expect ( results [ 0 ] . graphScore ) . toBeDefined ( )
} )
it ( 'should perform hybrid queries with RRF fusion' , async ( ) = > {
const query = {
similar : 'artificial intelligence machine learning' ,
where : {
category : 'tech' ,
score : { $gt : 30 }
} ,
connected : {
from : 'item-5000' ,
depth : 1
} ,
limit : 20
}
const startTime = performance . now ( )
const results = await triple . find ( query , {
fusion : {
strategy : 'rrf' ,
k : 60 ,
weights : {
vector : 0.5 ,
field : 0.3 ,
graph : 0.2
}
}
} )
const elapsed = performance . now ( ) - startTime
// Hybrid query should still be fast
const expectedTime = Math . log2 ( TEST_SIZE ) * 10
console . log ( ` Hybrid query: ${ elapsed . toFixed ( 2 ) } ms (expected < ${ expectedTime . toFixed ( 2 ) } ms) ` )
expect ( elapsed ) . toBeLessThan ( expectedTime * 2 )
expect ( results ) . toHaveLength ( 20 )
// Verify fusion scores
expect ( results [ 0 ] . fusionScore ) . toBeDefined ( )
expect ( results [ 0 ] . vectorScore ) . toBeDefined ( )
expect ( results [ 0 ] . fieldScore ) . toBeDefined ( )
// Fusion scores should be sorted
for ( let i = 0 ; i < results . length - 1 ; i ++ ) {
expect ( results [ i ] . fusionScore ) . toBeGreaterThanOrEqual ( results [ i + 1 ] . fusionScore )
}
} )
it ( 'should maintain performance across different dataset sizes' , async ( ) = > {
const sizes = [ 1000 , 10000 , 100000 ]
const timings : number [ ] = [ ]
for ( const size of sizes ) {
const query = {
where : {
value : { $lt : size }
} ,
limit : 10
}
// Warm up
await triple . find ( query )
// Measure
const startTime = performance . now ( )
await triple . find ( query )
const elapsed = performance . now ( ) - startTime
timings . push ( elapsed )
}
console . log ( '\nPerformance scaling:' )
console . log ( 'Size Time(ms) Ratio' )
console . log ( '--------- --------- -----' )
for ( let i = 0 ; i < sizes . length ; i ++ ) {
const ratio = i > 0 ? ( timings [ i ] / timings [ i - 1 ] ) . toFixed ( 2 ) : '-'
console . log (
` ${ sizes [ i ] . toString ( ) . padEnd ( 9 ) } ${ timings [ i ] . toFixed ( 2 ) . padEnd ( 9 ) } ${ ratio } `
)
}
// Each 10x increase in data should only increase time by ~3.3x (log2(10))
// Allow some variance but ensure it's not linear (10x)
for ( let i = 1 ; i < timings . length ; i ++ ) {
const ratio = timings [ i ] / timings [ i - 1 ]
expect ( ratio ) . toBeLessThan ( 5 ) // Much less than 10x
}
} )
it ( 'should fail loudly on performance violations' , async ( ) = > {
// Create a query that would be slow without indexes
const slowQuery = {
where : {
nonIndexedField : 'some value' // This field doesn't exist
}
}
// This should either:
// 1. Throw an error because the field isn't indexed
// 2. Return empty results quickly
// But NOT fall back to O(n) scanning
const startTime = performance . now ( )
try {
const results = await triple . find ( slowQuery )
const elapsed = performance . now ( ) - startTime
// If it doesn't throw, it should still be fast
expect ( elapsed ) . toBeLessThan ( 100 )
expect ( results ) . toHaveLength ( 0 ) // No results for non-existent field
} catch ( error ) {
// Expected - no fallback allowed
expect ( error . message ) . toMatch ( /Performance violation|not indexed|cannot perform/ )
}
} )
it ( 'should provide performance metrics' , async ( ) = > {
// Reset metrics
triple . resetMetrics ( )
// Run various queries
await triple . find ( { similar : 'test' , limit : 5 } )
await triple . find ( { where : { category : 'tech' } , limit : 5 } )
await triple . find ( { connected : { from : 'item-100' , depth : 1 } , limit : 5 } )
// Get performance report
const report = triple . getMetrics ( ) . getReport ( )
console . log ( '\n📊 Performance Report:' )
console . log ( JSON . stringify ( report , null , 2 ) )
// Verify metrics are collected
expect ( report . operations ) . toBeDefined ( )
expect ( Object . keys ( report . operations ) . length ) . toBeGreaterThan ( 0 )
// Check for violations
if ( report . violations . length > 0 ) {
console . warn ( '⚠️ Performance violations detected:' , report . violations )
}
// In production, violations should be rare
for ( const violation of report . violations ) {
expect ( violation . rate ) . toBeLessThan ( 0.1 ) // Less than 10% violation rate
}
} )
} )
describe ( 'Triple Intelligence Correctness' , ( ) = > {
let brain : Brainy
let triple : TripleIntelligenceSystem
beforeAll ( async ( ) = > {
feat(8.0)!: flip requireSubtype default to true (BRAINY-8.0-SUBTYPE-CONTRACT § C-1)
Brainy 8.0 makes subtype required by default on every public write path
(`add`, `addMany`, `update`, `relate`, `relateMany`, `updateRelation`,
import). Per the locked C-1 contract, every entity and relation gets a
non-empty subtype string by the time the storage layer sees it.
OPT-OUT REMAINS FULLY SUPPORTED
The runtime flag is still consumer-controlled. Three opt-out paths
cover migration / legacy fixtures / typed escape:
- `new Brainy({ requireSubtype: false })` — last-resort: turn off the
contract entirely. Recommended only for migration windows or test
fixtures that legitimately can't supply a subtype.
- `new Brainy({ requireSubtype: { except: [NounType.Thing, ...] } })` —
per-type allowlist: strict everywhere except the listed types.
- `brain.requireSubtype(type, options)` — per-type registration with
optional vocabulary. Composes with the brain-wide flag.
Default is now `true`. Opt-out is explicit and documented; nothing
silently degrades.
TEST SWEEP
Bulk-applied `requireSubtype: false` to every `new Brainy({...})` call
site across 120 test files. Three sed patterns covered the shapes:
- `new Brainy({` → `new Brainy({ requireSubtype: false,`
- `new Brainy<T>({` → `new Brainy<T>({ requireSubtype: false,`
- `new Brainy()` → `new Brainy({ requireSubtype: false })`
tests/helpers/test-factory.ts → createTestConfig() defaults
`requireSubtype: false` so test files using the helper inherit the
opt-out without per-site edits.
The test sites that DO exercise subtype semantics (the
subtype-and-facets suite, the strict-mode-self-test suite, the verb-
subtype-and-enforcement suite, etc.) already pass real subtypes — they
were the 7.30.x acceptance tests for this contract. Those tests
continue to pass unchanged.
CHANGES
src/brainy.ts
- normalizeConfig() — `requireSubtype` default `false` → `true`.
Comment refreshed to document the three opt-out paths.
tests/* (120 files)
- Bulk-edited brain construction sites. No functional test changes; the
opt-out preserves the test author's original intent.
tests/helpers/test-factory.ts
- createTestConfig() base config gains `requireSubtype: false`.
NO-OP for consumers who were already passing subtype on every write.
For consumers who weren't, the upgrade path is one of the three opt-out
forms above. Migration recipe documented in 8.0 release notes (next
commit).
VERIFICATION
- npx tsc --noEmit: clean
- npm test: 1408 / 1409 (same pre-existing race-condition outstanding;
no other regressions from the flip)
2026-06-09 14:58:25 -07:00
brain = new Brainy ( { requireSubtype : false } )
2025-09-11 16:23:32 -07:00
await brain . init ( {
enableMetadataIndex : true ,
enableGraphIndex : true
} )
// Add test data with known patterns
const testData = [
{ id : 'doc1' , data : 'Machine learning algorithms' , metadata : { topic : 'AI' , year : 2023 } } ,
{ id : 'doc2' , data : 'Deep learning neural networks' , metadata : { topic : 'AI' , year : 2024 } } ,
{ id : 'doc3' , data : 'Natural language processing' , metadata : { topic : 'AI' , year : 2023 } } ,
{ id : 'doc4' , data : 'Computer vision applications' , metadata : { topic : 'AI' , year : 2024 } } ,
{ id : 'doc5' , data : 'Quantum computing basics' , metadata : { topic : 'Physics' , year : 2023 } } ,
{ id : 'doc6' , data : 'Blockchain technology' , metadata : { topic : 'Crypto' , year : 2024 } }
]
await brain . addMany ( testData )
// Add relationships
await brain . relate ( { from : 'doc1' , to : 'doc2' , type : 'related' } )
await brain . relate ( { from : 'doc2' , to : 'doc3' , type : 'related' } )
await brain . relate ( { from : 'doc3' , to : 'doc4' , type : 'related' } )
triple = brain . getTripleIntelligence ( )
} )
afterAll ( async ( ) = > {
await brain ? . close ( )
} )
it ( 'should return exact matches for field queries' , async ( ) = > {
const results = await triple . find ( {
where : { topic : 'AI' } ,
limit : 10
} )
expect ( results ) . toHaveLength ( 4 )
for ( const result of results ) {
expect ( result . metadata . topic ) . toBe ( 'AI' )
}
} )
it ( 'should handle range queries correctly' , async ( ) = > {
const results = await triple . find ( {
where : { year : { $gte : 2024 } } ,
limit : 10
} )
expect ( results ) . toHaveLength ( 3 )
for ( const result of results ) {
expect ( result . metadata . year ) . toBeGreaterThanOrEqual ( 2024 )
}
} )
it ( 'should traverse graph relationships' , async ( ) = > {
const results = await triple . find ( {
connected : { from : 'doc1' , depth : 2 } ,
limit : 10
} )
// Should find doc1, doc2 (depth 1), and doc3 (depth 2)
const ids = results . map ( r = > r . id )
expect ( ids ) . toContain ( 'doc1' )
expect ( ids ) . toContain ( 'doc2' )
expect ( ids ) . toContain ( 'doc3' )
// Check depth values
const doc1Result = results . find ( r = > r . id === 'doc1' )
const doc2Result = results . find ( r = > r . id === 'doc2' )
const doc3Result = results . find ( r = > r . id === 'doc3' )
expect ( doc1Result ? . depth ) . toBe ( 0 )
expect ( doc2Result ? . depth ) . toBe ( 1 )
expect ( doc3Result ? . depth ) . toBe ( 2 )
} )
it ( 'should combine signals with proper fusion' , async ( ) = > {
const results = await triple . find ( {
similar : 'deep learning' ,
where : { topic : 'AI' } ,
limit : 3
} , {
fusion : {
strategy : 'rrf' ,
weights : { vector : 0.7 , field : 0.3 }
}
} )
// doc2 should rank highest (matches both signals)
expect ( results [ 0 ] . id ) . toBe ( 'doc2' )
expect ( results [ 0 ] . fusionScore ) . toBeGreaterThan ( 0 )
// All results should have AI topic
for ( const result of results ) {
expect ( result . metadata . topic ) . toBe ( 'AI' )
}
} )
} )