It cannot, today. The probe is committed so that stays checkable.
The bug is real and it IS in the version we ship: verified against our own
installed hypercore 11.26.0 that `deriveKeys` returns `{ blinding, block }`
while `_reload` reads `keys.blockKey` / `keys.blindingKey`, so both land
`undefined` and the core's cipher is destroyed - and `_reload` never updates
`this.compat`, so it re-fires on every subsequent block. The recorded range of
11.29.0-11.35.0 was therefore too narrow; 11.26.0 has it too.
But PearCal never instantiates that class. Autobase supplies its own encryption
(autobase/lib/encryption.js: ViewEncryption / WriterEncryption), and its compat
path reads `this.compat.block` / `.blinding` - the property names deriveKeys
actually returns - so it is correct where hypercore's is not. It also computes
compat keys once behind `if (!this.compat)` rather than re-deriving on a flip.
PearCal only ever passes an encryption key to the Autobase constructor
(bare.js:2314), never to a Hypercore or store.get() directly; the blind seeder
opens cores with no key at all, and the personal base is built without one.
Measured rather than argued: instrumenting the class prototype (shared by every
instance whichever module reference constructed it) and driving a real
encrypted group through a real worklet - create, three writes, read back -
gives reloads 0, encrypts 0, decrypts 0.
That verdict is a property of how we wire things up, not a guarantee from
upstream, and an innocent change would silently undo it - encrypting the local
DB or the personal base, or passing a key to a core directly, would each make
the broken class live again. So this ships as a tool to re-run after any
hypercore or autobase bump, or after changing how cores are opened. It exits
non-zero if the class is ever in use, so it can be wired into a check later.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEd2k9F1HgR3JHdB8spury