docs: external-backups/sparse-storage guide + generation fact log concept

- New public guide (guides/external-backups): the sparse-mmap reality
  for external backup tooling — why a brain directory can show 100+ GB
  apparent size on a small disk, which files are sparse, tar czSf /
  rsync --sparse / cp --sparse=always, live-store caveats, and what
  persist()/restore() already handle natively.
- New public concept (concepts/generation-fact-log): what facts are
  (after-image commit records, body-less tombstones), the crash-safety
  model (checksummed frames, reconcile-to-committed, absent = never
  committed), the scanFacts()/factSegmentPaths() surfaces with the
  telemetry shape, family stamps + open-time coherence, and the
  storage capability seam for plugin authors.
- Cross-link from the snapshots guide; sparse notes added to the
  public persist()/restore() JSDoc (the operator-facing sites).
This commit is contained in:
David Snelling 2026-07-16 10:30:32 -07:00
parent d60619c83b
commit 593bb8b0f9
5 changed files with 236 additions and 0 deletions

View file

@ -8280,6 +8280,14 @@ export class Brainy<T = any> implements BrainyInterface<T> {
* replacement. Release them first; a warning is logged when live pins
* exist.
*
* NON-DESTRUCTIVE STAGING + SPARSE-AWARE: the snapshot is copied into a
* staging area BEFORE any live data is touched (all-zero blocks stay
* holes, so a sparse mmap store restores at its true allocated size not
* its apparent size). Any copy failure, ENOSPC included, removes only the
* staging and throws; the live store is untouched. Only after the copy
* succeeds does an atomic per-entry swap move it into place; a crash
* mid-swap completes FORWARD on the next open.
*
* @param path - Snapshot directory to restore from.
* @param options - Must be `{ confirm: true }` an explicit acknowledgment
* that current state is destroyed.

View file

@ -945,6 +945,13 @@ export class Db<T = any> {
* {@link SpeculativeOverlayError} (commit them with `brain.transact()`
* first).
*
* SPARSE FILES: a native accelerator's mmap index files can be sparse
* huge apparent size, small allocated size. `persist()` handles them
* correctly (hard links share the allocation). But if you then archive the
* snapshot with EXTERNAL tools, use the sparse-aware flags (`tar czSf`,
* `rsync --sparse`, `cp --sparse=always`) or the copy materializes every
* hole see docs/guides/external-backups-and-sparse-storage.md.
*
* @param path - Absolute directory for the snapshot (created; must be
* empty or absent).
* @throws GenerationConflictError when this view is no longer the latest