Correctness
A backup is only useful if you can restore it, and if the restored database is actually correct. bakelite checks that with a torture harness: it drives a marked, self-checking workload that records a ground-truth commit history, then grades each restore against it — latest or any point in time — under injected backend faults and hard kills.
The correctness bar. Every restore is held to a self-checking oracle — no externally stored fingerprints. It must hold that:
- the restored file passes
PRAGMA integrity_check - its marker and log form the gap-free committed prefix {1..=seq} — no holes, no future rows
- its contents hash (BLAKE3 over every user table) to the digest the workload recorded at that commit
- the landed commit is one the workload really made — never a fabricated or torn boundary
- the durability floor holds: exact after a clean stop, and never below the last durable commit after a crash
- point-in-time targets land on monotonically non-decreasing commits
Graded under. The same marked workload, run through each of these adversities and graded by that oracle:
| Adversity | How it's exercised |
|---|---|
Marked workload — randomized commits, overflow-page blobs, periodic VACUUM | the workload every scenario records and replays |
| Clean quiescent drain, then restore must be exact | drain(), then an exact-restore assertion |
| Unsynced window — commits made after the last sync, before the process dies | the durability floor must hold across the gap |
| SIGKILL of the live daemon under write load | a real bakelite daemon killed mid-write, then resumed |
| Transient backend errors and full outages | injected at the in-process backend trait and graded for survival |
| Crash mid-operation — mid-compaction, between a write and its manifest, mid-delete | the fsync'd local cursor (not the manifest) is authoritative, so a crash between any two writes reconciles cleanly |
| WORM / S3 Object Lock immutability | exercised through the backend trait and its retention/compaction |
| At-rest encryption — encrypt legacy data, rotate keys, crash mid-rewrite | the reencrypt path driven under crashes |
| Multi-destination fan-out with asymmetric per-destination faults | N destinations written in lock-step, with faults injected per destination |
Generated by just correctness-regen — not hand-edited.
What the coverage means
The oracle uses no externally stored fingerprints: the workload records its own ground truth, and a restore has to reproduce it exactly. The harness also includes a red-path self-test that corrupts the replica and expects the oracle to reject it, which confirms a passing check is one that could have failed.
The per-object segments, the advisory manifest, and the tip pointer are what let bakelite ship incrementally — doing work only when the WAL changes — and mirror to a second backend up to a fully-restorable point. They also create extra crash windows. Restore reconciles against the objects: what's restorable is whatever gap-free chain of objects actually exists on the backend, re-derived by listing, so a lost or stale pointer costs nothing. The fsync'd local cursor only governs what the daemon ships next, and the manifest is a rebuildable cache. Every one of those windows is exercised above.
How this page is generated
The matrix is generated from the harness inventory by just correctness-regen
(never hand-edited). When the torture suite gains or drops an adversity, the page is
regenerated to match.