feat: provider access to the fact log + shared stamp verifier via internals

Three additive surfaces for native index providers, which hold only
`storage` and must never construct their own fact-log reader (the log's
open path is writer-side — it reconciles by truncating/rewriting):

- Fact-scan capability on the storage adapter (the getBinaryBlobPath
  pattern): the host brain wires a closure over its LIVE fact log at
  init; providers call storage.scanFacts()/factLogHeadGeneration()/
  factSegmentPaths() and fall back to the enumeration walk on null.
  Restore/reopen swaps the underlying log transparently.
- The family-stamp trio (readFamilyStamp/writeFamilyStamp/
  verifyFamilyStamp + types) exported from @soulcraft/brainy/internals,
  so 'one verifier' is literally one function shared with the native
  side, never two synchronized copies.
- Rollup invariants widened to number|string: content fingerprints
  (e.g. a per-tree SHA-256) are valid invariant values; strict equality
  either way, and a type mismatch reads as incoherence, never a pass.
This commit is contained in:
David Snelling 2026-07-15 12:36:27 -07:00
parent 70886da548
commit 352e356fd5
7 changed files with 153 additions and 3 deletions

View file

@ -999,6 +999,17 @@ export class Brainy<T = any> implements BrainyInterface<T> {
})
}
// Fact-scan capability: wire the storage seam through which index
// providers (which hold only `storage`) reach the fact log. A closure
// over the LIVE log — restore/reopen swaps the instance transparently —
// so a provider's heal can switch from the enumeration walk to one
// sequential fact scan whenever the log exists.
if (typeof (this.storage as BaseStorage).setFactScanSource === 'function') {
;(this.storage as BaseStorage).setFactScanSource(
() => this.generationStore?.getFactLog() ?? null
)
}
// Entity-tree stamp coherence: compare the stamped sourceGeneration +
// rollup invariants against the log head + live counters. Loud on
// genuine incoherence (repairIndex heals), silent on absent/coherent,