2026-08-10 10:55:11 -07:00
/ * *
* @module tests / integration / fact - log - v2 - cutover
* @description The fact log ' s LIVE WRITE FORMAT cutover to v2 , end - to - end
* through real brains : ( a ) a NEW brain ' s tail segment carries a v2 header
* ( formatVersion 2 , sealSize 4096 ) , opens with the log . genesis record
* ( id - space width 64 + the manifest - persisted brainId ) , and scanFacts yields
* the same CommitFact shape a v1 brain would — reconstruction included ,
* proven by digest - equality against canonical after a reopen ; ( b ) MIXED
* logs : an existing v1 segment stays readable forever beside a v2 tail
* ( cutover - by - rotation ; the v1 segment is never rewritten ) ; ( c ) MINT :
* after - image records carry the metadata index id mapper ' s exact int
* assignments ( white - box compare ) ; ( d ) SEALS : every flush leaves the tail
* sector - aligned , and pads are invisible to scans ; ( e ) REPLAY : the
* log - authority recovery path resurrects an acked write from a v2 tail
* after a crash - style abandon .
* /
import { describe , it , expect , afterEach } from 'vitest'
import * as fs from 'node:fs'
import * as path from 'node:path'
import { mkdtempSync , rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { Brainy } from '../../src/brainy.js'
import { NounType } from '../../src/types/graphTypes.js'
import {
parseSegmentHeader ,
decodeGroupV2 ,
SEGMENT_HEADER_BYTES ,
FACT_LOG_FORMAT_V1 ,
FACT_LOG_FORMAT_V2 ,
type LogGenesisRecord ,
type NounAfterImageRecord
} from '../../src/db/factLogFormat.js'
import type { CommitFact , FactIntMinter , FactLog } from '../../src/db/factLog.js'
import {
makeTempDir ,
openBrain ,
storeOf ,
abandonAsCrashed ,
factGenerations ,
vec ,
uid
} from '../helpers/durabilityKillMatrix.js'
/** The VFS root — created at init by a baseline (generation-less) write. */
const VFS_ROOT = '00000000-0000-0000-0000-000000000000'
const FACTS_DIR = [ '_generations' , 'facts' ] as const
const MANIFEST_PATH = '_generations/facts/manifest.json'
/** White-box internals this suite instruments. */
type BrainInternals = {
storage : {
readRawObject ( p : string ) : Promise < unknown | null >
readNounRaw ( id : string ) : Promise < { metadata : unknown | null ; vector : unknown | null } >
}
metadataIndex : {
getIdMapper ( ) : { getInt ( uuid : string ) : number | undefined }
}
}
const internals = ( brain : Brainy ) : BrainInternals = > brain as unknown as BrainInternals
/** The facts manifest as stored (additive brainId included). */
interface StoredFactsManifest {
segments : Array < { file : string } >
tailSegment : string | null
brainId? : string
}
async function readManifest ( brain : Brainy ) : Promise < StoredFactsManifest > {
const manifest = ( await internals ( brain ) . storage . readRawObject (
MANIFEST_PATH
) ) as StoredFactsManifest | null
expect ( manifest , 'the facts manifest exists' ) . toBeTruthy ( )
return manifest !
}
/** Raw on-disk bytes of one fact segment file. */
function segmentBytes ( dir : string , file : string ) : Uint8Array {
return new Uint8Array ( fs . readFileSync ( path . join ( dir , . . . FACTS_DIR , file ) ) )
}
async function allFacts ( brain : Brainy ) : Promise < CommitFact [ ] > {
const scan = ( brain as unknown as { scanFacts ( ) : { batches ( ) : AsyncGenerator < { facts : CommitFact [ ] } > } | null } ) . scanFacts ( )
expect ( scan , 'this storage hosts a fact log' ) . not . toBeNull ( )
const facts : CommitFact [ ] = [ ]
for await ( const batch of scan ! . batches ( ) ) facts . push ( . . . batch . facts )
return facts
}
/** The live FactLog instance (white-box: the minter strip in scenario b). */
function factLogOf ( brain : Brainy ) : FactLog & { intMinter : FactIntMinter | null } {
const log = storeOf ( brain ) . getFactLog ( )
expect ( log , 'filesystem storage hosts a fact log' ) . not . toBeNull ( )
return log as FactLog & { intMinter : FactIntMinter | null }
}
describe ( 'fact log v2 cutover — live writes land in the v2 segment format' , ( ) = > {
const dirs : string [ ] = [ ]
const brains : Brainy [ ] = [ ]
const trackDir = ( ) : string = > {
const dir = makeTempDir ( )
dirs . push ( dir )
return dir
}
const track = ( brain : Brainy ) : Brainy = > {
brains . push ( brain )
return brain
}
afterEach ( async ( ) = > {
for ( const b of brains . splice ( 0 ) ) {
await ( b as unknown as { close ? : ( ) = > Promise < void > } ) . close ? . ( ) . catch ( ( ) = > { } )
}
for ( const d of dirs . splice ( 0 ) ) rmSync ( d , { recursive : true , force : true } )
} )
it ( '(a) NEW BRAIN: v2 tail header, genesis-first, and scanFacts parity with canonical across a reopen' , async ( ) = > {
const dir = trackDir ( )
const brain = track ( await openBrain ( dir ) )
const idA = uid ( 'v2-new-a' )
const idB = uid ( 'v2-new-b' )
await brain . add ( { id : idA , data : 'alpha' , type : NounType . Document , vector : vec ( 1 ) , metadata : { n : 1 } } )
await brain . add ( { id : idB , data : 'beta' , type : NounType . Document , vector : vec ( 2 ) , metadata : { n : 2 } } )
await brain . flush ( )
// The tail segment's raw header bytes: formatVersion 2, sealSize 4096.
const manifest = await readManifest ( brain )
expect ( manifest . tailSegment ) . toBeTruthy ( )
expect ( manifest . brainId , 'the brain id was minted into the manifest' ) . toBeTruthy ( )
const bytes = segmentBytes ( dir , manifest . tailSegment ! )
const header = parseSegmentHeader ( bytes . subarray ( 0 , SEGMENT_HEADER_BYTES ) )
expect ( header . formatVersion ) . toBe ( FACT_LOG_FORMAT_V2 )
expect ( header . sealSize ) . toBe ( 4096 )
// Genesis is the FIRST record of the FIRST fact — and appears exactly once.
const group = decodeGroupV2 ( bytes . subarray ( SEGMENT_HEADER_BYTES ) , { expectedIdSpaceWidth : 64 } )
expect ( group . facts . length ) . toBeGreaterThanOrEqual ( 2 )
const firstRecord = group . facts [ 0 ] . records [ 0 ]
expect ( firstRecord . type ) . toBe ( 'log.genesis' )
const genesis = firstRecord as LogGenesisRecord
expect ( genesis . idSpaceWidth ) . toBe ( 64 )
expect ( genesis . brainId ) . toBe ( manifest . brainId )
const genesisCount = group . facts
. flatMap ( ( f ) = > f . records )
. filter ( ( r ) = > r . type === 'log.genesis' ) . length
expect ( genesisCount ) . toBe ( 1 )
// Shape parity + reconstruction fidelity: REOPEN (so the tail decodes
// from disk, not from the in-session originals) and compare each add's
// CommitFact op against canonical byte truth — metadata leg (bigint
// timestamps normalized back to numbers) AND the reconstructed vector
// wrapper must equal what readNounRaw returns, exactly as a v1 log's
// byte-faithful capture would.
await ( brain as unknown as { close : ( ) = > Promise < void > } ) . close ( )
brains . splice ( brains . indexOf ( brain ) , 1 )
const reopened = track ( await openBrain ( dir ) )
const facts = await allFacts ( reopened )
const gens = facts . map ( ( f ) = > f . generation )
expect ( [ . . . gens ] . sort ( ( a , b ) = > a - b ) ) . toEqual ( gens )
expect ( new Set ( gens ) . size ) . toBe ( gens . length )
const logGens = new Set (
( ( await ( reopened as unknown as { transactionLog ( ) : Promise < Array < { generation : number } > > } ) . transactionLog ( ) ) ? ? [ ] ) . map (
( e ) = > e . generation
)
)
for ( const g of gens ) expect ( logGens . has ( g ) , ` generation ${ g } is a real commit ` ) . toBe ( true )
for ( const id of [ idA , idB ] ) {
const fact = facts . find ( ( f ) = > f . ops . some ( ( op ) = > op . id === id && op . record !== null ) )
expect ( fact , ` the add fact for ${ id } survives the reopen ` ) . toBeDefined ( )
const op = fact ! . ops . find ( ( o ) = > o . id === id ) !
expect ( op . kind ) . toBe ( 'noun' )
const canonical = await internals ( reopened ) . storage . readNounRaw ( id )
expect ( op . record ! . metadata ) . toStrictEqual ( canonical . metadata )
feat(embedding): deferred-embed markers become log records — the sidecar recovery path is deleted
The private recovery discipline, applied to its own machinery: pending-
embed markers stop being sidecar files and become first-class log records
riding the write's OWN commit fact — embed.pending lands in the same
atomic append as its after-image (a marker can never be orphaned from its
write, or vice versa; in durable-at-ack mode it shares the write's
covering fsync — zero extra syncs), and the worker's landing commit rides
embed.landed with the inline vector. Crash recovery is now a FOLD of the
log (pending without a matching landed = recovered), skipped wholesale on
brains with no v2 history; the one-time legacy bridge folds existing
sidecar files in, migrates them as one fact, and deletes them —
idempotent under a crash mid-bridge. No code path writes the sidecar
again.
Plus the ENTITY-TRUTH digest law, found by this train's own pins:
canonical vector wrappers denormalize HNSW residue (connections + the
randomly-assigned node level) that the log deliberately does not carry —
the verification oracle digested it and would have reported false
state-differs on ~any nonzero-level node (a ~15% flake in the cutover pin
was the symptom). Both sides of every oracle comparison now normalize to
entity truth (nounEntityTruth); index residue has its own rebuild path
and is not entity state.
Pins: embed-markers-in-log 5/5 (same-generation marker, landed+fold-to-
zero, crash recovery via the log with the sidecar prefix EMPTY on disk,
legacy bridge, VFS hung-embedder ack) · deferred-embedding 5/5 unchanged
(the contract outlived its mechanism) · kill-matrix 11/11 · cutover 5/5
×10 runs (flake dead) · unit 2031/2031.
2026-08-10 11:27:07 -07:00
// ENTITY TRUTH comparison: canonical wrappers denormalize HNSW residue
// (connections + the randomly-assigned level) that the log record
// deliberately reconstructs empty — strip both sides (the oracle's
// normalizer law) so a nonzero random level can't fake a divergence.
const strip = ( w : unknown ) = > {
const { connections : _c , level : _l , . . . rest } = w as Record < string , unknown >
return rest
}
expect ( strip ( op . record ! . vector ) ) . toStrictEqual ( strip ( canonical . vector ) )
2026-08-10 10:55:11 -07:00
}
} )
it ( '(b) MIXED LOG: an existing v1 segment stays readable forever beside the v2 tail (cutover by rotation, v1 bytes untouched)' , async ( ) = > {
// ROUTE: a REAL v1 segment is written by the v1 writer itself — the live
// FactLog with its minter stripped (the exact pre-cutover code path,
// still shipped for minter-less configurations) — then the minter is
// restored mid-session and the next append performs the cutover
// rotation. Stronger than hand-crafted bytes: both formats come from
// their real writers, on one log.
const dir = trackDir ( )
const brain = track ( await openBrain ( dir ) )
const log = factLogOf ( brain )
const minter = log . intMinter
expect ( minter , 'the brain wired the int minter at init' ) . toBeTruthy ( )
log . intMinter = null // the pre-cutover writer
const idOld1 = uid ( 'v1-old-1' )
const idOld2 = uid ( 'v1-old-2' )
await brain . add ( { id : idOld1 , data : 'old one' , type : NounType . Document , vector : vec ( 3 ) , metadata : { era : 'v1' } } )
await brain . add ( { id : idOld2 , data : 'old two' , type : NounType . Document , vector : vec ( 4 ) , metadata : { era : 'v1' } } )
await brain . flush ( )
const before = await readManifest ( brain )
expect ( before . segments ) . toHaveLength ( 0 )
const v1TailFile = before . tailSegment !
const v1Bytes = segmentBytes ( dir , v1TailFile )
expect ( parseSegmentHeader ( v1Bytes . subarray ( 0 , SEGMENT_HEADER_BYTES ) ) . formatVersion ) . toBe (
FACT_LOG_FORMAT_V1
)
log . intMinter = minter // the cutover lands mid-session
const idNew = uid ( 'v2-new' )
await brain . add ( { id : idNew , data : 'new era' , type : NounType . Document , vector : vec ( 5 ) , metadata : { era : 'v2' } } )
await brain . flush ( )
// The v1 tail was SEALED (bytes untouched), the new tail is v2.
const after = await readManifest ( brain )
expect ( after . segments . map ( ( s ) = > s . file ) ) . toContain ( v1TailFile )
expect ( after . tailSegment ) . not . toBe ( v1TailFile )
const sealedBytes = segmentBytes ( dir , v1TailFile )
expect ( parseSegmentHeader ( sealedBytes . subarray ( 0 , SEGMENT_HEADER_BYTES ) ) . formatVersion ) . toBe (
FACT_LOG_FORMAT_V1
)
expect (
Buffer . compare ( Buffer . from ( sealedBytes ) , Buffer . from ( v1Bytes ) ) ,
'the sealed v1 segment is byte-identical — never rewritten'
) . toBe ( 0 )
const tailBytes = segmentBytes ( dir , after . tailSegment ! )
expect ( parseSegmentHeader ( tailBytes . subarray ( 0 , SEGMENT_HEADER_BYTES ) ) . formatVersion ) . toBe (
FACT_LOG_FORMAT_V2
)
// NOT a brand-new log: no genesis on a rotated-in v2 tail.
const tailGroup = decodeGroupV2 ( tailBytes . subarray ( SEGMENT_HEADER_BYTES ) , {
expectedIdSpaceWidth : 64
} )
expect (
tailGroup . facts . flatMap ( ( f ) = > f . records ) . some ( ( r ) = > r . type === 'log.genesis' )
) . toBe ( false )
// One scan spans both formats, shape-identically, in generation order.
const liveFacts = await allFacts ( brain )
const liveGens = liveFacts . map ( ( f ) = > f . generation )
expect ( [ . . . liveGens ] . sort ( ( a , b ) = > a - b ) ) . toEqual ( liveGens )
for ( const id of [ idOld1 , idOld2 , idNew ] ) {
const fact = liveFacts . find ( ( f ) = > f . ops . some ( ( op ) = > op . id === id ) )
expect ( fact , ` fact for ${ id } is scannable ` ) . toBeDefined ( )
const op = fact ! . ops . find ( ( o ) = > o . id === id ) !
expect ( op . kind ) . toBe ( 'noun' )
expect ( op . record ) . not . toBeNull ( )
}
// The MIXED log survives a reopen and keeps appending (v2 tail).
await ( brain as unknown as { close : ( ) = > Promise < void > } ) . close ( )
brains . splice ( brains . indexOf ( brain ) , 1 )
const reopened = track ( await openBrain ( dir ) )
const reFacts = await allFacts ( reopened )
expect ( reFacts . map ( ( f ) = > f . generation ) ) . toEqual ( liveGens )
// The v1 fact still reads exactly as the v1 decoder always read it.
// (Not compared byte-strict against canonical: the v1 CAPTURE has a
// known pre-existing wart — write-cache-warm objects carry
// undefined-valued engine keys that msgpack preserves as nil while the
// durable JSON drops them. v1 bytes are frozen; the v2 encoder
// sanitizes to durable truth instead — pinned in scenario (a).)
const oldOp = reFacts
. find ( ( f ) = > f . ops . some ( ( op ) = > op . id === idOld1 ) ) !
. ops . find ( ( o ) = > o . id === idOld1 ) !
const canonicalOld = await internals ( reopened ) . storage . readNounRaw ( idOld1 )
const oldMeta = oldOp . record ! . metadata as Record < string , unknown >
expect ( oldMeta . noun ) . toBe ( 'document' )
expect ( ( oldMeta . metadata as Record < string , unknown > ) . era ) . toBe ( 'v1' )
const oldWrapper = oldOp . record ! . vector as { id : string ; vector : number [ ] }
const canonicalWrapper = canonicalOld . vector as { id : string ; vector : number [ ] }
expect ( oldWrapper . id ) . toBe ( idOld1 )
expect ( oldWrapper . vector ) . toStrictEqual ( canonicalWrapper . vector )
await reopened . add ( { id : uid ( 'post-reopen' ) , data : 'still writing' , type : NounType . Document , vector : vec ( 6 ) , metadata : { } } )
expect ( ( await factGenerations ( reopened ) ) . length ) . toBe ( liveGens . length + 1 )
} )
it ( '(c) MINT-AT-APPEND: after-image records carry the id mapper\'s EXACT int assignments — distinct, nonzero, reproducible' , async ( ) = > {
const dir = trackDir ( )
const brain = track ( await openBrain ( dir ) )
const idA = uid ( 'mint-a' )
const idB = uid ( 'mint-b' )
await brain . add ( { id : idA , data : 'mint one' , type : NounType . Document , vector : vec ( 7 ) , metadata : { m : 1 } } )
await brain . add ( { id : idB , data : 'mint two' , type : NounType . Document , vector : vec ( 8 ) , metadata : { m : 2 } } )
await brain . flush ( )
const manifest = await readManifest ( brain )
const bytes = segmentBytes ( dir , manifest . tailSegment ! )
const group = decodeGroupV2 ( bytes . subarray ( SEGMENT_HEADER_BYTES ) , { expectedIdSpaceWidth : 64 } )
const afterImages = new Map < string , NounAfterImageRecord > ( )
for ( const fact of group . facts ) {
for ( const record of fact . records ) {
if ( record . type === 'noun.afterImage' ) afterImages . set ( record . id , record )
}
}
const recA = afterImages . get ( idA )
const recB = afterImages . get ( idB )
expect ( recA , 'idA has a decoded after-image' ) . toBeDefined ( )
expect ( recB , 'idB has a decoded after-image' ) . toBeDefined ( )
expect ( recA ! . entityInt ) . toBeGreaterThan ( 0 n )
expect ( recB ! . entityInt ) . toBeGreaterThan ( 0 n )
expect ( recA ! . entityInt ) . not . toBe ( recB ! . entityInt )
// White-box: the ints on the wire ARE the metadata index mapper's
// assignments — the exact ints a mapper rebuild must reproduce.
const mapper = internals ( brain ) . metadataIndex . getIdMapper ( )
expect ( recA ! . entityInt ) . toBe ( BigInt ( mapper . getInt ( idA ) ! ) )
expect ( recB ! . entityInt ) . toBe ( BigInt ( mapper . getInt ( idB ) ! ) )
} )
it ( '(d) SEALS AT SYNC: every flush leaves the tail sector-aligned; pads are invisible to scans' , async ( ) = > {
const dir = trackDir ( )
const brain = track ( await openBrain ( dir ) )
await brain . add ( { id : uid ( 'seal-1' ) , data : 'one' , type : NounType . Document , vector : vec ( 10 ) , metadata : { } } )
await brain . flush ( )
const manifest = await readManifest ( brain )
const tailPath = path . join ( dir , . . . FACTS_DIR , manifest . tailSegment ! )
const sizeAfterFirstFlush = fs . statSync ( tailPath ) . size
expect ( sizeAfterFirstFlush ) . toBeGreaterThan ( 0 )
expect ( sizeAfterFirstFlush % 4096 , 'tail is sector-aligned after flush' ) . toBe ( 0 )
const countAfterFirstFlush = ( await factGenerations ( brain ) ) . length
for ( let i = 0 ; i < 3 ; i ++ ) {
await brain . add ( { id : uid ( ` seal-more- ${ i } ` ) , data : ` more ${ i } ` , type : NounType . Document , vector : vec ( 11 + i ) , metadata : { i } } )
}
await brain . flush ( )
const sizeAfterSecondFlush = fs . statSync ( tailPath ) . size
expect ( sizeAfterSecondFlush ) . toBeGreaterThan ( sizeAfterFirstFlush )
expect ( sizeAfterSecondFlush % 4096 , 'still aligned after more writes + flush' ) . toBe ( 0 )
// Pads count toward bytes, never toward facts.
expect ( ( await factGenerations ( brain ) ) . length ) . toBe ( countAfterFirstFlush + 3 )
} )
it ( '(e) REPLAY COMPAT: the log-authority recovery path resurrects an acked write from a v2 tail after a crash-style abandon' , async ( ) = > {
// The flip idiom from the log-authority suite: seed writes, baseline
// backfill LAST (the init-time VFS root never got a fact), flush, then
// the sanctioned guarded flip — the oracle goes green over an ALL-V2
// log, which is itself the reproduction proof for the v2 record path.
const dir = mkdtempSync ( join ( tmpdir ( ) , 'brainy-v2-cutover-' ) )
dirs . push ( dir )
process . env . BRAINY_DETERMINISTIC_EMBEDDINGS = 'true'
const open = async ( ) : Promise < Brainy > = > {
const b = new Brainy ( {
storage : { type : 'filesystem' , path : dir } ,
requireSubtype : false ,
silent : true ,
dimensions : 384
} )
await b . init ( )
return track ( b )
}
const brain = await open ( )
const kept = await brain . add ( { data : 'alpha document' , type : 'document' , metadata : { n : 1 } } )
const removed = await brain . add ( { data : 'beta document' , type : 'document' , metadata : { n : 2 } } )
await brain . update ( { id : kept , metadata : { n : 10 } } )
await brain . remove ( removed )
const root = await brain . get ( VFS_ROOT )
expect ( root , 'the VFS root exists' ) . toBeTruthy ( )
await brain . update ( { id : VFS_ROOT , metadata : root ! . metadata } ) // baseline backfill — final write
await brain . flush ( )
const report = await ( brain as unknown as { adoptLogAuthority ( ) : Promise < { verdict : string } > } ) . adoptLogAuthority ( )
expect ( report . verdict , 'the oracle is green over a pure-v2 log' ) . toBe ( 'green' )
// An at-ack write: its v2 fact is fsynced (sector-sealed) at ack.
const survivor = await brain . add ( {
data : 'survives power loss' ,
type : 'document' ,
metadata : { s : 1 }
} )
// Crash-style abandon: RAM state gone, no flush, no close.
await abandonAsCrashed ( brain )
// Reopen: open() finds the acked fact ABOVE the manifest watermark in
// the v2 tail (peekFactsAbove → v2 decode) and REPLAYS it into
// canonical — an acked write is never lost.
const reopened = await open ( )
expect (
( reopened as unknown as { logAuthority ( ) : { authority : string } } ) . logAuthority ( ) . authority
) . toBe ( 'log' )
const resurrected = await reopened . get ( survivor )
expect ( resurrected , 'the acked write survived the crash' ) . toBeTruthy ( )
expect ( ( resurrected as { metadata ? : { s? : number } } ) . metadata ? . s ) . toBe ( 1 )
expect ( ( await factGenerations ( reopened ) ) . length ) . toBeGreaterThan ( 0 )
} )
} )