fix(log): acked writes survive power loss; rejected writes never silently commit — the kill-matrix goes 11/11 with zero .fails debt
Two release-blocking findings from the durability kill-matrix, both fixed
in the owning layer:
1. LOG-AUTHORITY REPLAY AT OPEN: durable-at-ack fsynced the fact before
the ack, but open() truncated every fact above the manifest — after a
power loss that takes the un-fsynced tmp+rename canonical bytes, the
acked write's ONLY durable copy was discarded. Now: under 'log'
authority, open() REPLAYS intact facts above the manifest into
canonical (FactLog.peekFactsAbove — CRC-gated, order-sorted) and
advances the manifest to cover them; tree-authority brains keep the
truncate contract they were promised. Pinned end to end: the power-loss
row constructs the exact disk state (fsynced log, vanished canonical
rename) and the acked write lives.
2. NO SILENT COMMIT: commitSingleOp buffered the generation BEFORE the
fact append; an append failure (ENOSPC) rejected the caller but the
next flush durably committed the generation with NO fact — a permanent
silent log gap. Now the failure path un-buffers and returns the counter
reservation: nothing commits, the log stays gap-free, and the canonical
execute-residue orphan is the documented crash-equivalent.
Plus: the kill-matrix itself (11 rows — every commit-path fault point ×
reopen-as-crash recovery contract, at-ack variants, disk-full row; five
new zero-cost faultPoint sites), the log-authority pin suite (oracle
green/red/state-differs, flip refusal, switch survives reopen, 9/9), and
the group-commit covering pins (5/5).
Gates: unit 2002/2002 (152 files) · integration 785 · conformance 27/27.
2026-08-10 09:29:21 -07:00
/ * *
* @module tests / unit / db / fact - log - group - sync
* @description Group commit on the fact log — the covering guarantee behind
* durable - at - ack : concurrent callers of ensureSynced ( ) share ONE covering
* fsync ( running + queued slots ) , a caller appending during a running sync
* joins a sync that STARTS after its append ( never the possibly - stale running
* one ) , a solo writer syncs immediately , and at the brain level an at - ack
* ack resolving means the write ' s fact is on disk .
*
feat(log): log authority is the fleet default — adopt-at-open, oracle-gated; plus the power-cut throw-site cures and the loud torn-record contract
THE DEFAULT FLIP (ruled on proven evidence — at-ack survived 301/301
acked-writes-through-power-cut in block-layer fault injection; deferred
tree authority demonstrably loses flush-covered acks): a brain with NO
stored authority artifact now ADOPTS LOG AUTHORITY AT OPEN. The oracle
gates the flip exactly as the guarded adoption path always did — curable
divergences baseline-backfilled, the flip lands ONLY on a green verdict —
and a brain that cannot verify STAYS tree-authoritative loudly, with the
refusal recorded on the switch artifact so subsequent opens are cheap.
config logAuthority: 'defer' is the explicit documented opt-out (no
automatic adoption; declared flush-window loss; adoptLogAuthority() flips
later). A stored artifact always wins. RELEASES.md carries the posture.
Two standing .fails debt pins FLIP TO HOLDING under the default: the
at-ack crash-survival gap and the ack-at-log durability target — both now
permanent asserted truths, not aspirations.
POWER-CUT THROW SITES (fault-injection findings, brainy-alone config):
- A manifest-listed-but-unloadable column segment QUARANTINES at
discovery (loud once, counted always, quarantinedSegments() exposed for
the heal) and the field serves its remaining segments DEGRADED — never
a raw throw killing every query on the field. Real storage faults still
propagate untouched.
- Torn generation artifacts (NaN/garbage in manifest or counter) DISCARD
with narration at the store's open and recovery re-derives — plus a
defensive finite-integer guard at the init consumer. Never a RangeError
killing an open.
THE LOUD TORN-RECORD CONTRACT: an existing-but-unparseable stored record
now surfaces as a typed, counted TornRecordError on every entity-read
surface (including fifteen previously-blind per-item batch catches);
ENOENT stays clean-absent; artifact readers with designed absent-recovery
keep null-tolerance behind the loud floor. Disk corruption can no longer
read as silent data invisibility.
Suite migration: the default's pins inverted deliberately, generation
baselines made relative, quarantine-contract pins rewritten to the ruled
behavior.
Gates: tsc 0 · unit 2065/2065 (159 files) · integration 826 (93 files) ·
conformance 31/31 · kill-matrix 15/15 · torn-open guards 2/2.
2026-08-11 08:37:38 -07:00
* The final pin holds the at - ack durability contract END TO END : an acked
* write ' s fact survives a crash - shaped reopen . This was a ` .fails ` known
* gap ( FactLog . open ( ) truncated every fact beyond the committed watermark ,
* which only advances at the pending - tier flush ) — CURED by the 10.0 . 0
* adopt - at - open fleet default : a fresh brain stores the log - authority
* artifact at open , and under 'log' authority recovery REPLAYS intact
* facts above the manifest instead of truncating them .
fix(log): acked writes survive power loss; rejected writes never silently commit — the kill-matrix goes 11/11 with zero .fails debt
Two release-blocking findings from the durability kill-matrix, both fixed
in the owning layer:
1. LOG-AUTHORITY REPLAY AT OPEN: durable-at-ack fsynced the fact before
the ack, but open() truncated every fact above the manifest — after a
power loss that takes the un-fsynced tmp+rename canonical bytes, the
acked write's ONLY durable copy was discarded. Now: under 'log'
authority, open() REPLAYS intact facts above the manifest into
canonical (FactLog.peekFactsAbove — CRC-gated, order-sorted) and
advances the manifest to cover them; tree-authority brains keep the
truncate contract they were promised. Pinned end to end: the power-loss
row constructs the exact disk state (fsynced log, vanished canonical
rename) and the acked write lives.
2. NO SILENT COMMIT: commitSingleOp buffered the generation BEFORE the
fact append; an append failure (ENOSPC) rejected the caller but the
next flush durably committed the generation with NO fact — a permanent
silent log gap. Now the failure path un-buffers and returns the counter
reservation: nothing commits, the log stays gap-free, and the canonical
execute-residue orphan is the documented crash-equivalent.
Plus: the kill-matrix itself (11 rows — every commit-path fault point ×
reopen-as-crash recovery contract, at-ack variants, disk-full row; five
new zero-cost faultPoint sites), the log-authority pin suite (oracle
green/red/state-differs, flip refusal, switch survives reopen, 9/9), and
the group-commit covering pins (5/5).
Gates: unit 2002/2002 (152 files) · integration 785 · conformance 27/27.
2026-08-10 09:29:21 -07:00
* /
import { describe , it , expect , beforeEach , afterEach } from 'vitest'
import { mkdtempSync , rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { Brainy } from '../../../src/index.js'
import { FileSystemStorage } from '../../../src/storage/adapters/fileSystemStorage.js'
import {
FactLog ,
storageSupportsFactLog ,
type CommitFact ,
type FactLogStorage
} from '../../../src/db/factLog.js'
const UUID = ( n : number ) : string = >
` 00000000-0000-4000-8000- ${ String ( n ) . padStart ( 12 , '0' ) } `
const fact = ( generation : number ) : CommitFact = > ( {
generation ,
timestamp : 1_700_000_000_000 + generation ,
ops : [
{
kind : 'noun' ,
id : UUID ( generation ) ,
record : { metadata : { noun : 'document' , title : ` doc ${ generation } ` } , vector : { v : [ 1 , 2 ] } }
}
]
} )
/** Scan every fact from a FRESH reader log over the same directory. */
async function readBack ( dir : string , committedHead : number ) : Promise < CommitFact [ ] > {
const storage : any = new FileSystemStorage ( dir )
await storage . init ( )
const reader = new FactLog ( storage as FactLogStorage )
await reader . open ( committedHead )
const facts : CommitFact [ ] = [ ]
const scan = reader . scanFacts ( )
for await ( const batch of scan . batches ( ) ) facts . push ( . . . batch . facts )
return facts
}
describe ( 'fact log group commit — the covering fsync' , ( ) = > {
let dir : string
let storage : any
let log : FactLog
beforeEach ( async ( ) = > {
dir = mkdtempSync ( join ( tmpdir ( ) , 'brainy-group-sync-' ) )
storage = new FileSystemStorage ( dir )
await storage . init ( )
expect ( storageSupportsFactLog ( storage ) ) . toBe ( true )
log = new FactLog ( storage as FactLogStorage )
await log . open ( 0 )
} )
afterEach ( ( ) = > {
rmSync ( dir , { recursive : true , force : true } )
} )
it ( 'many concurrent ensureSynced() callers share one covering fsync — every caller resolves, batching happened' , async ( ) = > {
for ( let g = 1 ; g <= 10 ; g ++ ) await log . append ( fact ( g ) )
// Count REAL fsync batches at the storage boundary, with a small delay so
// the concurrent callers genuinely overlap the running sync.
let fsyncBatches = 0
const origSync = storage . syncRawObjects . bind ( storage )
storage . syncRawObjects = async ( paths : string [ ] ) = > {
fsyncBatches ++
await new Promise ( ( r ) = > setTimeout ( r , 15 ) )
return origSync ( paths )
}
const callers = Array . from ( { length : 10 } , ( ) = > log . ensureSynced ( ) )
await Promise . all ( callers ) // every caller resolves — no lost writer
expect ( fsyncBatches , 'callers shared a covering fsync' ) . toBeLessThan ( 10 )
expect ( fsyncBatches ) . toBeGreaterThanOrEqual ( 1 )
// Durable: a fresh reader over the same directory sees all 10 facts.
const facts = await readBack ( dir , 10 )
expect ( facts . map ( ( f ) = > f . generation ) ) . toEqual ( [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] )
} )
it ( 'an append during a RUNNING sync is covered by a sync that starts after it — never the stale running one' , async ( ) = > {
for ( let g = 1 ; g <= 3 ; g ++ ) await log . append ( fact ( g ) )
// Gate the FIRST fsync so a sync is provably in flight.
let fsyncBatches = 0
let releaseGate ! : ( ) = > void
const gate = new Promise < void > ( ( r ) = > {
releaseGate = r
} )
let gated = true
const origSync = storage . syncRawObjects . bind ( storage )
storage . syncRawObjects = async ( paths : string [ ] ) = > {
fsyncBatches ++
if ( gated ) {
gated = false
await gate
}
return origSync ( paths )
}
const p1 = log . ensureSynced ( ) // sync A: snapshots gens 1..3, blocks in fsync
await new Promise ( ( r ) = > setTimeout ( r , 10 ) )
expect ( fsyncBatches , 'sync A is in flight' ) . toBe ( 1 )
await log . append ( fact ( 4 ) ) // lands AFTER sync A snapshotted
let p2Resolved = false
const p2 = log . ensureSynced ( ) . then ( ( ) = > {
p2Resolved = true
} )
// The covering guarantee: p2 must NOT resolve off the running sync (it
// may have snapshotted before the append) — it waits for the queued one.
await new Promise ( ( r ) = > setTimeout ( r , 25 ) )
expect ( p2Resolved , 'p2 never joins the possibly-stale running sync' ) . toBe ( false )
releaseGate ( )
await p1
await p2
expect ( p2Resolved ) . toBe ( true )
expect ( fsyncBatches , 'the queued covering sync ran after the running one' ) . toBe ( 2 )
// The late append is durable once p2 resolved.
const facts = await readBack ( dir , 4 )
expect ( facts . map ( ( f ) = > f . generation ) ) . toEqual ( [ 1 , 2 , 3 , 4 ] )
} )
it ( 'a solo writer syncs immediately — one fsync, and a dirty-free ensureSynced adds none' , async ( ) = > {
// Count only covering syncs: the first append itself fsyncs the tail
// manifest (the manifest-first flip), so instrument AFTER it.
await log . append ( fact ( 1 ) )
let fsyncBatches = 0
const origSync = storage . syncRawObjects . bind ( storage )
storage . syncRawObjects = async ( paths : string [ ] ) = > {
fsyncBatches ++
return origSync ( paths )
}
await log . ensureSynced ( )
expect ( fsyncBatches ) . toBe ( 1 )
// Nothing new appended: the covering sync finds nothing dirty.
await log . ensureSynced ( )
expect ( fsyncBatches ) . toBe ( 1 )
} )
} )
describe ( 'durable-at-ack through the brain (group commit end-to-end)' , ( ) = > {
const dirs : string [ ] = [ ]
const brains : any [ ] = [ ]
const openBrain = async ( dir? : string ) : Promise < { brain : any ; dir : string } > = > {
process . env . BRAINY_DETERMINISTIC_EMBEDDINGS = 'true'
const d = dir ? ? mkdtempSync ( join ( tmpdir ( ) , 'brainy-at-ack-' ) )
if ( ! dir ) dirs . push ( d )
const brain : any = new Brainy ( {
storage : { type : 'filesystem' , path : d } ,
requireSubtype : false ,
silent : true ,
dimensions : 384
} )
brains . push ( brain )
await brain . init ( )
return { brain , dir : d }
}
afterEach ( async ( ) = > {
for ( const b of brains . splice ( 0 ) ) await b . close ? . ( ) . catch ( ( ) = > { } )
for ( const d of dirs . splice ( 0 ) ) rmSync ( d , { recursive : true , force : true } )
} )
it ( 'at-ack: N concurrent add() acks all resolve, every ack was covered by a log sync, and every fact is on disk after reopen' , async ( ) = > {
const { brain , dir } = await openBrain ( )
feat(log): log authority is the fleet default — adopt-at-open, oracle-gated; plus the power-cut throw-site cures and the loud torn-record contract
THE DEFAULT FLIP (ruled on proven evidence — at-ack survived 301/301
acked-writes-through-power-cut in block-layer fault injection; deferred
tree authority demonstrably loses flush-covered acks): a brain with NO
stored authority artifact now ADOPTS LOG AUTHORITY AT OPEN. The oracle
gates the flip exactly as the guarded adoption path always did — curable
divergences baseline-backfilled, the flip lands ONLY on a green verdict —
and a brain that cannot verify STAYS tree-authoritative loudly, with the
refusal recorded on the switch artifact so subsequent opens are cheap.
config logAuthority: 'defer' is the explicit documented opt-out (no
automatic adoption; declared flush-window loss; adoptLogAuthority() flips
later). A stored artifact always wins. RELEASES.md carries the posture.
Two standing .fails debt pins FLIP TO HOLDING under the default: the
at-ack crash-survival gap and the ack-at-log durability target — both now
permanent asserted truths, not aspirations.
POWER-CUT THROW SITES (fault-injection findings, brainy-alone config):
- A manifest-listed-but-unloadable column segment QUARANTINES at
discovery (loud once, counted always, quarantinedSegments() exposed for
the heal) and the field serves its remaining segments DEGRADED — never
a raw throw killing every query on the field. Real storage faults still
propagate untouched.
- Torn generation artifacts (NaN/garbage in manifest or counter) DISCARD
with narration at the store's open and recovery re-derives — plus a
defensive finite-integer guard at the init consumer. Never a RangeError
killing an open.
THE LOUD TORN-RECORD CONTRACT: an existing-but-unparseable stored record
now surfaces as a typed, counted TornRecordError on every entity-read
surface (including fifteen previously-blind per-item batch catches);
ENOENT stays clean-absent; artifact readers with designed absent-recovery
keep null-tolerance behind the loud floor. Disk corruption can no longer
read as silent data invisibility.
Suite migration: the default's pins inverted deliberately, generation
baselines made relative, quarantine-contract pins rewritten to the ruled
behavior.
Gates: tsc 0 · unit 2065/2065 (159 files) · integration 826 (93 files) ·
conformance 31/31 · kill-matrix 15/15 · torn-open guards 2/2.
2026-08-11 08:37:38 -07:00
// The 10.0.0 fleet default already adopted log authority at open, so
// the brain is at-ack; the white-box engage stays so this pin holds the
// durability MACHINERY itself independent of the open-time posture.
fix(log): acked writes survive power loss; rejected writes never silently commit — the kill-matrix goes 11/11 with zero .fails debt
Two release-blocking findings from the durability kill-matrix, both fixed
in the owning layer:
1. LOG-AUTHORITY REPLAY AT OPEN: durable-at-ack fsynced the fact before
the ack, but open() truncated every fact above the manifest — after a
power loss that takes the un-fsynced tmp+rename canonical bytes, the
acked write's ONLY durable copy was discarded. Now: under 'log'
authority, open() REPLAYS intact facts above the manifest into
canonical (FactLog.peekFactsAbove — CRC-gated, order-sorted) and
advances the manifest to cover them; tree-authority brains keep the
truncate contract they were promised. Pinned end to end: the power-loss
row constructs the exact disk state (fsynced log, vanished canonical
rename) and the acked write lives.
2. NO SILENT COMMIT: commitSingleOp buffered the generation BEFORE the
fact append; an append failure (ENOSPC) rejected the caller but the
next flush durably committed the generation with NO fact — a permanent
silent log gap. Now the failure path un-buffers and returns the counter
reservation: nothing commits, the log stays gap-free, and the canonical
execute-residue orphan is the documented crash-equivalent.
Plus: the kill-matrix itself (11 rows — every commit-path fault point ×
reopen-as-crash recovery contract, at-ack variants, disk-full row; five
new zero-cost faultPoint sites), the log-authority pin suite (oracle
green/red/state-differs, flip refusal, switch survives reopen, 9/9), and
the group-commit covering pins (5/5).
Gates: unit 2002/2002 (152 files) · integration 785 · conformance 27/27.
2026-08-10 09:29:21 -07:00
brain . generationStore . setLogDurability ( 'at-ack' )
const factLog = brain . generationStore . getFactLog ( )
expect ( factLog ) . not . toBeNull ( )
let syncs = 0
const origSync = factLog . sync . bind ( factLog )
factLog . sync = async ( ) = > {
syncs ++
return origSync ( )
}
const ids : string [ ] = await Promise . all (
Array . from ( { length : 10 } , ( _ , i ) = >
brain . add ( { data : ` concurrent write ${ i } ` , type : 'document' , metadata : { i } } )
)
)
expect ( new Set ( ids ) . size , 'every ack resolved with a distinct id' ) . toBe ( 10 )
// Honest pin: single-op acks serialize under the commit mutex (append +
// covering sync run inside it), so concurrent add() acks do not currently
// share one fsync — cross-writer batching is the FactLog-layer property
// pinned above. What must hold here: at least one covering sync ran, and
// no ack resolved without the machinery engaged.
expect ( syncs ) . toBeGreaterThanOrEqual ( 1 )
expect ( syncs ) . toBeLessThanOrEqual ( 10 )
await brain . close ( )
const { brain : reopened } = await openBrain ( dir )
const scan = reopened . scanFacts ( )
expect ( scan ) . not . toBeNull ( )
const liveFactIds = new Set < string > ( )
for await ( const batch of scan ! . batches ( ) ) {
for ( const f of batch . facts ) {
for ( const op of f . ops ) if ( op . kind === 'noun' && op . record !== null ) liveFactIds . add ( op . id )
}
}
for ( const id of ids ) {
expect ( liveFactIds . has ( id ) , ` fact for acked write ${ id } survives reopen ` ) . toBe ( true )
}
} )
feat(log): log authority is the fleet default — adopt-at-open, oracle-gated; plus the power-cut throw-site cures and the loud torn-record contract
THE DEFAULT FLIP (ruled on proven evidence — at-ack survived 301/301
acked-writes-through-power-cut in block-layer fault injection; deferred
tree authority demonstrably loses flush-covered acks): a brain with NO
stored authority artifact now ADOPTS LOG AUTHORITY AT OPEN. The oracle
gates the flip exactly as the guarded adoption path always did — curable
divergences baseline-backfilled, the flip lands ONLY on a green verdict —
and a brain that cannot verify STAYS tree-authoritative loudly, with the
refusal recorded on the switch artifact so subsequent opens are cheap.
config logAuthority: 'defer' is the explicit documented opt-out (no
automatic adoption; declared flush-window loss; adoptLogAuthority() flips
later). A stored artifact always wins. RELEASES.md carries the posture.
Two standing .fails debt pins FLIP TO HOLDING under the default: the
at-ack crash-survival gap and the ack-at-log durability target — both now
permanent asserted truths, not aspirations.
POWER-CUT THROW SITES (fault-injection findings, brainy-alone config):
- A manifest-listed-but-unloadable column segment QUARANTINES at
discovery (loud once, counted always, quarantinedSegments() exposed for
the heal) and the field serves its remaining segments DEGRADED — never
a raw throw killing every query on the field. Real storage faults still
propagate untouched.
- Torn generation artifacts (NaN/garbage in manifest or counter) DISCARD
with narration at the store's open and recovery re-derives — plus a
defensive finite-integer guard at the init consumer. Never a RangeError
killing an open.
THE LOUD TORN-RECORD CONTRACT: an existing-but-unparseable stored record
now surfaces as a typed, counted TornRecordError on every entity-read
surface (including fifteen previously-blind per-item batch catches);
ENOENT stays clean-absent; artifact readers with designed absent-recovery
keep null-tolerance behind the loud floor. Disk corruption can no longer
read as silent data invisibility.
Suite migration: the default's pins inverted deliberately, generation
baselines made relative, quarantine-contract pins rewritten to the ruled
behavior.
Gates: tsc 0 · unit 2065/2065 (159 files) · integration 826 (93 files) ·
conformance 31/31 · kill-matrix 15/15 · torn-open guards 2/2.
2026-08-11 08:37:38 -07:00
// THE AT-ACK CONTRACT, HELD (was a `.fails` known gap): an acked write's
// fact survives a crash-shaped reopen. Fixed by the 10.0.0 adopt-at-open
// fleet default — this brain adopted LOG authority at open (artifact
// stored, durable-at-ack live), and under 'log' authority FactLog
// recovery REPLAYS intact facts above the committed watermark at the next
// open instead of truncating them back. Durable-at-ack now survives the
// very crash it exists for.
it ( 'at-ack CONTRACT: acked facts survive a crash-shaped reopen (no flush ever ran)' , async ( ) = > {
fix(log): acked writes survive power loss; rejected writes never silently commit — the kill-matrix goes 11/11 with zero .fails debt
Two release-blocking findings from the durability kill-matrix, both fixed
in the owning layer:
1. LOG-AUTHORITY REPLAY AT OPEN: durable-at-ack fsynced the fact before
the ack, but open() truncated every fact above the manifest — after a
power loss that takes the un-fsynced tmp+rename canonical bytes, the
acked write's ONLY durable copy was discarded. Now: under 'log'
authority, open() REPLAYS intact facts above the manifest into
canonical (FactLog.peekFactsAbove — CRC-gated, order-sorted) and
advances the manifest to cover them; tree-authority brains keep the
truncate contract they were promised. Pinned end to end: the power-loss
row constructs the exact disk state (fsynced log, vanished canonical
rename) and the acked write lives.
2. NO SILENT COMMIT: commitSingleOp buffered the generation BEFORE the
fact append; an append failure (ENOSPC) rejected the caller but the
next flush durably committed the generation with NO fact — a permanent
silent log gap. Now the failure path un-buffers and returns the counter
reservation: nothing commits, the log stays gap-free, and the canonical
execute-residue orphan is the documented crash-equivalent.
Plus: the kill-matrix itself (11 rows — every commit-path fault point ×
reopen-as-crash recovery contract, at-ack variants, disk-full row; five
new zero-cost faultPoint sites), the log-authority pin suite (oracle
green/red/state-differs, flip refusal, switch survives reopen, 9/9), and
the group-commit covering pins (5/5).
Gates: unit 2002/2002 (152 files) · integration 785 · conformance 27/27.
2026-08-10 09:29:21 -07:00
const { brain , dir } = await openBrain ( )
feat(log): log authority is the fleet default — adopt-at-open, oracle-gated; plus the power-cut throw-site cures and the loud torn-record contract
THE DEFAULT FLIP (ruled on proven evidence — at-ack survived 301/301
acked-writes-through-power-cut in block-layer fault injection; deferred
tree authority demonstrably loses flush-covered acks): a brain with NO
stored authority artifact now ADOPTS LOG AUTHORITY AT OPEN. The oracle
gates the flip exactly as the guarded adoption path always did — curable
divergences baseline-backfilled, the flip lands ONLY on a green verdict —
and a brain that cannot verify STAYS tree-authoritative loudly, with the
refusal recorded on the switch artifact so subsequent opens are cheap.
config logAuthority: 'defer' is the explicit documented opt-out (no
automatic adoption; declared flush-window loss; adoptLogAuthority() flips
later). A stored artifact always wins. RELEASES.md carries the posture.
Two standing .fails debt pins FLIP TO HOLDING under the default: the
at-ack crash-survival gap and the ack-at-log durability target — both now
permanent asserted truths, not aspirations.
POWER-CUT THROW SITES (fault-injection findings, brainy-alone config):
- A manifest-listed-but-unloadable column segment QUARANTINES at
discovery (loud once, counted always, quarantinedSegments() exposed for
the heal) and the field serves its remaining segments DEGRADED — never
a raw throw killing every query on the field. Real storage faults still
propagate untouched.
- Torn generation artifacts (NaN/garbage in manifest or counter) DISCARD
with narration at the store's open and recovery re-derives — plus a
defensive finite-integer guard at the init consumer. Never a RangeError
killing an open.
THE LOUD TORN-RECORD CONTRACT: an existing-but-unparseable stored record
now surfaces as a typed, counted TornRecordError on every entity-read
surface (including fifteen previously-blind per-item batch catches);
ENOENT stays clean-absent; artifact readers with designed absent-recovery
keep null-tolerance behind the loud floor. Disk corruption can no longer
read as silent data invisibility.
Suite migration: the default's pins inverted deliberately, generation
baselines made relative, quarantine-contract pins rewritten to the ruled
behavior.
Gates: tsc 0 · unit 2065/2065 (159 files) · integration 826 (93 files) ·
conformance 31/31 · kill-matrix 15/15 · torn-open guards 2/2.
2026-08-11 08:37:38 -07:00
expect ( brain . logAuthority ( ) . authority , 'the fleet default adopted at open' ) . toBe ( 'log' )
expect ( brain . generationStore . logDurability ) . toBe ( 'at-ack' )
fix(log): acked writes survive power loss; rejected writes never silently commit — the kill-matrix goes 11/11 with zero .fails debt
Two release-blocking findings from the durability kill-matrix, both fixed
in the owning layer:
1. LOG-AUTHORITY REPLAY AT OPEN: durable-at-ack fsynced the fact before
the ack, but open() truncated every fact above the manifest — after a
power loss that takes the un-fsynced tmp+rename canonical bytes, the
acked write's ONLY durable copy was discarded. Now: under 'log'
authority, open() REPLAYS intact facts above the manifest into
canonical (FactLog.peekFactsAbove — CRC-gated, order-sorted) and
advances the manifest to cover them; tree-authority brains keep the
truncate contract they were promised. Pinned end to end: the power-loss
row constructs the exact disk state (fsynced log, vanished canonical
rename) and the acked write lives.
2. NO SILENT COMMIT: commitSingleOp buffered the generation BEFORE the
fact append; an append failure (ENOSPC) rejected the caller but the
next flush durably committed the generation with NO fact — a permanent
silent log gap. Now the failure path un-buffers and returns the counter
reservation: nothing commits, the log stays gap-free, and the canonical
execute-residue orphan is the documented crash-equivalent.
Plus: the kill-matrix itself (11 rows — every commit-path fault point ×
reopen-as-crash recovery contract, at-ack variants, disk-full row; five
new zero-cost faultPoint sites), the log-authority pin suite (oracle
green/red/state-differs, flip refusal, switch survives reopen, 9/9), and
the group-commit covering pins (5/5).
Gates: unit 2002/2002 (152 files) · integration 785 · conformance 27/27.
2026-08-10 09:29:21 -07:00
// Crash simulation: the pending-tier durability flush never happens
// (every trigger routes through flushPendingSingleOps), and the brain is
// abandoned without close() — exactly the power-loss shape at-ack is for.
brain . generationStore . flushPendingSingleOps = async ( ) = > { }
const ids : string [ ] = [ ]
for ( let i = 0 ; i < 5 ; i ++ ) {
ids . push ( await brain . add ( { data : ` acked write ${ i } ` , type : 'document' , metadata : { i } } ) )
}
// No flush, no close — reopen the directory as a new session.
const { brain : reopened } = await openBrain ( dir )
const scan = reopened . scanFacts ( )
expect ( scan ) . not . toBeNull ( )
const liveFactIds = new Set < string > ( )
for await ( const batch of scan ! . batches ( ) ) {
for ( const f of batch . facts ) {
for ( const op of f . ops ) if ( op . kind === 'noun' && op . record !== null ) liveFactIds . add ( op . id )
}
}
for ( const id of ids ) {
expect ( liveFactIds . has ( id ) , ` acked fact ${ id } survives the crash-shaped reopen ` ) . toBe ( true )
}
} )
} )