Files
buzz/desktop
Duncan 77d88875fd fix(sidebar-sync): correct P1 guard shape; add P3 reconnect/remount preservation; causal tests
P1 guard shape fix (both whole-blob hooks):
- Was: reduce all non-apply-remote paths to headCreatedAt=0, gate on queuedAt>0
- Now: branch on bootstrap result explicitly
  - hold/absent/failed (result.action !== 'apply-remote'): always replay,
    including legacy queuedAt=0 records (old 0>0 guard silently stranded them)
  - apply-remote: suppress only on strict queuedAt < appliedHead.createdAt;
    equality replays (aligns with reclamation's strict-lt, prevents stranding
    a same-second edit neither consumed nor published)
- Documents clock-skew residual: queuedAt vs relay created_at are independent
  wall clocks — accepted tradeoff of the existing LWW max-merge strategy

P3 reconnect preservation (MergeLaneSyncManager + both stars/mutes hooks):
- Add retryReconnectPublish() to MergeLaneSyncManager: re-drives the existing
  generation without calling publish(), so pendingPreservedKey is not reset
- Expose retryReconnectStarsPublish() / retryReconnectMutesPublish() on adapters
- Switch both hooks' reconnect effects to retryReconnectPublish() instead of
  publishStars/Mutes(pending), which would open a new generation and clear key
- Clear pendingPreservedKey in destroy()

P3 remount preservation (storage layer + both hooks):
- writeOwnOutbox: accept optional preservedKey, include in envelope JSON
- parseEnvelope: read preservedKey from envelope; OutboxRecord gains field
- enumerateOutbox: propagate preservedKey into OutboxRecord
- mergeLaneStorage.shared: writeOutbox forwards preservedKey; add
  readOutboxPreservedKey to read own-window record's key for bootstrap
- channelStarsStorage / channelMutesStorage: accept+forward preservedKey in
  write, expose readChannelStarsOutboxPreservedKey / readChannelMutesOutboxPreservedKey
- MergeLaneSyncManager: writeOutbox config type includes preservedKey param;
  publish() forwards it to config.writeOutbox
- useChannelStars / useChannelMutes: import and call readPreservedKey on
  bootstrap outbox replay; pass to publishStars/Mutes alongside the store

Causal test coverage:
- wholeBlobHook.shared: replace non-causal stale-replay test with four-case
  P1 regression using makeHookTimerBed.hasDelay(2000) as the synchronous
  causal signal (timer present iff publish() called): strict-lt suppresses,
  equality replays, hold+v2 replays, hold+legacy-queuedAt=0 replays
- channelStarsSync.test: add P3 reconnect (retryReconnectStarsPublish keeps
  key) and P3 remount (storage round-trip write+read preservedKey)
- channelMutesSync.test: add matching P3 501-entry, reconnect, and remount
  regressions parameterizing coverage across both lanes

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-09-02 14:04:36 -04:00
..
…

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 frontend
  • pnpm tauri dev - run the desktop app
  • pnpm build - typecheck and build frontend
  • pnpm typecheck - TypeScript checks
  • pnpm lint - Biome lint
  • pnpm 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