fix(recovery): the fold streams and narrates; the checkpoint chain arms at the flip
All checks were successful
CI / Node 22 (push) Successful in 12m13s
CI / Node 24 (push) Successful in 12m9s
CI / Integration + conformance (Node 22) (push) Successful in 18m16s
CI / Bun (latest) (push) Successful in 12m20s

A production brain's first process boot after a live authority flip looked
hung and was restarted three times mid-recovery — three defects with one
scene. (1) THE FOLD MATERIALIZED THE LOG: peekFactsAbove(0) decoded every
fact into one array (GBs of after-images on a ~7k-fact log, a GC storm, a
starved write lane). The fold now STREAMS one segment-batch at a time —
memory is one segment at any log size — with structural ordering asserted
loudly. (2) THE FOLD WAS SILENT UNTIL DONE: minutes of boot work with zero
narration is what invited the restarts. It now announces itself BEFORE the
work ('do not restart, the fold is finite') and prints progress every
thousand facts. (3) THE CHAIN COULD ONLY ARM AT A CRASH: a live mid-session
flip left the fold checkpoint unfounded, so the brain's first unclean boot
paid a whole-log fold. Adoption now founds the checkpoint AT THE FLIP — one
paged full canonical barrier (bounded memory), then the stamp — so bounded
recovery holds from minute zero for every store that flips, at any size.

Pinned: a non-fresh flip stamps immediately; the first post-flip unclean
boot folds bounded (an unflushed at-ack fact above the checkpoint is
restored; a barrier-covered row below it is outside the fold). Kill matrix
and both adoption suites green alongside.
This commit is contained in:
David Snelling 2026-08-18 12:53:50 -07:00
parent 8fb6cb7e54
commit ed7d1db97e
4 changed files with 215 additions and 33 deletions

View file

@ -161,6 +161,38 @@ describe('fold-checkpoint bound — crash recovery folds (checkpoint, head], nev
expect(stamped, 'the first whole-log fold is the chains base case — it stamps').toBe(committedOf(reopened))
}, 120000)
it('ARM-AT-FLIP: a non-fresh adoption founds the checkpoint immediately — the first post-flip boot folds BOUNDED, never whole-log', async () => {
const dir = trackDir()
// The production shape: a brain with history flips LIVE (no crash ever).
const brain = await openBrain(dir, { logAuthority: 'defer' })
liveBrains.push(brain)
const preFlip = await brain.add({ data: 'pre-flip resident', type: NounType.Document, metadata: { era: 'tree' } })
await brain.flush()
expect(readCheckpoint(dir), 'no checkpoint before the flip').toBeNull()
const report = await brain.adoptLogAuthority()
expect(report.verdict).toBe('green')
// THE PIN: the flip itself founded the checkpoint — no crash required.
const founded = readCheckpoint(dir)
expect(founded, 'checkpoint founded at flip').toBe(committedOf(brain))
// First post-flip boot, unclean (the production first-restart shape):
// a post-flip write above the checkpoint is restored FROM ITS AT-ACK FACT
// (deliberately NOT flushed — a flush would barrier-sync it and advance
// the stamp over it, making its loss synthetic); the pre-flip row (its
// baseline fact ≤ checkpoint, its bytes barrier-synced at the flip) is
// OUTSIDE the fold — vaporizing it synthetically proves the bound.
const postFlip = await brain.add({ data: 'post-flip write', type: NounType.Document, metadata: { era: 'log' } })
await abandonAsCrashed(liveBrains.pop()!)
dropCanonicalNoun(dir, preFlip)
dropCanonicalNoun(dir, postFlip)
const reopened = await openBrain(dir, { logAuthority: 'adopt' })
liveBrains.push(reopened)
expect(await reopened.get(postFlip), 'above-checkpoint fact re-applied').not.toBeNull()
expect(await reopened.get(preFlip), 'below-checkpoint fact skipped — the fold is bounded on the FIRST post-flip boot').toBeNull()
}, 240000)
it('a tree-authority brain never stamps a checkpoint', async () => {
const dir = trackDir()
const brain = await openBrain(dir, { logAuthority: 'defer' })