perf(desktop): persist channel snapshot hash (#5684)

## Summary

- persist each relay/identity's complete channel list and server hash as
one integrity-checked snapshot
- paint the snapshot immediately on cold boot, then revalidate with
`knownHash`
- fail slow-never-wrong: malformed/legacy/partial snapshots and
mismatched not-modified responses force an unhashed full fetch
- add sidebar boot diagnostics and deterministic unit/E2E coverage for
boot, identity/relay isolation, partial writes, mismatch fallback, and
community switches

## Safety invariants

- channel list and hash are serialized in one localStorage document and
replaced together
- snapshot ownership is scoped to normalized relay URL plus identity
pubkey
- a not-modified response is accepted only when its hash exactly matches
the hash describing the available list
- any missing or impossible hash/list pairing retries
`getChannels(null)` before replacing persistence

## Validation

At exact commit `19ca25d23c434cc0b8893a93691aaf4c77794f60` with a clean
working tree:

- `cd desktop && pnpm check && pnpm typecheck` — passed (existing
informational Biome findings only)
- `cd desktop && pnpm test` — 4,723 passed
- `cd desktop && node --import ./test-loader.mjs
--experimental-strip-types --test
src/features/channels/channelSnapshot.test.mjs` — 13 passed
- `cd desktop && pnpm exec playwright test e2e/sidebar-snapshot.spec.ts
--grep "cold boot paints" --repeat-each=5` — 5 passed
- `cd desktop && pnpm exec playwright test e2e/sidebar-snapshot.spec.ts`
— 8 passed
- push hooks repeated desktop check/typecheck and all 4,723 unit tests
successfully

The Playwright suite uses injected bridge delays. Its roughly 0.5–0.6 s
snapshot paint and 3.0 s snapshot-to-live readings are synthetic
invariant evidence, not production desktop performance measurements.

## Measurement context

The controlled current-main investigation is documented separately in
`RESEARCH/DESKTOP_PERF_DEEP_DIVE_2026_08_12.md`; its raw local artifacts
are `.scratch/summer-perf-deepdive-results-v2.json`,
`.scratch/summer-perf-deepdive-run.log`,
`.scratch/summer-perf-deepdive-run-2.log`, and
`.scratch/summer-perf-deepdive-build-2.log`. Those original timings are
also synthetic Chromium/mock-bridge measurements and are not presented
as shipped Tauri/WKWebView or production-relay numbers.


## Latest review delta

At exact tip `e8e2b1d617aac7ea008258ad9974bbf8da9cd2eb`, storage-denial
reads fail open to the live fetch, hashless retries reject `channels:
null` before pair/persistence updates, identity-read failure enables a
hashless live fetch, and repeated consumers reuse snapshot
parsing/integrity validation by storage key + raw document. The four
remaining review nits are deferred as non-blocking follow-ups.

Validation at this tip: sidebar snapshot E2E 30/30 serial; desktop unit
suite 4,725/4,725; full push gate green (desktop check/typecheck/unit,
Rust, Tauri).

---------

Signed-off-by: Summer <1fdd3cc104e2911eb3b2da6f97d1b25f4a7f3550ded4492b24ff1d95acd66766@buzz.block.builderlab.xyz>
Co-authored-by: Summer <1fdd3cc104e2911eb3b2da6f97d1b25f4a7f3550ded4492b24ff1d95acd66766@buzz.block.builderlab.xyz>
This commit is contained in:
Wes
2026-08-12 15:23:41 -06:00
committed by GitHub
parent 72d56e7bd3
commit c86443c599
9 changed files with 1340 additions and 164 deletions

View File

@@ -4,6 +4,11 @@ import { installMockBridge } from "../helpers/bridge";
import { FEATURE_OVERRIDES_STORAGE_KEY } from "../helpers/features";
const RELAY_URL = "ws://localhost:3000";
const OWNER_PUBKEY = "deadbeef".repeat(8);
function snapshotKey(relayUrl: string) {
return `buzz-channels.v1:${relayUrl}:${OWNER_PUBKEY.toLowerCase()}`;
}
const COMMUNITY_A = {
id: "ws-a",
@@ -412,33 +417,36 @@ test.describe("community rail", () => {
await seedCommunities(page, [COMMUNITY_A, COMMUNITY_B], COMMUNITY_A.id);
await page.goto("/");
await expect(page.getByTestId("app-sidebar")).toBeVisible();
const rememberedChannelId = await page.evaluate((communityId) => {
const source = window.localStorage.getItem(
"buzz-channels.v1:ws://localhost:3000",
);
if (!source) throw new Error("missing source channel snapshot");
const snapshot = JSON.parse(source) as {
channels: Array<{ id: string; name: string }>;
};
const generalChannel = snapshot.channels.find(
(channel) => channel.name === "general",
);
if (!generalChannel) throw new Error("missing general channel snapshot");
window.localStorage.setItem(
"buzz-channels.v1:ws://localhost:3001",
source,
);
window.localStorage.setItem(
"buzz-community-destinations",
JSON.stringify({
[communityId]: {
kind: "channel",
channelId: generalChannel.id,
},
}),
);
return generalChannel.id;
}, COMMUNITY_B.id);
const rememberedChannelId = await page.evaluate(
({ communityId, sourceSnapshotKey, targetSnapshotKey }) => {
const source = window.localStorage.getItem(sourceSnapshotKey);
if (!source) throw new Error("missing source channel snapshot");
const snapshot = JSON.parse(source) as {
channels: Array<{ id: string; name: string }>;
};
const generalChannel = snapshot.channels.find(
(channel) => channel.name === "general",
);
if (!generalChannel)
throw new Error("missing general channel snapshot");
window.localStorage.setItem(targetSnapshotKey, source);
window.localStorage.setItem(
"buzz-community-destinations",
JSON.stringify({
[communityId]: {
kind: "channel",
channelId: generalChannel.id,
},
}),
);
return generalChannel.id;
},
{
communityId: COMMUNITY_B.id,
sourceSnapshotKey: snapshotKey(COMMUNITY_A.relayUrl),
targetSnapshotKey: snapshotKey(COMMUNITY_B.relayUrl),
},
);
await page.evaluate(() => {
const testWindow = window as typeof window & {
@@ -478,28 +486,29 @@ test.describe("community rail", () => {
}, COMMUNITY_B.id);
await page.goto("/");
const sourceSnapshotKey = snapshotKey(COMMUNITY_A.relayUrl);
const targetSnapshotKey = snapshotKey(COMMUNITY_B.relayUrl);
await expect
.poll(() =>
page.evaluate(() =>
window.localStorage.getItem("buzz-channels.v1:ws://localhost:3000"),
page.evaluate(
(key) => window.localStorage.getItem(key),
sourceSnapshotKey,
),
)
.not.toBeNull();
await page.evaluate(() => {
const source = window.localStorage.getItem(
"buzz-channels.v1:ws://localhost:3000",
);
if (!source) throw new Error("missing source channel snapshot");
const snapshot = JSON.parse(source);
snapshot.channels = snapshot.channels.map(
(channel: Record<string, unknown>, index: number) =>
index === 0 ? { ...channel, id: "missing-channel" } : channel,
);
window.localStorage.setItem(
"buzz-channels.v1:ws://localhost:3001",
JSON.stringify(snapshot),
);
});
await page.evaluate(
({ sourceKey, targetKey }) => {
const source = window.localStorage.getItem(sourceKey);
if (!source) throw new Error("missing source channel snapshot");
const snapshot = JSON.parse(source);
snapshot.channels = snapshot.channels.map(
(channel: Record<string, unknown>, index: number) =>
index === 0 ? { ...channel, id: "missing-channel" } : channel,
);
window.localStorage.setItem(targetKey, JSON.stringify(snapshot));
},
{ sourceKey: sourceSnapshotKey, targetKey: targetSnapshotKey },
);
await page.getByTestId(`community-rail-button-${COMMUNITY_B.id}`).click();
await expect(page).not.toHaveURL(/#\/channels\//);
@@ -531,10 +540,12 @@ test.describe("community rail", () => {
}, COMMUNITY_B.id);
await page.goto("/");
await expect(page.getByTestId("app-sidebar")).toBeVisible();
const sourceSnapshotKey = snapshotKey(COMMUNITY_A.relayUrl);
await expect
.poll(() =>
page.evaluate(() =>
window.localStorage.getItem("buzz-channels.v1:ws://localhost:3000"),
page.evaluate(
(key) => window.localStorage.getItem(key),
sourceSnapshotKey,
),
)
.not.toBeNull();
@@ -563,20 +574,21 @@ test.describe("community rail", () => {
};
}),
).toEqual({ released: 0, pending: 0 });
await page.evaluate(() => {
const source = window.localStorage.getItem(
"buzz-channels.v1:ws://localhost:3000",
);
if (!source) throw new Error("missing source channel snapshot");
const snapshot = JSON.parse(source);
snapshot.channels = snapshot.channels.filter(
(channel: { id: string }) => channel.id !== "general",
);
window.localStorage.setItem(
"buzz-channels.v1:ws://localhost:3001",
JSON.stringify(snapshot),
);
});
await page.evaluate(
({ sourceKey, targetKey }) => {
const source = window.localStorage.getItem(sourceKey);
if (!source) throw new Error("missing source channel snapshot");
const snapshot = JSON.parse(source);
snapshot.channels = snapshot.channels.filter(
(channel: { id: string }) => channel.id !== "general",
);
window.localStorage.setItem(targetKey, JSON.stringify(snapshot));
},
{
sourceKey: sourceSnapshotKey,
targetKey: snapshotKey(COMMUNITY_B.relayUrl),
},
);
await page.evaluate(() => {
const config = (
window as Window & {