mirror of
https://github.com/block/buzz.git
synced 2026-10-29 05:21:31 +00:00
CRITICAL 1 (C1): restored replay must carry original queuedAt age.
- WholeBlobSyncManager.publish() now takes restoredQueuedAt param;
pendingRestoredQueuedAt drives the adopt-guard in
fetchOwnBlobBeforePublish (publish when remote.createdAt <=
restoredQueuedAt; adopt when strictly newer). writeOutbox called
with original queuedAt so on-disk stamp is never reminted.
- channelSectionsSync/channelSortSync publishSections/publishSortPrefs
accept and thread restoredQueuedAt through to publish().
- channelSectionsStorage/channelSortPreference writeOutbox signatures
updated to accept optional nowSecs override.
- Hook-layer tests in runWholeBlobCarlSuite use the actual React hook
(renderHook), driving the real bootstrap .then() callback, outbox
read, queuedAt, and shouldReplay guard.
CRITICAL 2 (C2): successful-bootstrap replay needs a baseline.
- bootstrap() snapshots the fetched head to this.bootstrapResultHead
before returning. publish(_, true) uses canonicalMax(current,
bootstrapResultHead) so a no-prior-pending restored replay gets the
correct baseline from the immutable bootstrap snapshot rather than
the mutable lastRemoteHead (which may carry a suppressed live peer
head H102 that must remain a genuine advance).
- New runWholeBlobC2Suite (manager layer) drives publish(_, true,
undefined) so C1's queuedAt guard is disabled and only C2's
bootstrapResultHead mechanism can prevent the adopt.
CRITICAL 3 (C3): confirmRetainedHead decrypt gap.
- For a foreign winner, lastRemoteHead is advanced only AFTER
decryptAndParse succeeds (mirrors fetchRemoteBlob fix). A click
arriving during the confirm decrypt gap now sees lastRemoteHead as
{0,""} (or the pre-confirm value) and correctly adopts the foreign
winner rather than publishing over it.
- New runWholeBlobC3Suite (manager layer) gates the first decrypt call
and injects a click during the gap; asserts publishCalls === 1.
CRITICAL 4 (C4 / P3-reclaim): reclaimSubsumedOutbox drops preservedKey.
- mergeLaneStorage.shared.ts reclaimSubsumedOutbox signature updated
to accept optional preservedKey; calls isSubsumedBy(record.store,
head, record.preservedKey) so a capacity-bounded proof can never
evict the reserved channel and falsely certify retention.
- New P3-reclaim tests (already in mergeLaneSyncCarl.shared.test.mjs)
exercise 500-entry relay head + foreign outbox with clicked channel
absent; mutation (drop preservedKey) → record deleted → test red.
IMPORTANT: test coverage.
- P1/C1 hook tests now drive renderHook with the real outbox read,
queuedAt threading, shouldReplay guard, and bootstrap .then()
callback (not manager.publishReplay directly).
- P3-ack fixture clock set to t=1s so clicked channel is the
lexicographically evicted entry at 501-entry capacity, making the
pendingPreservedKey-drop mutation genuinely causal (2 red).
- All 6 named mutations verified red on exactly their tests, green
on fixed source: C1 (2r), C2 (2r), C3 (2r), C4/P3-reclaim (2r),
P3-ack (2r), P2a-1 (2r), P2b (2r). 57/57 pass on fixed source.
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Buzz
Desktop chat shell with:
- Tauri + React + TypeScript + Vite
- Tailwind CSS
- shadcn/ui-ready shared components
- Biome (lint/format/check)
- Feature-driven frontend structure
Scripts
pnpm dev- run the web frontendpnpm tauri dev- run the desktop apppnpm build- typecheck and build frontendpnpm typecheck- TypeScript checkspnpm lint- Biome lintpnpm format- Biome format (write)pnpm check- Biome check
Structure
src/shared- reusable app-wide code (ui,lib,styles)src/features- feature modules (vertical slices)src/app- top-level app composition