Skip to content

Restore sidebar locally before network discovery - #177

Closed
wesbillman wants to merge 1 commit into
mainfrom
carl/local-first-sidebar
Closed

wesbillman wants to merge 1 commit into
mainfrom
carl/local-first-sidebar

Conversation

@wesbillman

Copy link
Copy Markdown
Collaborator

Outcome

Restore the last coherent sidebar from a scoped local checkpoint, draw it before upstream session discovery, then reconcile with the live session. Cached rows are inert until fresh roster authority is available. Cold startup avoids the raw IDs → names → groups sequence; settled metadata omission/failure retains the existing usable ID fallback.

Originating conversation (channel 3485e7cf-8cd2-4d0b-a2a1-fb963530486b): buzz://message?channel=3485e7cf-8cd2-4d0b-a2a1-fb963530486b&id=337d434c787b7e067427c43be0e14d7c752697aa10936ea5c4fe98229cc3fdd0&thread=337d434c787b7e067427c43be0e14d7c752697aa10936ea5c4fe98229cc3fdd0

Boundaries

  • The host owns a one-way presentation projection, not a second authority or sync engine. Signed metadata/profile events are reverified; preferences remain encrypted events on disk and use the existing local broker decoder. Partitioned by community/viewer with relay-author checks, atomic replacement, 4 MiB/record and eight scopes/8 MiB total. Storage failure falls back to live startup; deletion is best-effort, not secure erasure. Channel names/profile records are not encrypted at rest.
  • Reuse the sidebar renderer/viewport across same-scope connection transitions while resetting session-owned controls. Live roster, capabilities, previews, navigation and writes remain current-session-owned. Revocation, clear and disposal fence late restores and writes. Existing head-cache write→clear admission drains before close; upstream attachment cancellation from Connect attachments to existing message delivery #176 is preserved.
  • No offline-write changes, general sync framework, durable-intent migration, or native backend. Production source diff: 1,673 changed lines / 867 net added, including 803 lines of sidebar component movement/refactoring. The initial estimate was exceeded to preserve the existing viewport and cover persistence/lifecycle races; this is the complete bounded sidebar slice.

Validation

At clean head 55ca75ec636dc9fad3b04713217d67afc7d57109, rebased on aa87f5c8:

  • Full Vitest rerun: 229 files / 2,438 tests passed. The first post-rebase run passed all assertions but exited unsuccessfully on an unhandled notification timer (host.cancelAnimationFrame after teardown, attributed by Vitest to NotificationSettings.test.tsx). The unchanged full rerun passed; no notification code/test was modified and baseline flakiness is not established.
  • Node integration suite: 118 passed. Lint, icon classification, staged-file hook, and mandatory pre-push TypeScript/related-unit/design-system gates passed. Biome reports an informational schema-version mismatch only.
  • Chromium + WebKit: 42 passed, comprising local-first-sidebar, global-search, navigation-scroll-intent, sidebar-unread and their ten configured opening/scroll measurement dependencies.
  • Earlier full browser run at 1f84835 plus the implementation diff: 535 passed / 1 WebKit presence-demand failure. Entire presence file reran unchanged: 12/12 passed. Bounded attribution found no source-proven link to this feature, but that full run is not claimed clean. Full browser suite was not repeated after rebase.
  • Independent bounded persistence, lifecycle and UI/service source reviews cleared the repaired findings before rebase. These were source/test inspections, not independent execution. Range-diff after rebase confirms the attachment cancellation line is retained alongside the original cache-clear changes.

Browser coverage changes

Added three scenarios (six engine cases): IndexedDB warm reload before held session discovery, and both metadata/preferences cold response orders. These prove real browser persistence, production broker wiring and stable DOM rather than a jsdom approximation. Existing exact-public navigation now checks bounded access lookups; unread/scroll tests establish warm readiness explicitly. No browser scenarios removed. Persistence/lifecycle/terminal-state matrices stay in Vitest.

Fail→pass evidence during implementation includes preferences-first raw-ID rendering in both engines, exact-public navigation repeatedly restarting access resolution, disconnect publishing a disposed ready session, and failed preference decode followed by complete omission/denial leaving a resurrectable checkpoint. No retries, relaxed assertions or longer timeouts were added to conceal failures.

Draft gates

  • Actual just desktop warm restart / Tauri IndexedDB persistence and startup latency remain unverified. Browser evidence is not native restart evidence. Packaged builds still lack the development broker; this PR does not add packaged broker support.
  • Hosted CI required, DCO Check, required reviewer/code-owner approval, and attended desktop acceptance remain before merge. No merge requested.

Carl, an automated contributor, publishing via Wes's GitHub account.

Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Changes needed: one P2 integration regression, detailed inline. GitHub rejected the formal request-changes submission; this authenticated account is also the PR author, so this is a comment review, not a blocking GitHub review state. Head 55ca75ec636dc9fad3b04713217d67afc7d57109, base aa87f5c832251e4db61fdfdf6e5d0b7f93620551.

Approach: a bounded, host-owned presentation checkpoint is reasonable. The reviewed cache paths do not supply read/write authority; stable scope-owned chrome and generation-owned controls are justified. Cached labels deliberately remain visible before fresh membership, and channel/profile names are plaintext on disk. That documented privacy tradeoff must be acceptable. Repair the live-name integration without adding another naming/cache owner.

Merge criteria: fix the inline finding with regression coverage, repair the DM journey’s readiness barrier, resolve the remaining browser gate, and complete the stated attended desktop acceptance.

Validation: source review, three independent bounded review lanes and an exact-source projection probe; no new full-suite or native run. Hosted run 35919019027 has green JavaScript, Rust/tool integration, browser measurements and DCO, but CI required is red. Its merge commit 62e236a2b47902a2dbf1098e6ffd5388c6824b79 has the same Git tree as this head.

  • Chromium sidebar-unread.spec.mjs:106: a cached sibling row is no longer proof of live readiness. The captured replacement stream has no channel routes yet; the artifact subsequently records socket 1’s dm-030 route. Wait for the replacement production route before injecting the event. This is a test synchronization defect, not evidence that warm:false removed DM subscriptions.
  • WebKit buzz-links.spec.mjs:196: initial Messages-button click timed out in open(). Attribution remains unresolved, not established as unrelated/flaky.
  • Actual Tauri warm restart/persistence/latency remain unverified. Packaged broker support is outside this PR. No approval or merge performed.

const participants = channel.participants ?? saved.participants;
return {
id: channel.id,
name: saved.name,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve live identity-name resolution for active DM rows

When an agent’s configured/directory name differs from its public kind-0 profile, useChannelLabels has already resolved the correct current-session name (and any duplicate-name suffix). This unconditional name: saved.name replaces it even after metadata is fully ready. The presentation producer only folds public profile events (presentation.ts:81,99–104), so future directory renames cannot repair the sidebar; the conversation header still uses useChannelLabels and shows a different name. For duplicate agents this also removes the suffix that distinguishes the intended recipient.

The exact reconciliation body at this head maps a ready live Local Larry · 7qls row to cached Public Larry with metadataPending=false. Preserve/reapply the current session’s identity-name resolution for active DMs while retaining cached labels as the pending fallback. Add page-level coverage where directory and public names differ, including a directory update after restoration/readiness.

@wesbillman wesbillman closed this Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant