upstream(sync): Tier 1 perf/CPU — mounted-view, Rust hot paths, relay traffic - #312
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
DONEAll five upstream changes in #279's scope are ported, on
TDD, per upstream PR (RED → GREEN, full logs): Gates (Hermit toolchain;
Evidence (all under
IN PROGRESSNothing is half-done. The worktree is clean at TODO / NEXTRemaining verification, none of it blocking the diff:
Known risks and expected conflicts:
CI status (not fixed, per instruction): the latest run shows |
…e echo (block#5879) ## Problem Desktop webview CPU stayed high after the presence-scope fix (block#5830) and the shared useNow ticker (block#5861). A per-kind byte tap hot-patched into `relayClientSession.ts` on a live desktop (~500 channels, large agent fleet; 850 s capture correlated with CPU sampling) showed the remaining steady-state relay traffic is mostly self-inflicted: | kind | what | share of inbound bytes | shape | |------|------|-----------------------|-------| | 30078 | read-state | **34%** | our own ~44 KB nip44 blob echoed back every ~10-30 s while reading | | 30030 | emoji union | **33%** | 2-min poll refetching every member's full set (~300 KB burst) | | 30175 | persona catalog | **13%** | same 2-min backstop pattern, ~150 KB per walk | CPU tracked the bursts directly: 3-5% in quiet 10 s buckets vs 44-54% in buckets containing a poll burst or read-state echo. (The kind-24200 observer-frame theory was tested and disproven by the same tap: 9.7% of bytes, steady trickle.) ## Outcome - **Read-state echo drop.** `ReadStateManager` remembers the ids of events it just published (FIFO set capped at 64) and drops their relay echoes before the nip44-decrypt + `JSON.parse` step. Ids are recorded *before* publishing so relay fan-out can't race the OK. The drop consumes the id, so a reconnect replay of the same event still parses normally. Events from other clients of the same pubkey are untouched. - **Poll backstops stretched 2 min → 20 min** for the emoji union and persona catalog queries. The live subscriptions (invalidate on any new 30030/30175) and the reconnect invalidations remain the freshness paths; the poll only exists to cover a silently dropped live event. Behavior on publish, focus, and reconnect is unchanged. - Mechanical: localStorage identity helpers moved to `readStateIdentity.ts` (no behavior change) to keep `readStateManager.ts` under the file-size ratchet. Expected effect on the measured profile: the poll stretch cuts the 30030/30175 bursts (46% of inbound bytes) by 10x; the echo drop removes the recurring ~44 KB nip44-decrypt + parse per publish cycle (the echo still arrives on the wire — nostr filters cannot exclude own-author events — so this is a CPU/IPC saving, not a bandwidth one). ## Acceptance - New tests: echo dropped **before** decrypt (mutation-checked: disabling the drop fails the test), replayed duplicate of the same id still parses, foreign-client events always parse, published-id set stays capped when publishes fail (never-echoed ids). - Full desktop suite **4794/4794**, `tsc --noEmit` clean, `pnpm check` (biome + ratchets) clean at head. ## Not addressed (follow-ups) - The 44 KB blob itself (one read-state event carries all ~500 channels; a delta or per-channel-shard format is a protocol change). - Duplicate delivery of the same events on concurrent `history-` subscriptions (relay/client dedupe). - Webview RSS of 12.5 GB observed on the same machine — retention hunt is separate work; shrinking the heap multiplies the value of this PR since the GC floor scales with live-heap size. Signed-off-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
…#5897) Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
Port the pre-SDK definition_validation module verbatim from upstream as the minimum dependency for PR block#6024 (upstream block#4220). Validation boundaries in personas/create.rs, inbound.rs, update.rs, agent_models.rs, agents.rs, agent_events.rs, agent_snapshot.rs, and commands/managed_agent_definition.rs deliberately remain out of scope. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
Port upstream Buzz PR block#6024, moving relay, unread, archive, and persona catalog hot paths into native Rust. Preserve Crew lifecycle, relay recovery, channel-first navigation, and E2E extension points while applying additive adaptations. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
Record exact upstream-owned line counts required by the desktop file-size ratchet for the Tier 1 performance sync. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
The Tier 1 observer baseline was recorded with a future date. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
Restore upstream observed-unread shutdown flush wiring and align ported test fixtures with Crew's managed-agent shapes and scoped node path. Remove the duplicate PTT installer and narrowly allow the bounded validation wrapper that remains unused outside the block#4220 validation-boundary port. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
e6dad95 to
2ce50bd
Compare
The rebase onto main picked up #312's observerRelayStore baseline (1031). Tier 1 ACP harness control_result dispatch grows that file to 1054, which is upstream-owned (block#4557), so the recorded baseline is bumped per D-033. Keep discovery/tests.rs at main's grandfathered size: add effort_level without wrapping the adjacent comment. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: oscarlehuu <oscarlehuu@users.noreply.github.com>
Summary
Tier 1 performance/CPU sync from upstream Buzz onto the Crew
0.5.11pin. Five upstream PRs, ported in scope order, each as its own commit:{ agentPubkey, events }— only the newly admitted, retained events for the one agent that changed — and the active-turn bridge processes that delta instead of rescanning the whole fleet's retained journalsSet+ re-sort per envelope), low-water eviction floor so cap trims amortize, poll-tick disk reads removeddiscover_acp_providerssplit into a cheap cached path and an explicit forced path; hot surfaces (channel switch, composer, member bar) render from cache with a 30-minutestaleTime, forced discovery is single-flighted and only runs on Settings/onboarding/post-mutationarchiveSyncManager.ts(345 lines) and the TS persona-catalog parse (242 lines) are deleted in favour of the native commandsNet: ~9.9k lines added, ~2.6k removed, mostly upstream Rust modules plus their test suites.
Prerequisites pulled in deliberately (not in #279's list)
Two upstream changes had to come along because the scoped PRs are built directly on top of them. Both are verbatim upstream code, both are in the
desktop-v0.5.18target tag, and neither is itemised in a sibling child issue:definition_validation.rsfrom upstream Harden shared agent instruction review block/buzz#4220 (a20e40301). Upstream's newpersona_catalog.rsimportsmanaged_agents::validate_agent_definition_text, which does not exist at the Crew0.5.11baseline. The module is copied verbatim frombbd20fae7^and wired with only themod+pub(crate) uselines Harden shared agent instruction review block/buzz#4220 added. None of Harden shared agent instruction review block/buzz#4220's validation boundaries (create/update/inbound paths, agent events, snapshot) are ported — that hardening is a separate PR's scope. Since this is security-sensitive code, nothing here was hand-written or re-derived.appendAgentEventson top of. Perf-only, same file, same function.Crew divergences (Crew behaviour kept, upstream hunk adapted)
AppShell.tsxis not applicable and was not taken: noonSelectProjects, noonSelectWorkbench, no restoredorgview. AppShell changes are additive (useArchiveAgentMetricsBridge, the archive-sync hook move,topLevelUnreadChannelIds).useAppShellLifecycleEffects.ts.desktop_invoke_handler!(), new state additively to.manage(...); upstream's inline handler list is not restored.toRelayFrames) is adopted.commands/agent_models.rsinstead of upstream'sagent_models_update.rs; observer dedup keepsobserverEventIdentity.activeAgentTurnsStorebecause Crew owns theactiveAgentTurnsHooks.tssplit.AppShellChannelSurfaceand deep-link APIs stay; upstream's newer modules for those are outside this port.desktop/scripts/file-size-baselines.jsonrecords the upstream-owned growth inobserverRelayStore.ts(1031),activeAgentTurnsStore.ts(1059) andrelayClientSession.ts(1070).Related issue
Fixes #279. Part of the
0.5.18sync stack tracked by #285; guardrail #278.Testing
TDD per PR — tests applied first (RED), then implementation (GREEN). Full untruncated logs are attached to the session; counts:
createActiveAgentTurnsObserverListenerfailsGates (Hermit toolchain,
just _ensure-sidecar-stubsbefore Rust):pnpm --filter buzz checkpnpm --filter buzz typecheckpnpm --filter buzz testjust check-compilecd desktop/src-tauri && cargo check --all-targetsjust desktop-tauri-clippyjust desktop-tauri-testjust test-unitbuzz-cli(agents callsubcommand count — Crew's call-by-name) andbuzz-db(embedded_migrator31 vs 30) assertions; neither crate is touched by this branch and both fail onmainDesktop E2E under xvfb: unread/inbox/badge suites relevant to the block#6024 rewrite — 54 passed (
badge,unread-pill,sidebar-more-unread-overlap,thread-unread,inbox-live-update,inbox-edit,inbox-refactor-screenshots,mission-inbox), plusobserver-archive-policy.spec.ts6 passed.inbox-reactionsandproject-inboxfail onmaintoo (project-inboxexpects the removed Repositories IA, per #223/#219);dm-double-notificationneeds a live relay on :3000.Quantitative delta (block#5897) — same-revision A/B of the two bridge publication paths, fleet of 20 running agents × 500 retained observer events, 200 steady-state single-event publications:
UI evidence — full-window, before (pin
0.5.11) vs after (this branch)The perf port is not meant to change the UI; these prove the app shell and channel-first IA render identically, including sidebar unread emphasis now sourced from the native observed-unread projection.
App shell (Inbox + channel + thread panel):
Agents settings:
Harness catalog (the surface block#6330's forced-discovery gate changes) — opening and ready state:
Runtime verification — headed drive through the E2E mock bridge
Driven headed through the mock bridge with the Tauri IPC wrapped to count every native command call, focusing on the five hot paths moved to Rust (unread being the highest-risk one).
Live emits into a non-active channel bold the row and drive the badge; opening the channel clears both:
Adversarial isolation — a reply to an already-read root must not register as top-level unread, and the next top-level message must:
Thread unread stays separate (
1 reply (1 new)), the messaging golden path works (sent reply renders, summary 1 → 2 replies), and forced ACP discovery resolves with no endless shimmer:No errors from
start_archive_sync,observed_unread_open_scope,observed_unread_ingest,unread_catch_uporfetch_persona_catalog; only pre-existing benign mock gaps (is_shared_identity, audio-device commands,fetch_workspace_icon,discover_git_bash_prerequisite,mock-feed-mention).Not proven / follow-ups
resetMockObservedUnread()on install and native mode no longer mirrors acknowledged state tolocalStorage, so the mock cannot model Rust-side persistence. Worth one manual check on a real Tauri build before merge.stop_archive_syncnever fired in a session (start only) — the teardown side of the archive-sync port is unexercised at runtime; it appears to be unmount/sign-out only.fetch_persona_catalogitself succeeded (covered byagents.spec.ts).observed_unread_ingestfires very frequently (~305 calls by boot-end). Behaviour is correct, but the per-call IPC volume is worth a glance given this is a perf PR.Follow-up commit — Tauri test-target compile break
just check-compilerunscargo check --workspace --all-targetsfrom the repo root, anddesktop/src-tauriis not a member of that workspace, so the Tauri crate's test targets were never compiled by the documented gate and the port shipped four defects that only CI's Desktop Rust job saw. Fixed in a follow-up commit, withcargo check --all-targets+ clippy + the full Tauri test suite now run in-crate:observed_unread::flush(app)inshut_down_app(WAL checkpoint on exit) that the port dropped — Crew'squit_governorline kept.ptt_shortcut.rstomain: the port had added a duplicate copy of Crew's inline PTT global-shortcut handler asptt_shortcut::install, out of scope and never called.#[allow(dead_code)]onvalidate_managed_agent_definition_textand trimmed the re-export: it is part of the verbatim upstream module, and its callers are Harden shared agent instruction review block/buzz#4220 validation-boundary changes deliberately excluded here.ManagedAgentRecord(hermes_profile, not upstream'sprovider_policy_pending/effort_level), Crew's 5-argumentprospective_spawn_config_snapshot, and Crew's platform-scoped managed-node path. No production types or signatures were changed to satisfy a test.DONE
All five upstream changes in #279's scope are ported, on
devin/issue-279-tier1-perf@4efdbd15350e4d92777fcfeb5abb324b13f3382c(2 commits, both-ssigned):MAX_OBSERVER_EVENTS3000 / 90% low water, per-agent eviction floor), no poll-tick disk reads.invoke.rs) andlib.rsmanaged state; the TS archive-sync manager and persona parse path were deleted in favour of the native ones.relayClientSession.ts, no read-state echo when unchanged (readStateIdentity.ts).{ agentPubkey, events }observer updates,createActiveAgentTurnsObserverListener+useActiveAgentTurnsBridgehydrate once then apply deltas.staleTime30 min) + explicitrefreshAcpRuntimes, Rust-side forced single-flight and auth-status cache.TDD, per upstream PR (RED → GREEN, full logs):
5879-RED/GREEN.log,5897-RED/GREEN.log,6198-RED/GREEN.log,6330-RED/GREEN.log,6024-RED/GREEN.log,6024-cargo-check.log(all under~/evidence-279/).Gates (Hermit toolchain;
just _ensure-sidecar-stubsbefore Rust):pnpm --filter buzz checkgate-check.logpnpm --filter buzz typecheckgate-typecheck.logpnpm --filter buzz testgate-test.logjust check-compilegate-check-compile.logcd desktop/src-tauri && cargo check --all-targetsfix-desktop-rust-check.logjust desktop-tauri-clippyfix-desktop-rust-clippy.logjust desktop-tauri-testfix-desktop-rust-test.logjust test-unitbuzz-cli/buzz-dbassertions that also fail onmaingate-test-unit.log,base-test-unit.logEvidence (all under
~/evidence-279/unless noted):shots/before-01..04-*.png,shots/after-01..04-*.png(embedded above).~/screenshots/ss_*.png, recording~/screencasts/tier1-perf/tier1-perf-edited.mp4.e2e-unread.log,e2e-observer-archive-policy.log,e2e-after*.log, plus base-branch comparisonsbase-e2e-inbox-reactions.log,base-e2e-project-inbox.log.measure-5897.log,measure-5897.mjs— 1115.4 ms / 5.577 ms per publication (full replay) → 6.0 ms / 0.030 ms (incremental), 186.6x less bridge time at 20 agents × 500 events × 200 publications.divergences.md. CI excerpts:pr312-desktop-e2e-excerpts.log.IN PROGRESS
Nothing is half-done. The worktree is clean at
4efdbd15, everything is pushed, and no local edit is uncommitted. One unrelated change (an update to.agents/skills/desktop-e2e-manual-drive/SKILL.mddocumenting how to drive unread / native-command flows) was deliberately kept out of this PR and sent as a separate skill-PR suggestion, so it is not part of this diff.TODO / NEXT
Remaining verification, none of it blocking the diff:
resetMockObservedUnread()on install and native mode no longer mirrors acknowledged state intolocalStorage, so the mock cannot model the Rust store across relaunch. Worth one manual check on a real Tauri build: mark channels read, quit, relaunch, confirm they stay read.stop_archive_syncwas never exercised at runtime — onlystart_archive_syncfired in a session. Confirm the teardown path is genuinely unmount/sign-out only.observed_unread_ingestfires very frequently (~305 calls by boot-end). Behaviour is correct, but the IPC call volume deserves a look given this is a perf PR.agents.spec.ts).Known risks and expected conflicts:
just check-compiledoes not coverdesktop/src-tauri(it is not a member of the root workspace), so Tauri test-target breaks are invisible to the documented gate — that is how the four defects fixed in4efdbd15reached CI. A tooling fix belongs in its own PR; I did not touch tooling or CI here.persona_catalog.rsrequiresvalidate_agent_definition_text, absent from thedesktop-v0.5.11pin, so upstream Harden shared agent instruction review block/buzz#4220'sdefinition_validation.rsis included verbatim with onlymod+ one re-export of wiring. None of Harden shared agent instruction review block/buzz#4220's validation boundaries are ported, which is whyvalidate_managed_agent_definition_textcarries a narrow#[allow(dead_code)]— the allow should be removed when Harden shared agent instruction review block/buzz#4220 lands.desktop/src-tauri/src/invoke.rsandlib.rs(additive command/state registration),desktop/src/app/AppShell.tsx,desktop/src/testing/e2eBridge.ts, anddesktop/scripts/file-size-baselines.json(ratcheted foractiveAgentTurnsStore.ts1059,observerRelayStore.ts1031,relayClientSession.ts1070). All are additive hunks; resolve by keeping both sides, never wholesale "ours".divergences.md.CI status (not fixed, per instruction): the latest run shows
NuncioCrew Gatefailing solely becausedesktop-fast,desktop-rustandmacos-armwere cancelled — the gate script reportsdesktop-fast must be success when desktop=true, got cancelled. That is the parent session's deliberate CI serialization, not a failure of this change; every non-cancelled leg that ran passed. The earlier genuineDesktop Rustcompile failure was real and is fixed in4efdbd15.Link to Devin session: https://app.devin.ai/sessions/5e6d0da9f17741d79cc58e401375f66a
Requested by: @oscarlehuu