mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Closes all 7 IMPORTANT + 2 MINOR findings from Thufir pass-1. Core changes: - Consolidate pending-intents storage into override-state.v2 blob (Paul's design ruling). Single write point for registers, receipts, and intents eliminates the double-commit window; no migration needed since pending-intents.v1 never shipped. - Implement retryLoad() single-flight controller: bounded exponential backoff (1s->2s->4s...60s cap), reconnect coalescing into pendingRetryOnComplete, destroy/identity cancellation, retryAttempt reset on complete verdict. - sourceScope + readTarget captured in enqueue path so drain performs exact source cleanup at the correct frontier position. - refused-unread rollback: snapshot prior forced-unread entry before ordered write; restore exact snapshot on refusal; delete only when no prior existed. - Surfaced drain outcomes via onDrainOutcome hook; genuine refusals (uint32_overflow, budget_exhausted, storage_failed) trigger toast; already_inactive is silent success; load_incomplete never surfaces. - Cleanup atomicity: intent + receipt deleted in a single persistLocalState() call (one v2 blob write) so they are never observable separately. - createDrainContext typed factory replaces this-as-unknown-as-DrainContext cast. - NIP-RS.md: added normative refusal-reason vocabulary list. Biting witnesses added (readStateManager.test.mjs, +12 tests): - Amendment A: gen2 enqueued mid-replay, gen1 register rolled back - Both inversion directions (unread->read, read->unread in-flight) - compare-delete preserves newer intent - Amendment C via production fetchAndMerge load path (not direct register write) - Atomic intent+receipt deletion witness - Controller: automatic backoff, reconnect during loadInFlight, stale-gen ordering - Controller: destroy-with-timer, exactly-one-drain-per-generation - Store/UI: identity-swap-during-drain, deferred refusal surfaces outcome Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>