OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-proto-peer commits / 9a5eb37

resync: record why setLocal cannot replace the side Corestore
autobase exposes an undocumented setLocal(key,{keyPair}) writer rotation that looks like it should collapse this whole apparatus — rotate onto a fresh keypair in place, drop the side store and the _sideStore.replicate ordering in bootMultiDevice. Characterized against autobase 7.28.1: it does not work here. LocalState.moveTo copies the linearizer updates and the boot record onto the new writer (so it is not the clean slate a fresh primaryKey gives, and the stale view cores stay), it asserts when the writer is an indexer — which a poisoned creator always is — and it de-admits anyway, so an indexer still has to addWriter the new key. Comment only; no behaviour change. The point is that the next reader who spots setLocal does not spend a day rediscovering this. Evidence in pear-git#35. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9a5eb374948ae6381b6518f3f5f2c3d256681811
by plankatron <fleeky@gmail.com> · 2026-08-13T03:23:55.000Z

Changed files (1) +17 -0

lib/device-node.js +17 -0
……@@ -619,6 +619,23 @@ export async function bootSwarmDevice ({ storage, deviceMnemonic, did, signingKe
619619// per-repo forceResync). resyncDid() BUMPS the gen; the daemon reopens on next boot — a poisoned base
620620// can't be live-closed (it aborts on apply), so boot-reopen (never opening the poisoned base) is the
621621// correct shape. Nothing is deleted: the old poisoned cores stay on disk in the shared store.
622//
623// ⛔ DO NOT "SIMPLIFY" THIS INTO autobase's setLocal(key,{keyPair}) WRITER ROTATION. That undocumented
624// API (autobase/index.js:489) looks like it should replace the whole second-Corestore apparatus below —
625// rotate onto a fresh keypair in place, drop the side store, drop the _sideStore.replicate ordering in
626// bootMultiDevice. Characterized against 7.28.1 (2026-08-12) and it does NOT work here, for three
627// independent reasons:
628// 1. NOT A CLEAN SLATE. _rotateLocalWriter calls LocalState.moveTo(old,new), which copies the
629// linearizer updates AND the autobase/boot record onto the new writer, and the base stays in the
630// same store with its stale view cores. The fresh primaryKey is the whole point of a side store.
631// 2. IT ASSERTS ON AN INDEXER. _rotateLocalWriter nulls localWriter before _updateLinearizer calls
632// _clearLocalIndexer, which asserts localWriter !== null — a bare AssertionError with an EMPTY
633// message, leaving a half-rotated base. A poisoned node is usually the creator, i.e. the sole
634// indexer. Even with that fixed, rotating the sole indexer leaves the room with ZERO indexers.
635// 3. IT DE-ADMITS ANYWAY. The rotated key is not in the writer set, so an indexer still has to
636// addWriter it — the same online-indexer dependency the fresh-corestore re-join already has.
637// So the second Corestore + the side-store replication ordering are load-bearing, not incidental.
638// Evidence + probes: memory/reference_autobase-setlocal-writer-rotation, pear-git#35.
622639const RESYNC_DIR = 'statebase-resync'
623640const did16For = (did) => b4a.toString(crypto.hash([NS('room-key'), b4a.from(did)]), 'hex').slice(0, 16)
624641