fix: restore loadBinaryBlob fault-propagation (native column-store lockstep)

The Pass-1 hardening that makes loadBinaryBlob distinguish genuine absence
(ENOENT -> null) from a real fault (EIO/EACCES/... -> throw) was held out of
8.2.6 because the native accelerator's two column-store read sites still relied
on null-on-error. That accelerator release has now hardened those sites to
handle the throw (a faulted segment read marks the field unavailable and throws
a named error), so the fault-propagating form is restored and ships lockstep.

A present-but-unreadable index blob no longer masquerades as absent (which drove
needless rebuilds / empty reads). Adds the loadBinaryBlob leg to the blob
durability suite (absent -> null; present -> bytes; real fault -> throws).
This commit is contained in:
David Snelling 2026-07-13 12:09:55 -07:00
parent 76843b782e
commit b6c7039769
3 changed files with 65 additions and 19 deletions

View file

@ -10,6 +10,24 @@ Full auto-generated changelog: `CHANGELOG.md` · Releases: https://github.com/so
---
## v8.2.7 — 2026-07-13 (loadBinaryBlob fault-propagation — the lockstep completion of 8.2.6)
Completes the Pass-1 spine hardening. `loadBinaryBlob` (the raw-blob read a native accelerator mmaps
for its index files) previously returned `null` on ANY read error, so a real IO fault
(EIO/EACCES/EMFILE) on a present-but-unreadable index blob masqueraded as "the blob is absent" —
driving a needless full rebuild or an empty read. It now distinguishes genuine absence (ENOENT →
`null`, the documented contract) from a real fault (→ throw), so a transient disk fault surfaces
loudly instead of silently degrading the index.
This one change was deliberately held out of 8.2.6 and ships now, in lockstep with the native
accelerator release that hardened its two column-store read sites to handle the throw (a faulted
segment read marks the field unavailable and throws a named error, instead of relying on
null-on-error). A consumer on new brainy + an older accelerator was never at risk: 8.2.6 kept the
prior swallow-on-fault behavior for this method until the accelerator was ready.
No API change. Regression: `tests/unit/storage/blob-save-durability.test.ts` gains the loadBinaryBlob
leg (absent → null; present → bytes; real fault → throws).
## v8.2.6 — 2026-07-13 (write/index-spine hardening — loud errors, never quiet losses)
Durability + integrity hardening across the write and index paths. Every fix converts a place that