test(8.0): cover the native graph seam + make provider resolution factory-tolerant
The brain.graph.subgraph/export NATIVE routing (graphSubgraphNative /
graphExportNative / hydrateNativeSubgraph + provider resolution) had ZERO brainy
CI coverage — in production it's exercised only cross-layer against cor's engine,
so a columnar return-shape or hydration-alignment drift would pass brainy CI
silently. This registers a faithful MOCK GraphAccelerationProvider returning a
columnar Subgraph built from the brain's REAL ints, locking the seam:
- subgraph() routes native (traverse called) and hydrates node int->id, the
nodeDepth column aligned to the node column, node type via batchGet, and edge
verb-int->Relation via verbIntsToIds + getVerbsBatchCached.
- node<->depth alignment is preserved when a node int does NOT resolve
(deleted/unknown) — the unresolvable int is dropped, not collapsed (which would
shift every later depth). This is the exact hydration risk the release audit flagged.
- export() routes to the graph cursor, hydrates chunks, and ALWAYS closes the handle.
Also fixes a latent contract bug found writing the test: graphAccelerationProvider()
only accepted a ready instance, so a provider registered as a (storage)=>provider
FACTORY (the convention graphIndex/metadataIndex/vector use) would fail the duck-test
and the native path would silently never engage. Now resolves instance OR factory,
cached. Covered by the factory-registration test.
2026-06-22 09:34:09 -07:00
/ * *
* @module tests / unit / brainy / graph - native - routing
* @description Graph engine — NATIVE seam coverage . brain . graph . subgraph / export
* route to a registered GraphAccelerationProvider and hydrate its columnar
* ` Subgraph ` ( node ints - > ids , depth alignment , edge verb - ints - > Relations ) .
* In production that provider is cor ' s native engine , cross - layer - tested on
* bxl9000 ; brainy CI never registers one , so graphSubgraphNative /
* graphExportNative / hydrateNativeSubgraph + the provider - resolution + routing
* were previously UNEXERCISED — a return - shape or hydration - alignment drift would
* pass CI silently . This registers a faithful MOCK provider ( returning a columnar
* Subgraph built from the brain ' s REAL ints , so hydration resolves to real
* entities / relations ) to lock those paths .
* /
import { describe , it , expect , beforeEach , afterEach } from 'vitest'
import { Brainy } from '../../../src/index.js'
import { NounType , VerbType } from '../../../src/types/graphTypes.js'
import { createTestConfig } from '../../helpers/test-factory.js'
/** A stateful mock GraphAccelerationProvider; the test sets the columnar payloads. */
function makeMockAccel() {
const calls = { traverse : 0 , cursorOpen : 0 , cursorNext : 0 , cursorClose : 0 }
const state : { calls : typeof calls ; traverseResult : any ; cursorChunks : any [ ] } = {
calls ,
traverseResult : null ,
cursorChunks : [ ]
}
const empty = { nodeInts : new BigInt64Array ( 0 ) , scores : new Float64Array ( 0 ) }
const provider = {
isInitialized : true ,
traverse : async ( ) = > {
calls . traverse ++
return state . traverseResult
} ,
edgesForNode : async ( ) = > state . traverseResult ,
graphCursorOpen : async ( ) = > {
calls . cursorOpen ++
return 'mock-handle'
} ,
graphCursorNext : async ( ) = > {
calls . cursorNext ++
const subgraph = state . cursorChunks . shift ( )
return { subgraph , done : state.cursorChunks.length === 0 }
} ,
graphCursorClose : async ( ) = > {
calls . cursorClose ++
} ,
2026-06-22 09:54:01 -07:00
rank : async ( ) = > empty ,
communities : async ( ) = > ( { nodeInts : new BigInt64Array ( 0 ) , communityIds : new Uint32Array ( 0 ) , communityCount : 0 } ) ,
path : async ( ) = > null ,
sample : async ( ) = > state . traverseResult ,
mostConnected : async ( ) = > empty
test(8.0): cover the native graph seam + make provider resolution factory-tolerant
The brain.graph.subgraph/export NATIVE routing (graphSubgraphNative /
graphExportNative / hydrateNativeSubgraph + provider resolution) had ZERO brainy
CI coverage — in production it's exercised only cross-layer against cor's engine,
so a columnar return-shape or hydration-alignment drift would pass brainy CI
silently. This registers a faithful MOCK GraphAccelerationProvider returning a
columnar Subgraph built from the brain's REAL ints, locking the seam:
- subgraph() routes native (traverse called) and hydrates node int->id, the
nodeDepth column aligned to the node column, node type via batchGet, and edge
verb-int->Relation via verbIntsToIds + getVerbsBatchCached.
- node<->depth alignment is preserved when a node int does NOT resolve
(deleted/unknown) — the unresolvable int is dropped, not collapsed (which would
shift every later depth). This is the exact hydration risk the release audit flagged.
- export() routes to the graph cursor, hydrates chunks, and ALWAYS closes the handle.
Also fixes a latent contract bug found writing the test: graphAccelerationProvider()
only accepted a ready instance, so a provider registered as a (storage)=>provider
FACTORY (the convention graphIndex/metadataIndex/vector use) would fail the duck-test
and the native path would silently never engage. Now resolves instance OR factory,
cached. Covered by the factory-registration test.
2026-06-22 09:34:09 -07:00
}
return { provider , state }
}
describe ( 'brain.graph.* native routing + columnar hydration (native seam)' , ( ) = > {
let brain : Brainy
let mock : ReturnType < typeof makeMockAccel >
let a : string , b : string , c : string
// Build a faithful columnar Subgraph from the brain's REAL ints, so brainy's
// hydration resolves the node ints to ids and the verb ints to Relations.
async function realSubgraph ( withUnresolvable = false ) {
const gei = ( id : string ) : bigint = > ( brain as any ) . graphEntityInt ( id )
const gi = ( brain as any ) . graphIndex
const intA = gei ( a ) , intB = gei ( b ) , intC = gei ( c )
const vAB = ( await gi . getVerbIdsBySource ( intA ) ) [ 0 ] as bigint // verb int a->b
const vBC = ( await gi . getVerbIdsBySource ( intB ) ) [ 0 ] as bigint // verb int b->c
const nodeInts = [ intA , intB , intC ]
const depths = [ 0 , 1 , 2 ]
if ( withUnresolvable ) {
nodeInts . push ( 999 _999_999n ) // a never-assigned int (simulates a deleted/unknown node)
depths . push ( 3 )
}
return {
nodes : BigInt64Array.from ( nodeInts ) ,
nodeDepth : Uint8Array.from ( depths ) ,
edgeSources : BigInt64Array.from ( [ intA , intB ] ) ,
edgeTargets : BigInt64Array.from ( [ intB , intC ] ) ,
edgeVerbInts : BigInt64Array.from ( [ vAB , vBC ] ) ,
edgeTypes : Uint16Array.from ( [ 0 , 0 ] ) ,
truncated : false
}
}
beforeEach ( async ( ) = > {
mock = makeMockAccel ( )
brain = new Brainy ( createTestConfig ( ) )
brain . use ( {
name : 'mock-graph-accel' ,
activate : async ( ctx : any ) = > {
ctx . registerProvider ( 'graphAcceleration' , mock . provider )
return true
}
} as any )
await brain . init ( )
a = await brain . add ( { type : NounType . Person , subtype : 'employee' , data : 'A' } )
b = await brain . add ( { type : NounType . Person , subtype : 'employee' , data : 'B' } )
c = await brain . add ( { type : NounType . Project , subtype : 'milestone' , data : 'C' } )
await brain . relate ( { from : a , to : b , type : VerbType . RelatedTo , subtype : 'colleague' } )
await brain . relate ( { from : b , to : c , type : VerbType . ParticipatesIn , subtype : 'assignment' } )
} )
afterEach ( async ( ) = > {
await brain . close ( )
} )
it ( 'subgraph() routes to the native provider and hydrates the columnar result' , async ( ) = > {
mock . state . traverseResult = await realSubgraph ( )
const view = await brain . graph . subgraph ( a , { depth : 2 } )
expect ( mock . state . calls . traverse ) . toBe ( 1 ) // native path, not the TS fallback
const byId = new Map ( view . nodes . map ( ( n ) = > [ n . id , n ] ) )
expect ( new Set ( byId . keys ( ) ) ) . toEqual ( new Set ( [ a , b , c ] ) ) // node int -> id
expect ( byId . get ( a ) ? . depth ) . toBe ( 0 )
expect ( byId . get ( c ) ? . depth ) . toBe ( 2 ) // depth column aligned to node column
expect ( byId . get ( c ) ? . type ) . toBe ( NounType . Project ) // node type hydrated via batchGet
const pairs = view . edges . map ( ( e ) = > ` ${ e . from } -> ${ e . to } ` ) . sort ( )
expect ( pairs ) . toEqual ( [ ` ${ a } -> ${ b } ` , ` ${ b } -> ${ c } ` ] . sort ( ) ) // verb int -> Relation
} )
it ( 'keeps node<->depth alignment when a node int does not resolve (deleted/unknown)' , async ( ) = > {
mock . state . traverseResult = await realSubgraph ( true ) // appends an unresolvable int at depth 3
const view = await brain . graph . subgraph ( a , { depth : 3 } )
const byId = new Map ( view . nodes . map ( ( n ) = > [ n . id , n ] ) )
// The 3 real nodes keep their CORRECT depths — the unresolvable int is dropped,
// not collapsed into the array (which would shift every later depth).
expect ( byId . get ( a ) ? . depth ) . toBe ( 0 )
expect ( byId . get ( b ) ? . depth ) . toBe ( 1 )
expect ( byId . get ( c ) ? . depth ) . toBe ( 2 )
expect ( view . nodes . length ) . toBe ( 3 )
} )
it ( 'export() routes to the native graph cursor, hydrates chunks, and always closes' , async ( ) = > {
mock . state . cursorChunks = [ await realSubgraph ( ) ]
const chunks : any [ ] = [ ]
for await ( const v of brain . graph . export ( ) ) chunks . push ( v )
expect ( mock . state . calls . cursorOpen ) . toBe ( 1 )
expect ( mock . state . calls . cursorClose ) . toBe ( 1 ) // cursor released even on normal completion
const nodes = new Set ( chunks . flatMap ( ( c ) = > c . nodes . map ( ( n : any ) = > n . id ) ) )
expect ( nodes ) . toEqual ( new Set ( [ a , b , c ] ) )
const edges = chunks . flatMap ( ( c ) = > c . edges . map ( ( e : any ) = > ` ${ e . from } -> ${ e . to } ` ) ) . sort ( )
expect ( edges ) . toEqual ( [ ` ${ a } -> ${ b } ` , ` ${ b } -> ${ c } ` ] . sort ( ) )
} )
it ( 'resolves a provider registered as a FACTORY (storage) => provider, not just an instance' , async ( ) = > {
const m = makeMockAccel ( )
const fb = new Brainy ( createTestConfig ( ) )
fb . use ( {
name : 'mock-graph-accel-factory' ,
activate : async ( ctx : any ) = > {
ctx . registerProvider ( 'graphAcceleration' , ( ) = > m . provider ) // factory form
return true
}
} as any )
await fb . init ( )
const x = await fb . add ( { type : NounType . Person , subtype : 'employee' , data : 'X' } )
const y = await fb . add ( { type : NounType . Person , subtype : 'employee' , data : 'Y' } )
await fb . relate ( { from : x , to : y , type : VerbType . RelatedTo , subtype : 'colleague' } )
const gei = ( id : string ) : bigint = > ( fb as any ) . graphEntityInt ( id )
const gi = ( fb as any ) . graphIndex
const ix = gei ( x ) , iy = gei ( y )
const vxy = ( await gi . getVerbIdsBySource ( ix ) ) [ 0 ] as bigint
m . state . traverseResult = {
nodes : BigInt64Array.from ( [ ix , iy ] ) ,
nodeDepth : Uint8Array.from ( [ 0 , 1 ] ) ,
edgeSources : BigInt64Array.from ( [ ix ] ) ,
edgeTargets : BigInt64Array.from ( [ iy ] ) ,
edgeVerbInts : BigInt64Array.from ( [ vxy ] ) ,
edgeTypes : Uint16Array.from ( [ 0 ] ) ,
truncated : false
}
const view = await fb . graph . subgraph ( x , { depth : 1 } )
expect ( m . state . calls . traverse ) . toBe ( 1 ) // factory was invoked + provider routed
expect ( new Set ( view . nodes . map ( ( n ) = > n . id ) ) ) . toEqual ( new Set ( [ x , y ] ) )
await fb . close ( )
} )
} )