Reset Hive to thin Buzz v0.5.2 adapters - #82
Conversation
## Summary - combine Desktop Tauri clippy and tests into one pre-push command - run clippy first, then tests - keep unrelated pre-push commands parallel ## Why PR block#3555 added clippy as a separate command while the pre-push group uses `parallel: true`. That can start clippy and tests simultaneously against the same Cargo target directory, leaving one command waiting on Cargo's build lock and making pushes appear stalled. Serializing only these two Cargo-heavy checks avoids lock contention while retaining the CI-equivalent clippy command and existing test coverage. ## Validation - `lefthook validate` - forced `desktop-tauri-checks` through Lefthook with an instrumented `just`; observed `desktop-tauri-clippy` followed by `desktop-tauri-test` Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
clap renders live env var values in help text by default. Three args carrying credentials were exposed this way: - `BUZZ_PRIVATE_KEY` in `buzz-cli` (`crates/buzz-cli/src/lib.rs`) - `BUZZ_AUTH_TAG` in `buzz-cli` - `BUZZ_PRIVATE_KEY` in `buzz-acp` (`crates/buzz-acp/src/config.rs`) Add `hide_env_values = true` to each. Env var names remain visible for discoverability; only their runtime values are withheld from `--help` output. Also adds a regression guard in each crate's test module that walks the clap command tree (recursing into subcommands for `buzz-cli`) and asserts every arg whose env var name contains `KEY`, `SECRET`, `TOKEN`, `PASSWORD`, `CRED`, or `AUTH` has `hide_env_values` set. This prevents future credential-bearing args from being added without the masking in place. Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
…ricks_v2 (block#3569) ## Summary Makes Gemini — and every other non-Claude, non-GPT-5 model on the Databricks MLflow route (`databricks_v2`) — usable in an agent loop. These are the non-`benchmarks/` changes from `benchmark/harness-accounting-and-solo`, lifted onto a clean base off `main` so they can land independently while the harness work continues. Two defects made these models unusable, one fatal and one silent. Both live only in `openai_body` / `parse_openai`, which is the least-exercised of the three `databricks_v2` sub-routes — the `luna`/`sol` conditions run the Responses route and the `opus` conditions run the Anthropic route, so **this change is inert for every model already in use** and only lights up the MLflow path. ## Why a third route at all `databricks_v2_route_for_model` buckets by model family: `claude*` → Anthropic Messages, `gpt-5`/code-names → OpenAI Responses, **everything else → MLflow chat-completions**. Gemini, Qwen, gpt-oss, and friends all fall through to that third pair — and both bugs below live only there. ## D1 — dropped thought signatures (fatal) Gemini returns a `thoughtSignature` on every tool call and **requires it echoed back**. `openai_body` reserialized each call as `{id, type, function}` only, dropping the field, so the next request 400'd: ``` HTTP 400 Function call is missing a thought_signature in functionCall parts. ``` For a coding agent this fires on the **first** tool call, so the model never completes a single turn. **Position is load-bearing.** A four-shape replay probe against the live gateway established that the signature must sit as a *sibling* of `function` — nesting it inside `function{}` fails with the *same* 400 as omitting it. A fix that "preserves the field" without preserving its position passes a unit test and still 400s. The fix: `ToolCall` gains `provider_extra: Map<String, Value>`. `parse_openai` captures every top-level wire key except the three we model (`id`, `type`, `function`); `openai_body` re-emits them beside `function`. Keeping *whatever we did not model*, rather than naming `thoughtSignature`, means the next provider with an opaque per-call token needs no change here. The Responses and Anthropic replay shapes are fully modelled, so they pass `Default::default()` and stay **byte-identical** to before. ### D1b — duplicate tool-call ids (same root cause) Gemini returns the **function name** as the id, so two parallel calls to one function arrive sharing an id — and that id is what pairs a `role:"tool"` result back to its call, making two results indistinguishable. `dedupe_provider_ids` suffixes collisions (`get_weather`, `get_weather-2`). Safe because both halves of the pairing (the assistant `tool_calls[].id` and the result's `tool_call_id`) are re-emitted from this same value; the provider never sees its original id again. ## D2 — block-array content discarded (silent, worse than a crash) `parse_openai` read `content` with `as_str()`, which returns `""` for anything that isn't a JSON string. Gemini (and Qwen35, gpt-oss) send an array of typed blocks: ```json "content": [ {"type": "reasoning", "summary": [{"type": "summary_text", "text": "…"}]}, {"type": "text", "text": "391"} ] ``` So the model answered and the answer was thrown away — no error, no warning, just a turn that looked like the model had said nothing. On a benchmark this reads as "Gemini is bad at the task" rather than "buzz dropped the reply." `openai_content_parts` now accepts either shape — string as before, or a block array where `text` blocks concatenate into text and `reasoning` blocks into reasoning (Gemini nests the prose one level down under `summary`). Message-level `reasoning_content` / `reasoning` still win when present, so DeepSeek and vLLM-style hosts are unchanged; block reasoning is the last fallback. ## Also: a turn-start log line (`buzz-acp` `pool.rs`) Small, independent observability change that also rides in the non-benchmark delta: `run_prompt_task` now emits a `pool::prompt` "turn starting" line, labelled by the same `prompt_label` helper as `log_stop_reason`, so a log reads as start/stop pairs. An unpaired start is the only durable evidence that a turn was entered and never returned — without it, a stalled agent and an agent nobody woke leave identical (zero-completion) logs. ## Interaction with block#3538 block#3538 (already merged) rewrote `databricks_v2_route_for_model` to route by boundary-aware model-family segments. That change and this one touch **different functions** in `llm.rs` — routing vs. body/parse — and compose cleanly; the family routing decides *which* pair runs, and this fixes the MLflow pair it can now select. ## Testing - `cargo fmt --all -- --check`, `cargo clippy -p buzz-agent -p buzz-acp --all-targets -- -D warnings` — clean. - `cargo test -p buzz-agent -p buzz-acp` — all green (304 + 632 lib tests plus integration suites, 0 failures). Five new tests cover: block-array text extraction, plain-string regression, passthrough capture (and non-duplication of the modelled keys), replay position (`thoughtSignature` beside `function`, not inside it), and id de-duplication. - Wire evidence: the four-shape replay table and the reasoning-effort probe were run against `block-lakehouse-staging` (recorded in the design doc). ## Relationship to the benchmark branch The full design write-up (four-shape replay table, position-matters analysis, effort verification, and open pricing item) lives in `docs/08-gemini-provider-fixes.md` on `benchmark/harness-accounting-and-solo`. The benchmark manifests and endpoint-config entries that exercise these models are separable and stay on that branch. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Atish Patel <atish@squareup.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lock#3576) ## Summary [block#3144](block#3144) injected `GOOSE_ACP_SCHEDULER_DISABLED=true` into every `AcpClient::spawn` call as a forward-compatible no-op, intended to suppress the cron scheduler in goose ACP children once the matching reader landed in goose. That reader only ever existed in [aaif-goose/goose#10738](aaif-goose/goose#10738), which was closed unmerged. [goose#10781](aaif-goose/goose#10781) (Lifei Zhou, merged 2026-07-29) disables the ACP scheduler by default at the source: `goose acp` now requires `--enable-scheduler` to start a scheduler. Buzz-spawned children therefore get no scheduler with zero configuration — making the `GOOSE_ACP_SCHEDULER_DISABLED` injection permanently dead code. ## What changes Removes from `crates/buzz-acp/src/acp.rs`: - `GOOSE_SCHEDULER_DISABLED_ENV` constant - `cmd.env(GOOSE_SCHEDULER_DISABLED_ENV, "true")` injection in `AcpClient::spawn` - `spawn_injects_scheduler_disabled_env_by_default` test - `spawn_scheduler_disabled_env_overrides_conflicting_extra_env` test - `spawn_and_read_child_env` helper (unreferenced once the two tests above are gone) No other files are affected. ## Why now Leaving dead code that references an env var no reader will ever consume misleads future maintainers about the actual scheduler-isolation mechanism. The isolation is now an upstream default, not a Buzz injection. Reverts: [block#3144](block#3144) Related: [aaif-goose/goose#10781](aaif-goose/goose#10781) Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
## Summary - render existing shared personas whose catalog avatar is a bounded inline PNG, JPEG, GIF, or WebP data URL - keep rejecting arbitrary, malformed, unsupported, and oversized `data:` URLs - preserve hosted relay URLs as the forward format; catalog browsing remains read-only ## Root cause Paul's live shared kind:30175 head contains a 144,878-character `data:image/png;base64,...` avatar. The catalog projection accepted HTTP(S) URLs and bounded percent-encoded SVG emoji avatars only, so it projected Paul's avatar to `null` before `ProfileAvatar` rendered it. The owner still saw the local persona avatar, producing the reported owner/viewer mismatch. This patch accepts only four raster MIME types with strict base64 shape and a 256 KiB total URL cap at the existing catalog parsing boundary. It repairs already-signed heads such as Paul without viewer-side uploads or publication side effects. Hosted media remains the canonical forward path. block#3578 uploads inline raster avatars during snapshot import, preventing the known source from creating future inline persona/profile values; existing signed catalog heads still need this compatibility path until their owners republish. ## Agent instruction finding The catalog publishes `AgentDefinition.system_prompt` verbatim as the user-authored **Agent instruction**, as documented by the sharing UI and NIP-AP. No Buzz base/core/runtime prompt is concatenated in the publish, catalog, or import path. This PR therefore does not remove authored instructions and accidentally strip copied agents of their behavior. ## Validation - targeted `personaCatalogRelay.test.mjs`: 24 passed - Desktop typecheck: passed - pre-push Desktop frontend suite: 3,771 passed - pre-push Desktop checks: passed - `git diff --check`: passed - independent review: no blockers, 9.4/10 Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
> Carl is updating this pull request on Wes's behalf. ## Summary - upload an embedded raster avatar through the existing authenticated media pipeline before minting or persisting an imported shared agent - store and publish only the resulting hosted URL so agent kind:0 profiles remain within content limits ## Root cause Snapshot import recovered raster avatar pixels as a large inline base64 data URL. That value was persisted and placed into the agent's kind:0 profile. The relay rejected the oversized profile, so other clients could not resolve the imported agent's avatar. ## Scope This is intentionally the forward fix only. It changes two Desktop files and does **not** add migration or reconciliation behavior for previously imported agents. Existing affected imports must be re-imported or fixed manually. ## Validation - successful pre-push Desktop suite: 1,863 passed, 14 ignored, 0 failed - all pre-push Rust/Desktop gates green, including all-target clippy - valid >256 KiB PNG import → production MIME detection/sanitization → bounded signed kind:0 containing only the hosted URL - upload failure, malformed data, and URL-only avatar cases covered - independent fresh review by Princess Donut: clean, no blocking findings Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
## Summary - Show all colon emoji autocomplete matches - Rank exact and prefix shortcodes before weaker matches - Add a regression test and screenshot ## Validation - `pnpm test` - `pnpm build` - `pnpm exec playwright test --project=smoke tests/e2e/custom-emoji.spec.ts --grep "exact standard shortcode"` - `just desktop-tauri-clippy` Native Tauri tests were attempted but could not link because the local disk filled during compilation. --------- Signed-off-by: kenny lopez <klopez4212@gmail.com>
## Summary Communities joined via an invite link never connect: the app dials `ws://` on port 80 instead of `wss://` on 443 and sits on "Reconnecting…" indefinitely. `RelayConfig.baseUrl` is documented as an HTTP origin, but the two onboarding flows disagree on what they persist: - **Device pairing** validates and stores `https://` — `pairing_provider.dart:657` throws on anything else. - **Invite join** stores the relay URL straight off the invite link, and `deep_link.dart:165` always emits `ws://` or `wss://`. `wsUrl` only special-cased `https://`, so a `wss://` base fell through to the plaintext branch: ```dart final scheme = uri.scheme == 'https' ? 'wss' : 'ws'; // 'wss' is not 'https' ``` The claim request itself succeeds, because `_claimUrlFromRelay` (`invite_join_provider.dart:242`) maps `wss → https` explicitly. Only the socket path is missing that conversion — which is why the community appears, correctly named, and then never loads. The same `baseUrl` also feeds `/query` (`relay_session.dart:136`), media upload (`media_upload.dart:765`), Blossom auth (`media_auth.dart:128`) and `relayClientProvider` (`relay_provider.dart:113`), so those requests were malformed too. Where port 80 *does* answer, it is additionally a silent TLS downgrade after `validateInviteRelayUri` insisted on `wss://`. This folds the websocket schemes back to their HTTP equivalents in `baseUrl` itself, so every consumer is correct by construction rather than needing a second getter remembered at each call site, and communities **already persisted** with `wss://` are repaired on read without a migration. `community_icon_provider.dart:46` already performs this same conversion locally. One subtlety worth flagging for review: the normalization is derived in the getter rather than applied in the constructor, so the constructor stays `const`. The compile-time fallback at `relay_provider.dart:77` relies on const canonicalization for a stable identity across rebuilds, and Riverpod's `defaultUpdateShouldNotify` is `previous != next` (`element.dart:361`), which falls back to identity for this class. A `factory` constructor here yields a fresh instance per rebuild, which tears down and resubscribes every listener — `channels_provider_test.dart` catches it as an unexpected unsubscribe during reconnect. ### Related issue Fixes block#2662. ### Testing `flutter test` — **705 passed, 1 skipped, 0 failed** `flutter analyze` — No issues found `dart format --set-exit-if-changed .` — 249 files, 0 changed Run against the Hermit-pinned SDK (Flutter 3.41.7 / Dart 3.11.5), matching CI. 10 new unit tests in `mobile/test/shared/relay/relay_config_test.dart` covering both onboarding schemes, `http`/`https` passthrough, non-default ports, and agreement between the invite and pairing paths for the same relay. Verified end-to-end against a self-hosted relay behind `tailscale serve`, which terminates TLS on 443 and leaves port 80 closed. Relay logs show the invite claim succeeding over HTTPS at the moment of joining, while no WebSocket connection ever arrives — no `WebSocket connection established`, no NIP-42 auth, no `kind:0` profile, no push registration — across the relay's entire history, even though the member row is present and correct. Port-80 refusals are not logged by `tailscaled`'s netstack, which is why the retries leave no trace server-side. Reproduced on both iOS and Android. --------- Signed-off-by: Krishna C <github@kumb.uk>
## Summary - reconcile stale native-scroll anchors when a reply arrives at the physical floor - clear the thread new-message affordance instead of incrementing it from stale cached state - preserve the existing mid-history path and add direct lifecycle regression coverage ## Why PR block#3411 fixed geometry-driven reconciliation, but the reply-arrival branch still trusted a cached `message` anchor without checking the rendered position. Native anchoring could return a short thread to the floor without another scroll/resize callback, then the next reply incremented the pill anyway. ## Verification - Desktop checks passed - Desktop typecheck passed - focused lifecycle test passed (6/6) - push hook full Desktop unit suite passed (3,770/3,770) - `git diff --check` passed Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
🤖 ## Summary - Keep the relay reconnect notification dismissed across repeated connection retries during one continuous outage. - Re-arm the notification after recovery or relay lifecycle replacement, including switches between communities that use the same relay URL. - Preserve the existing dedicated path for authentication and other application-level errors. ### How an outage is tracked The AppShell-owned relay-card hook treats an outage as one contiguous runtime episode rather than assigning it a persisted ID. A hook-local `outageActiveRef` is armed by the first qualifying unreachable/degraded observation. While it is armed, intermediate retry states (`connecting`, `reconnecting`, `stalled`, and `disconnected`) belong to that same episode, so retry churn cannot clear dismissal or emit another notification. The hook receives the same lifecycle identity used by community initialization: community ID plus `reinitKey`. This distinguishes multiple communities even when they share a relay URL, and it also changes when the active community is explicitly reinitialized. The latch and dismissal are reset when that identity changes or when the relay singleton reports its authoritative `idle` teardown state. A successful `connected` state also closes the episode and re-arms the next outage. These boundaries deliberately bias toward re-notifying rather than suppressing a later outage: recovery, community switch/reinit, or relay teardown cannot leave the hook stuck believing an old outage is still active. No outage state is persisted beyond the mounted hook lifecycle. ### Related issue None found. ### Testing - `pnpm --dir desktop typecheck` - `pnpm --dir desktop test` — 3,769 passed - `pnpm --dir desktop check` - `pnpm --dir desktop build:e2e` - `pnpm --dir desktop exec playwright test tests/e2e/sidebar-relay-card.spec.ts --project=integration` — 11 passed --------- Signed-off-by: Larry <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> Co-authored-by: npub13n66s06epmqf2kc3v373ez8hj65cuzyvxzjf93vwpervxqn2u7jq2qd9je <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz>
🤖 ## Summary Agent-authored mentions currently depend on matching visible `@Name` text to channel profiles. That makes notification delivery ambiguous when names collide or profiles change, and it encourages an extra post-send lookup just to confirm that the intended `p` tags were emitted. This change makes `buzz messages send` mirror Desktop's existing model: the message keeps a readable name in its content while the recipient pubkey is supplied separately. ```bash buzz messages send \ --channel <UUID> \ --content '@alice could you review this?' \ --mention <alice-hex-or-npub> ``` `--mention` is repeatable. The CLI normalizes and deduplicates explicit pubkeys, merges them with any names it can resolve from the channel, and gives explicit identities priority under the existing 50-mention limit. Before uploading attachments, signing, or publishing, the command checks every resulting pubkey against the channel's current membership: - Members are mentioned normally. - Non-members stop the send and produce an actionable error. - `--allow-non-member-mentions` deliberately sends notifying `p` tags without adding anyone to the channel. Sending a message never changes membership. On success, `mention_pubkeys` is read from the exact signed event and returned with the relay response, so callers can verify the emitted recipients without another query. Managed-agent guidance teaches this single-command mention flow. Desktop mention behavior and the Nostr event schema are unchanged. Forum guidance is intentionally handled separately in block#3596. ### Related issue None found. This replaces the earlier guidance-only approach in this PR with the underlying CLI behavior it required. ### Testing - `cargo test -p buzz-sdk` - `cargo test -p buzz-cli` - `cargo test -p buzz-acp` - `cargo test --manifest-path desktop/src-tauri/Cargo.toml` --------- Signed-off-by: npub1fdupjvyregj3z2tx7gx5x6py04zw89jm5usef9lyea4f3vcgh8qq9zgkdz <4b78193083ca25112966f20d4368247d44e3965ba7219497e4cf6a98b308b9c0@buzz.block.builderlab.xyz> Signed-off-by: npub13n66s06epmqf2kc3v373ez8hj65cuzyvxzjf93vwpervxqn2u7jq2qd9je <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz> Co-authored-by: npub1fdupjvyregj3z2tx7gx5x6py04zw89jm5usef9lyea4f3vcgh8qq9zgkdz <4b78193083ca25112966f20d4368247d44e3965ba7219497e4cf6a98b308b9c0@buzz.block.builderlab.xyz> Co-authored-by: npub13n66s06epmqf2kc3v373ez8hj65cuzyvxzjf93vwpervxqn2u7jq2qd9je <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz>
…#3602) ## What and why The Buzz AppImage is built on `ubuntu:22.04`, which links WebKitGTK against FreeType 2.11.1. Because `libfreetype.so.6` is on the linuxdeploy community excludelist, the bundled WebKit loads the **host's** FreeType at runtime instead of the bundled one. FreeType 2.13.0 (released 2023-02-09) added `FT_Bool read_variable` to `FT_ColorStopIterator`, growing the struct from 16 to 20 bytes. Any host running FreeType ≥ 2.13 (Fedora 42+, Ubuntu 24.04+) has a struct-layout mismatch with the 22.04-compiled WebKit. The mismatched offsets corrupt color-stop index arithmetic inside Skia's COLRv1 renderer, producing the assertion abort in issues block#2548 and block#2982: ``` stl_vector.h:1123: Assertion '__n < this->size()' failed. ... colrv1_configure_skpaint(FT_Face, ...) ... ``` ## Fix Bump the build container to `ubuntu:24.04` (noble), which ships FreeType **2.13.2**. Noble's struct layout matches every crash-affected host. The ABI mismatch disappears and the crash is eliminated at root. WebKitGTK also advances from **2.50.4** (jammy backport) to **2.52.3** (noble backport). ## Glibc floor change | Build base | glibc floor | Oldest supported AppImage distro | |---|---|---| | ubuntu:22.04 (before) | 2.35 | Ubuntu 22.04 LTS, Debian 12 | | ubuntu:24.04 (after) | 2.39 | Ubuntu 24.04 LTS, Fedora 40+ | Ubuntu 22.04 LTS and Debian 12 users lose AppImage support. Both distributions continue to receive first-class `.deb` / `.rpm` packages, which use the system WebKit and are unaffected. The crash-affected users (Fedora 42/44, Ubuntu 24.04+) all have glibc ≥ 2.39. ## Changes - `.github/workflows/linux-canary.yml:24` — container pin updated to `ubuntu:24.04@sha256:4fbb8e6a…` - `.github/workflows/release.yml:479` — same container pin updated - `.github/workflows/release.yml:501` — comment version string updated from 22.04 to 24.04 `fix-appimage.sh` and `desktop/src-tauri/**` are untouched. The block#3573 fontconfig stopgap remains active; retirement is a separate follow-on PR once this fix is verified on a shipped build. ## Sequencing `docs/linux-rendering-troubleshooting.md` (introduced in block#3573) will receive a glibc-floor callout section once block#3573 merges — adding it here would conflict with block#3573's open branch. Context: block#2548, block#2982. Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
## Summary Correlates trace + span IDs with logs, allowing traces and logs to be bridged seamlessly ### Related issue none found ### Testing Unit tests Signed-off-by: David Grochowski <dgrochowski@squareup.com> Co-authored-by: Amp <amp@ampcode.com>
…3343) ## Problem `common_binary_paths()` probes mise shims, `~/.local/bin`, volta, asdf, and (further down `resolve_command_uncached`) nvm's default bin dir — but not bun's global bin directory, `~/.bun/bin`. bun's installer appends its bin dir to `~/.zshrc` / `~/.bashrc`, which are **interactive**-only. A login shell never sources them, so `find_via_login_shell()` can't recover the path either. That's the same failure mode already called out in this file for nvm: ```rust // Check nvm's default Node.js bin directory — nvm initializes via // ~/.zshrc (interactive) which is not loaded by a login shell, so // `node`, `npm`, and npm-global shims installed there are otherwise // invisible. ``` So for a GUI-launched desktop app, every rung of the resolution ladder misses a bun-installed CLI: 1. workspace dev dirs — no 2. `command_looks_like_path` — no, presets use bare names 3. Buzz-managed npm/node dirs — no 4. current process PATH — launchd's minimal PATH on a Finder launch 5. `find_via_login_shell` — `.zshrc` not sourced 6. `common_binary_paths()` — **`~/.bun/bin` absent** 7. nvm default bin — no This matters because bun is a common install route for the agent CLIs Buzz targets. Kimi Code in particular ships as an npm package (`@moonshot-ai/kimi-code`), so `bun add -g` puts it at `~/.bun/bin/kimi` — exactly where discovery doesn't look. ## Reproduction On macOS with `codex` and `kimi` installed via bun, launching Buzz from Finder: - Kimi Code shows **"CLI needed"** - both CLIs run fine in an interactive terminal Probing the way `find_via_login_shell` does, in a clean environment: ```console $ env -i HOME=$HOME /bin/zsh -l -c 'command -v -- codex; command -v -- kimi' (nothing) ``` Launching the app with the bun dir on PATH resolves both immediately: ```console $ env PATH="$HOME/.bun/bin:$PATH" /Applications/Buzz.app/Contents/MacOS/buzz-desktop ``` ## Change One entry appended to the home-relative list in `common_binary_paths()`. It goes **last** so it cannot shadow a directory that already resolves — the change can only add resolutions, never alter existing ones. ## Testing `cargo fmt --check` passes. I was not able to run the full `just ci` gate locally: `ring 0.17.14` fails to build in this environment against the macOS 26.2 SDK (`cc` error compiling `p256-nistz.c`), which is unrelated to this change. Relying on CI for the rest — the diff adds one `PathBuf` to an existing `Vec<PathBuf>` and introduces no new API. ## Notes - Related to block#3084, which adds `~/.kimi-code/bin` for the same class of GUI-launch discovery failure. That covers Kimi's standalone installer; this covers the bun/npm-global install route. They're complementary — I've left a note on that PR. - Only `~/.bun/bin` is added. bun's global packages live under `~/.bun/install/global/node_modules` but are symlinked into `~/.bun/bin`, so the single directory is sufficient. - Worth noting `~/.bun/bin` contains no `node`/`npm`/`npx`, so appending it can't shadow a system Node toolchain. Signed-off-by: Xule Lin <43122877+linxule@users.noreply.github.com>
## What Adds `docs/linux-rendering-troubleshooting.md` — the user-facing troubleshooting page for Linux rendering failures. ## What's in the doc **Crash: `colrv1_configure_skpaint` assertion abort (AppImage, Fedora 40+)** Root cause: the AppImage bundles WebKitGTK compiled against FreeType 2.11.1, but `libfreetype.so.6` is not bundled — WebKit loads the host's FreeType at runtime. FreeType 2.13.0 added a field to `FT_ColorStopIterator` (16 → 20 bytes); on hosts with FreeType ≥ 2.13 the struct-layout mismatch corrupts Skia's COLRv1 color-stop arithmetic, causing the assertion abort. Fix: upgrade to v0.5.2+ (build container bumped to `ubuntu:24.04` in [block#3602](block#3602)). Includes the glibc floor table (2.35 → 2.39) and `.deb`/`.rpm` guidance for Ubuntu 22.04 / Debian 12 users. A manual fontconfig workaround is preserved for users stuck on older AppImages. **Blank window / dmabuf renderer (NVIDIA, AppImage)** Covers the auto-fix shipped in v0.5.1 ([block#3271](block#3271)) and the `--safe-rendering` flag for cases where auto-detection misses. **AMD RDNA4 / transparent window ([block#2643](block#2643 Documents the three-variable workaround verified by the reporter (`GDK_BACKEND=x11`, `WEBKIT_DISABLE_DMABUF_RENDERER=1`, `WEBKIT_SKIA_ENABLE_CPU_RENDERING=1`). Also includes a crash-log capture recipe and issue-filing checklist. Context: [block#2548](block#2548), [block#2982](block#2982), [block#2643](block#2643), [block#2338](block#2338). Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
## Buzz Desktop release v0.5.2 ### Changes since v0.5.1: - feat(cli): mirror Desktop mention delivery ([block#3330](block#3330)) ([`7adc46268`](block@7adc462)) - fix(desktop): deduplicate relay outage notification ([block#3579](block#3579)) ([`66e705492`](block@66e7054)) - fix(desktop): reconcile thread arrivals at bottom ([block#3585](block#3585)) ([`b42a8d447`](block@b42a8d4)) - Improve emoji autocomplete matching ([block#3571](block#3571)) ([`259de6afb`](block@259de6a)) - Fix shared agent avatar import profiles ([block#3578](block#3578)) ([`324bd6b46`](block@324bd6b)) - Fix inline raster avatars in agent catalog ([block#3581](block#3581)) ([`7e9b77f72`](block@7e9b77f)) - feat(agent): make Gemini and MLflow-route models usable through databricks_v2 ([block#3569](block#3569)) ([`4a1ebf25c`](block@4a1ebf2)) **To release:** merge this PR. The tag and build will happen automatically. Signed-off-by: Wes <wesbillman@users.noreply.github.com>
📝 WalkthroughPriority Level: P1 P1: Possible managed-authorization / signing gate regression (security)
P1: High risk of huddle/sidebar behavior regression from deleting the shared active-huddle replay subsystem
P2: Removing metadata polling can cause transient relay-propagation failures
P2: Removing v0.5.1 governance/adoption artifacts may weaken thin-adapter reset verification
P2: Rust execution proof deferred because local Rust toolchain unavailable
WalkthroughThis PR resets Hive to v0.5.2, updates CI and release metadata, preserves provider-specific tool-call data, adds stricter mention handling, refactors managed identity and company-agent flows, changes desktop interaction behavior, and migrates mobile relay-scoped preferences. Changesv0.5.2 release and tooling
Provider, CLI, and telemetry
Managed desktop and agent catalog
Desktop interaction and mobile persistence
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c0587a1b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
evaOS review status: completedPR: #82 - Reset Hive to thin Buzz v0.5.2 adapters evaOS review completed for this PR head. Automation note: agents should wait for this comment to reach PR URL: #82 Review URL: #82 (review) |
There was a problem hiding this comment.
Walkthrough
PR: #82 - Reset Hive to thin Buzz v0.5.2 adapters
Head: 7d5eacff3cfaf7e8aba14ffd4451dc13322074d1 into main. Review event: COMMENT.
Provider: Unregistered provider id (builtin:zai-coding-plan, zcode (registry miss), model unknown).
Estimated review effort: 5/5 (~70 min)
Changed Files
| File | Status | Churn | Purpose | Risk |
|---|---|---|---|---|
.github/workflows/ci.yml |
modified | +9/-4 | Changed file | Low |
.github/workflows/linux-canary.yml |
modified | +1/-1 | Changed file | Low |
.github/workflows/release.yml |
modified | +2/-2 | Changed file | Low |
AGENTS.md |
modified | +0/-5 | Documentation | Low |
CHANGELOG.md |
modified | +11/-0 | Documentation | Low |
VISION_HIVE.md |
removed | +0/-183 | Documentation | Low |
crates/buzz-acp/src/acp.rs |
modified | +0/-85 | Changed file | Low |
crates/buzz-acp/src/base_prompt.md |
modified | +2/-0 | Documentation | Low |
crates/buzz-acp/src/config.rs |
modified | +31/-1 | Configuration | Low |
crates/buzz-acp/src/lib.rs |
modified | +16/-0 | Changed file | Low |
crates/buzz-acp/src/pool.rs |
modified | +23/-4 | Changed file | Low |
crates/buzz-agent/src/agent.rs |
modified | +3/-0 | Changed file | Low |
crates/buzz-agent/src/llm.rs |
modified | +216/-11 | Changed file | Elevated: large change |
crates/buzz-agent/src/types.rs |
modified | +52/-1 | Changed file | Low |
crates/buzz-cli/src/commands/messages.rs |
modified | +251/-43 | Changed file | Moderate: validated P2 finding |
crates/buzz-cli/src/lib.rs |
modified | +47/-2 | Changed file | Low |
crates/buzz-relay/src/main.rs |
modified | +9/-1 | Changed file | Low |
crates/buzz-relay/src/telemetry.rs |
modified | +359/-3 | Changed file | Elevated: large change |
desktop/package.json |
modified | +1/-1 | Configuration | Low |
desktop/scripts/check-file-sizes.mjs |
modified | +0/-7 | Changed file | Low |
desktop/src-tauri/Cargo.lock |
modified | +1/-1 | Changed file | Low |
desktop/src-tauri/Cargo.toml |
modified | +1/-1 | Changed file | Low |
desktop/src-tauri/hive/package-contract.json |
modified | +2/-2 | Changed file | Low |
desktop/src-tauri/src/app_state.rs |
modified | +29/-10 | Changed file | Low |
desktop/src-tauri/src/app_state/signing.rs |
removed | +0/-63 | Changed file | Low |
91 additional changed files omitted from this walkthrough.
Review Signal
Validated inline findings: 3 (P0: 0, P1: 0, P2: 1, P3: 2).
Dropped findings before posting: 0. High-severity findings: 0.
Risk Taxonomy
- API compatibility: 1
- Release regression: 1
- Runtime correctness: 1
Validation and Proof
2 required validation/proof recommendation(s) selected from changed files.
- required: TypeScript/web build or CI proof - Runtime TypeScript/web files or package/config files changed. Proof: npm run build; typecheck; focused Vitest; green GitHub check.
- required: CI/release smoke proof - CI, release, launchd, or package metadata changed. Proof: green GitHub check; release-status; coverage-audit; rollback note.
Proof status: missing - 1 required validation/proof recommendation(s) missing from PR metadata.
Profile validation hints: Prefer correctness, security, data-loss, release, and regression findings over style-only feedback.
Profile proof expectations: Look for focused validation, rollback notes, and evidence appropriate to the changed surface.
Related Context
Related issues/PRs: #81.
Suggested labels: docs, tests.
Suggested reviewers: none from current metadata.
Review Settings Preview
- Profile: assertive
- Enabled sections: Review summary (inline_review); Walkthrough (inline_review); Changed-files table (walkthrough); Effort estimate (walkthrough); Related issues/PRs (walkthrough); Review status comment (sticky_status)
- Path instructions: none
- Label suggestions: none
- Reviewer suggestions: none
- Suggestion behavior: suggestions only; labels and reviewers are not auto-applied.
- Roadmap-only settings: auto-apply labels; auto-request reviewers; required status checks
Pre-merge checklist
- Inline comments target current RIGHT-side diff lines.
- No secret-like content survived into posted inline comments.
- REQUEST_CHANGES is only used when eligible P0/P1 findings survive validation.
- Required behavior proof is present or not applicable.
- Labels and reviewers are suggestions only; the bot did not auto-apply them.
Signed-off-by: Eva <eva@100yen.org>
evaOS review status: stale headPR: #82 - Reset Hive to thin Buzz v0.5.2 adapters evaOS review stopped because this queued head is no longer the live PR head. Automation note: agents should wait for this comment to reach PR URL: #82 |
Signed-off-by: Eva <eva@100yen.org>
evaOS review status: completedPR: #82 - Reset Hive to thin Buzz v0.5.2 adapters evaOS review completed for this PR head. Automation note: agents should wait for this comment to reach PR URL: #82 Review URL: #82 (review) |
There was a problem hiding this comment.
Walkthrough
PR: #82 - Reset Hive to thin Buzz v0.5.2 adapters
Head: 0bce7e9dbc3e781a7158abb4536c6344a8919070 into main. Review event: COMMENT.
Provider: Unregistered provider id (builtin:zai-coding-plan, zcode (registry miss), model unknown).
Estimated review effort: 5/5 (~70 min)
Changed Files
| File | Status | Churn | Purpose | Risk |
|---|---|---|---|---|
.github/workflows/ci.yml |
modified | +9/-4 | Changed file | Low |
.github/workflows/linux-canary.yml |
modified | +1/-1 | Changed file | Low |
.github/workflows/release.yml |
modified | +2/-2 | Changed file | Low |
AGENTS.md |
modified | +0/-5 | Documentation | Low |
CHANGELOG.md |
modified | +11/-0 | Documentation | Low |
VISION_HIVE.md |
removed | +0/-183 | Documentation | Low |
crates/buzz-acp/src/acp.rs |
modified | +0/-85 | Changed file | Low |
crates/buzz-acp/src/base_prompt.md |
modified | +2/-0 | Documentation | Low |
crates/buzz-acp/src/config.rs |
modified | +31/-1 | Configuration | Low |
crates/buzz-acp/src/lib.rs |
modified | +16/-0 | Changed file | Low |
crates/buzz-acp/src/pool.rs |
modified | +23/-4 | Changed file | Low |
crates/buzz-agent/src/agent.rs |
modified | +3/-0 | Changed file | Low |
crates/buzz-agent/src/llm.rs |
modified | +216/-11 | Changed file | Moderate: validated P3 finding |
crates/buzz-agent/src/types.rs |
modified | +52/-1 | Changed file | Low |
crates/buzz-cli/src/commands/messages.rs |
modified | +251/-43 | Changed file | Elevated: validated P1 finding |
crates/buzz-cli/src/lib.rs |
modified | +47/-2 | Changed file | Low |
crates/buzz-relay/src/main.rs |
modified | +9/-1 | Changed file | Low |
crates/buzz-relay/src/telemetry.rs |
modified | +359/-3 | Changed file | Moderate: validated P3 finding |
desktop/package.json |
modified | +1/-1 | Configuration | Low |
desktop/scripts/check-file-sizes.mjs |
modified | +0/-7 | Changed file | Low |
desktop/src-tauri/Cargo.lock |
modified | +1/-1 | Changed file | Low |
desktop/src-tauri/Cargo.toml |
modified | +1/-1 | Changed file | Low |
desktop/src-tauri/hive/package-contract.json |
modified | +2/-2 | Changed file | Low |
desktop/src-tauri/src/app_state.rs |
modified | +29/-10 | Changed file | Low |
desktop/src-tauri/src/app_state/signing.rs |
removed | +0/-63 | Changed file | Low |
93 additional changed files omitted from this walkthrough.
Review Signal
Validated inline findings: 4 (P0: 0, P1: 1, P2: 1, P3: 2).
Dropped findings before posting: 0. High-severity findings: 1.
Risk Taxonomy
- Runtime correctness: 4
Validation and Proof
2 required validation/proof recommendation(s) selected from changed files.
- required: TypeScript/web build or CI proof - Runtime TypeScript/web files or package/config files changed. Proof: npm run build; typecheck; focused Vitest; green GitHub check.
- required: CI/release smoke proof - CI, release, launchd, or package metadata changed. Proof: green GitHub check; release-status; coverage-audit; rollback note.
Proof status: missing - 1 required validation/proof recommendation(s) missing from PR metadata.
Profile validation hints: Prefer correctness, security, data-loss, release, and regression findings over style-only feedback.
Profile proof expectations: Look for focused validation, rollback notes, and evidence appropriate to the changed surface.
Related Context
Related issues/PRs: #81.
Suggested labels: bug, docs, tests.
Suggested reviewers: none from current metadata.
Review Settings Preview
- Profile: assertive
- Enabled sections: Review summary (inline_review); Walkthrough (inline_review); Changed-files table (walkthrough); Effort estimate (walkthrough); Related issues/PRs (walkthrough); Review status comment (sticky_status)
- Path instructions: none
- Label suggestions: none
- Reviewer suggestions: none
- Suggestion behavior: suggestions only; labels and reviewers are not auto-applied.
- Roadmap-only settings: auto-apply labels; auto-request reviewers; required status checks
Pre-merge checklist
- Inline comments target current RIGHT-side diff lines.
- No secret-like content survived into posted inline comments.
- REQUEST_CHANGES is only used when eligible P0/P1 findings survive validation.
- Required behavior proof is present or not applicable.
- Labels and reviewers are suggestions only; the bot did not auto-apply them.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0bce7e9dbc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
evaOS review status: stale headPR: #82 - Reset Hive to thin Buzz v0.5.2 adapters evaOS review stopped because this queued head is no longer the live PR head. Automation note: agents should wait for this comment to reach PR URL: #82 |
evaOS review status: completedPR: #82 - Reset Hive to thin Buzz v0.5.2 adapters evaOS review completed for this PR head. Automation note: agents should wait for this comment to reach PR URL: #82 Review URL: #82 (review) |
There was a problem hiding this comment.
Walkthrough
PR: #82 - Reset Hive to thin Buzz v0.5.2 adapters
Head: ec2bf14273e2f9131df603e34fa111f40cc74cf6 into main. Review event: COMMENT.
Provider: Unregistered provider id (builtin:zai-coding-plan, zcode (registry miss), model unknown).
Estimated review effort: 5/5 (~70 min)
Changed Files
| File | Status | Churn | Purpose | Risk |
|---|---|---|---|---|
.github/workflows/ci.yml |
modified | +9/-4 | Changed file | Low |
.github/workflows/linux-canary.yml |
modified | +1/-1 | Changed file | Low |
.github/workflows/release.yml |
modified | +2/-2 | Changed file | Low |
AGENTS.md |
modified | +0/-5 | Documentation | Low |
CHANGELOG.md |
modified | +11/-0 | Documentation | Low |
VISION_HIVE.md |
removed | +0/-183 | Documentation | Low |
crates/buzz-acp/src/acp.rs |
modified | +0/-85 | Changed file | Low |
crates/buzz-acp/src/base_prompt.md |
modified | +2/-0 | Documentation | Low |
crates/buzz-acp/src/config.rs |
modified | +31/-1 | Configuration | Low |
crates/buzz-acp/src/lib.rs |
modified | +16/-0 | Changed file | Low |
crates/buzz-acp/src/pool.rs |
modified | +23/-4 | Changed file | Low |
crates/buzz-agent/src/agent.rs |
modified | +3/-0 | Changed file | Low |
crates/buzz-agent/src/llm.rs |
modified | +216/-11 | Changed file | Elevated: large change |
crates/buzz-agent/src/types.rs |
modified | +52/-1 | Changed file | Low |
crates/buzz-cli/src/commands/messages.rs |
modified | +251/-43 | Changed file | Elevated: validated P1 finding |
crates/buzz-cli/src/lib.rs |
modified | +47/-2 | Changed file | Low |
crates/buzz-relay/src/main.rs |
modified | +9/-1 | Changed file | Low |
crates/buzz-relay/src/telemetry.rs |
modified | +359/-3 | Changed file | Elevated: large change |
desktop/package.json |
modified | +1/-1 | Configuration | Low |
desktop/scripts/check-file-sizes.mjs |
modified | +0/-7 | Changed file | Low |
desktop/src-tauri/Cargo.lock |
modified | +1/-1 | Changed file | Low |
desktop/src-tauri/Cargo.toml |
modified | +1/-1 | Changed file | Low |
desktop/src-tauri/hive/package-contract.json |
modified | +2/-2 | Changed file | Low |
desktop/src-tauri/src/app_state.rs |
modified | +29/-10 | Changed file | Low |
desktop/src-tauri/src/app_state/signing.rs |
removed | +0/-63 | Changed file | Low |
94 additional changed files omitted from this walkthrough.
Review Signal
Validated inline findings: 3 (P0: 0, P1: 1, P2: 1, P3: 1).
Dropped findings before posting: 0. High-severity findings: 1.
Risk Taxonomy
- API compatibility: 1
- Runtime correctness: 2
Validation and Proof
2 required validation/proof recommendation(s) selected from changed files.
- required: TypeScript/web build or CI proof - Runtime TypeScript/web files or package/config files changed. Proof: npm run build; typecheck; focused Vitest; green GitHub check.
- required: CI/release smoke proof - CI, release, launchd, or package metadata changed. Proof: green GitHub check; release-status; coverage-audit; rollback note.
Proof status: missing - 1 required validation/proof recommendation(s) missing from PR metadata.
Profile validation hints: Prefer correctness, security, data-loss, release, and regression findings over style-only feedback.
Profile proof expectations: Look for focused validation, rollback notes, and evidence appropriate to the changed surface.
Related Context
Related issues/PRs: #81.
Suggested labels: bug, docs, tests.
Suggested reviewers: none from current metadata.
Review Settings Preview
- Profile: assertive
- Enabled sections: Review summary (inline_review); Walkthrough (inline_review); Changed-files table (walkthrough); Effort estimate (walkthrough); Related issues/PRs (walkthrough); Review status comment (sticky_status)
- Path instructions: none
- Label suggestions: none
- Reviewer suggestions: none
- Suggestion behavior: suggestions only; labels and reviewers are not auto-applied.
- Roadmap-only settings: auto-apply labels; auto-request reviewers; required status checks
Pre-merge checklist
- Inline comments target current RIGHT-side diff lines.
- No secret-like content survived into posted inline comments.
- REQUEST_CHANGES is only used when eligible P0/P1 findings survive validation.
- Required behavior proof is present or not applicable.
- Labels and reviewers are suggestions only; the bot did not auto-apply them.
There was a problem hiding this comment.
💡 Codex Review
When a status refresh returns reauth_required or identity_restore_required—for example after server-side revocation or a failed entitlement refresh—this branch clears native authorization but does not call revoke_managed_access, unlike logout and expiry. Any running managed-agent child therefore retains its injected relay URL, private key, and auth tag and can continue collaborating while Hive reports access as revoked; route all authorization-loss branches through the agent-shutdown path.
AGENTS.md reference: AGENTS.md:L163-L166
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
evaOS review status: completedPR: #82 - Reset Hive to thin Buzz v0.5.2 adapters evaOS review completed for this PR head. Automation note: agents should wait for this comment to reach PR URL: #82 Review URL: #82 (review) |
There was a problem hiding this comment.
Walkthrough
PR: #82 - Reset Hive to thin Buzz v0.5.2 adapters
Head: 12d94d24a05d1bb7297f47e2d8a0a0d9e1876c32 into main. Review event: COMMENT.
Provider: Unregistered provider id (builtin:zai-coding-plan, zcode (registry miss), model unknown).
Estimated review effort: 5/5 (~70 min)
Changed Files
| File | Status | Churn | Purpose | Risk |
|---|---|---|---|---|
.github/workflows/ci.yml |
modified | +9/-4 | Changed file | Moderate: validated P3 finding |
.github/workflows/linux-canary.yml |
modified | +1/-1 | Changed file | Low |
.github/workflows/release.yml |
modified | +2/-2 | Changed file | Low |
AGENTS.md |
modified | +0/-5 | Documentation | Low |
CHANGELOG.md |
modified | +11/-0 | Documentation | Low |
VISION_HIVE.md |
removed | +0/-183 | Documentation | Low |
crates/buzz-acp/src/acp.rs |
modified | +0/-85 | Changed file | Elevated: validated P1 finding |
crates/buzz-acp/src/base_prompt.md |
modified | +2/-0 | Documentation | Low |
crates/buzz-acp/src/config.rs |
modified | +31/-1 | Configuration | Low |
crates/buzz-acp/src/lib.rs |
modified | +16/-0 | Changed file | Low |
crates/buzz-acp/src/pool.rs |
modified | +23/-4 | Changed file | Low |
crates/buzz-agent/src/agent.rs |
modified | +3/-0 | Changed file | Low |
crates/buzz-agent/src/llm.rs |
modified | +216/-11 | Changed file | Elevated: large change |
crates/buzz-agent/src/types.rs |
modified | +52/-1 | Changed file | Low |
crates/buzz-cli/src/commands/messages.rs |
modified | +251/-43 | Changed file | Moderate: validated P2 finding |
crates/buzz-cli/src/lib.rs |
modified | +47/-2 | Changed file | Low |
crates/buzz-relay/src/main.rs |
modified | +9/-1 | Changed file | Low |
crates/buzz-relay/src/telemetry.rs |
modified | +359/-3 | Changed file | Elevated: large change |
desktop/package.json |
modified | +1/-1 | Configuration | Low |
desktop/scripts/check-file-sizes.mjs |
modified | +0/-7 | Changed file | Low |
desktop/src-tauri/Cargo.lock |
modified | +1/-1 | Changed file | Low |
desktop/src-tauri/Cargo.toml |
modified | +1/-1 | Changed file | Low |
desktop/src-tauri/hive/package-contract.json |
modified | +2/-2 | Changed file | Low |
desktop/src-tauri/src/app_state.rs |
modified | +29/-10 | Changed file | Low |
desktop/src-tauri/src/app_state/signing.rs |
removed | +0/-63 | Changed file | Low |
95 additional changed files omitted from this walkthrough.
Review Signal
Validated inline findings: 3 (P0: 0, P1: 1, P2: 1, P3: 1).
Dropped findings before posting: 0. High-severity findings: 1.
Risk Taxonomy
- API compatibility: 1
- CI/build: 1
- Runtime correctness: 1
Validation and Proof
2 required validation/proof recommendation(s) selected from changed files.
- required: TypeScript/web build or CI proof - Runtime TypeScript/web files or package/config files changed. Proof: npm run build; typecheck; focused Vitest; green GitHub check.
- required: CI/release smoke proof - CI, release, launchd, or package metadata changed. Proof: green GitHub check; release-status; coverage-audit; rollback note.
Proof status: missing - 1 required validation/proof recommendation(s) missing from PR metadata.
Profile validation hints: Prefer correctness, security, data-loss, release, and regression findings over style-only feedback.
Profile proof expectations: Look for focused validation, rollback notes, and evidence appropriate to the changed surface.
Related Context
Related issues/PRs: #81.
Suggested labels: bug, docs, tests.
Suggested reviewers: none from current metadata.
Review Settings Preview
- Profile: assertive
- Enabled sections: Review summary (inline_review); Walkthrough (inline_review); Changed-files table (walkthrough); Effort estimate (walkthrough); Related issues/PRs (walkthrough); Review status comment (sticky_status)
- Path instructions: none
- Label suggestions: none
- Reviewer suggestions: none
- Suggestion behavior: suggestions only; labels and reviewers are not auto-applied.
- Roadmap-only settings: auto-apply labels; auto-request reviewers; required status checks
Pre-merge checklist
- Inline comments target current RIGHT-side diff lines.
- No secret-like content survived into posted inline comments.
- REQUEST_CHANGES is only used when eligible P0/P1 findings survive validation.
- Required behavior proof is present or not applicable.
- Labels and reviewers are suggestions only; the bot did not auto-apply them.
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
desktop/src/features/evaosTeams/api.test.mjs (1)
80-91: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd an unmanaged recovery-phase case.
The implementation also requires
managed === true, but the new cases only distinguish the phase andnullstatus. Add anidentity_restore_requiredstatus withmanaged: falseand assertfalse; otherwise a regression to phase-only matching would pass while incorrectly showing native identity recovery for unmanaged users. Confidence: 97%.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@desktop/src/features/evaosTeams/api.test.mjs` around lines 80 - 91, Add an assertion in the test for evaosTeamsNeedsNativeIdentityRecovery covering status("identity_restore_required") with managed set to false, and verify it returns false while preserving the existing managed and null-status cases.desktop/src-tauri/src/commands/identity.rs (1)
281-334: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
persist_current_identityis missing the managed-identity-recovery gate thatimport_identityjust gained. Confidence: 60%.Both functions previously had a compile-time
evaos-teams-managedrejection; both now run unconditionally.import_identity(Line 217) was updated to callcrate::evaos_teams::prepare_managed_identity_recovery(&app_handle, &state)?before mutating identity state, butpersist_current_identitystill does none of that — it goes straight from acquiringidentity_mutationto persisting keys and clearingidentity_lost.Root cause: this function also finalizes a new signing identity (the currently-loaded ephemeral key becomes permanent), which is exactly the class of operation the sibling fix targets ("Managed identity replacement denied during active entitlement"). Today's call graph likely makes this hard to trigger while managed access is genuinely active —
identity_lostis only set at boot (perAppStatedoc comments),relay_url_overrideresets toNoneevery process start, andnative_identity_for_managed_verificationfails whileidentity_lostis true, which typically preventsinstall_entitlementfrom ever re-armingrelay_url_overridebefore this path is reached. But that's an indirect, multi-hop invariant across three files, not an explicit guard — any future change torestore.rs's new authorization gate, or a state whereidentity_lostgets set without a clean fresh boot, would silently reopen a path to finalize an identity swap while a managed agent is still running and authorized, unlikeimport_identity.Add the same guard for defense-in-depth and to keep the two identity-mutation entry points consistent.
🔒 Proposed fix
tokio::task::spawn_blocking(move || { let state = app_handle.state::<AppState>(); // Acquire mutation lock before reading identity_lost so that a // concurrent import_identity cannot complete between our check and // our persist, which would let the stale ephemeral key overwrite the // imported one. let _mutation_guard = state.identity_mutation.lock().map_err(|e| e.to_string())?; + crate::evaos_teams::prepare_managed_identity_recovery(&app_handle, &state)?; if !state .identity_lost .load(std::sync::atomic::Ordering::Acquire) { return Err("identity is not in a lost state".to_string()); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@desktop/src-tauri/src/commands/identity.rs` around lines 281 - 334, Update persist_current_identity to call crate::evaos_teams::prepare_managed_identity_recovery(&app_handle, &state)? immediately after acquiring identity_mutation and before checking or persisting identity state, matching import_identity’s guard while preserving the existing persistence flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@desktop/src-tauri/src/evaos_teams/authorization.rs`:
- Around line 41-77: Update schedule_managed_access_expiry so failures from
revoke_managed_access trigger bounded retries with backoff instead of only
logging and exiting. Retry the cleanup while the revoke operation continues to
report failure, preserve the expiry recheck and existing successful no-op
behavior, and stop after a finite attempt limit while retaining the error log.
In `@desktop/src-tauri/src/shutdown.rs`:
- Around line 258-294: Preserve per-record shutdown failures across all runtime
pairs by aggregating failed agent indices before clearing error fields. Update
the shutdown loop around the `to_stop` iteration and `records[agent.idx]`
updates to track every `idx` whose process remains running, then only clear
`last_error` and `last_error_code` in the success path when that index has no
recorded failure; retain the existing failure recording and `shutdown_errors`
behavior.
In `@desktop/src/features/evaosTeams/api.test.mjs`:
- Around line 31-53: Replace the removed logout-gate regression coverage with
assertions using the current API or outer gate behavior, verifying that managed
sign-out reloads for signed-out, pending, and error states. Keep the existing
evaosTeamsRefreshDelay tests unchanged and anchor the new cases to the current
gate/API symbols rather than the deleted implementation.
In `@desktop/src/features/messages/ui/useNewMessageRecipients.ts`:
- Line 91: Make company-agent discovery lifecycle-aware by passing an enabled
option tied to active in useNewMessageRecipients.ts at lines 91-91, and tied to
open in MembersSidebar.tsx at lines 188-188, when calling useCompanyVmAgents.
Ensure both relay and authorization queries remain disabled while their
respective surfaces are inactive.
---
Outside diff comments:
In `@desktop/src-tauri/src/commands/identity.rs`:
- Around line 281-334: Update persist_current_identity to call
crate::evaos_teams::prepare_managed_identity_recovery(&app_handle, &state)?
immediately after acquiring identity_mutation and before checking or persisting
identity state, matching import_identity’s guard while preserving the existing
persistence flow.
In `@desktop/src/features/evaosTeams/api.test.mjs`:
- Around line 80-91: Add an assertion in the test for
evaosTeamsNeedsNativeIdentityRecovery covering
status("identity_restore_required") with managed set to false, and verify it
returns false while preserving the existing managed and null-status cases.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 891d602c-463f-433d-8861-fe108ed85e06
📒 Files selected for processing (14)
desktop/src-tauri/src/commands/identity.rsdesktop/src-tauri/src/evaos_teams.rsdesktop/src-tauri/src/evaos_teams/authorization.rsdesktop/src-tauri/src/evaos_teams/http_api.rsdesktop/src-tauri/src/huddle/relay_api.rsdesktop/src-tauri/src/managed_agents/restore.rsdesktop/src-tauri/src/relay.rsdesktop/src-tauri/src/shutdown.rsdesktop/src/features/agents/lib/agentAutocompleteEligibility.test.mjsdesktop/src/features/agents/lib/agentAutocompleteEligibility.tsdesktop/src/features/channels/ui/MembersSidebar.tsxdesktop/src/features/evaosTeams/api.test.mjsdesktop/src/features/evaosTeams/api.tsdesktop/src/features/messages/ui/useNewMessageRecipients.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (17)
- GitHub Check: Desktop E2E Integration (1/2)
- GitHub Check: Relay E2E
- GitHub Check: Desktop E2E Integration (2/2)
- GitHub Check: Server Cross-Compile (aarch64-unknown-linux-musl)
- GitHub Check: Desktop Smoke E2E (1)
- GitHub Check: Desktop Smoke E2E (3)
- GitHub Check: Desktop Smoke E2E (4)
- GitHub Check: Desktop Smoke E2E (2)
- GitHub Check: Server Cross-Compile (x86_64-unknown-linux-musl)
- GitHub Check: Windows Rust (x86_64-pc-windows-msvc)
- GitHub Check: Desktop Build (macOS)
- GitHub Check: Rust Lint
- GitHub Check: Desktop Core
- GitHub Check: Unit Tests
- GitHub Check: Mobile
- GitHub Check: Analyze (rust)
- GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.rs: Do not introduceunsafeRust code.
Do not introduce newunwrap()orexpect()calls in production paths; use?and proper error types.
Add doc comments to every new public Rust API.
Files:
desktop/src-tauri/src/huddle/relay_api.rsdesktop/src-tauri/src/evaos_teams/http_api.rsdesktop/src-tauri/src/managed_agents/restore.rsdesktop/src-tauri/src/relay.rsdesktop/src-tauri/src/shutdown.rsdesktop/src-tauri/src/evaos_teams/authorization.rsdesktop/src-tauri/src/commands/identity.rsdesktop/src-tauri/src/evaos_teams.rs
desktop/**/*.{ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use rem-based named text-size tokens; do not use arbitrary px, rem, or em text-size literals.
Files:
desktop/src/features/evaosTeams/api.tsdesktop/src/features/messages/ui/useNewMessageRecipients.tsdesktop/src/features/agents/lib/agentAutocompleteEligibility.tsdesktop/src/features/channels/ui/MembersSidebar.tsx
desktop/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
When adding a community-scoped module-level cache, Map, or class instance, add its reset to
resetCommunityState()inuseCommunityInit.ts.
Files:
desktop/src/features/evaosTeams/api.tsdesktop/src/features/messages/ui/useNewMessageRecipients.tsdesktop/src/features/agents/lib/agentAutocompleteEligibility.tsdesktop/src/features/channels/ui/MembersSidebar.tsx
desktop/src/features/agents/**/*.{test,spec}.{ts,tsx,mjs}
📄 CodeRabbit inference engine (desktop/src/features/agents/AGENTS.md)
Update and preserve tests covering the agent configuration core, field contracts, discovery status/cache behavior, onboarding defaults acceptance flow, runtime environment-key application, and company responder visibility/projection whenever the corresponding behavior changes.
Files:
desktop/src/features/agents/lib/agentAutocompleteEligibility.test.mjs
desktop/src/features/agents/**/*.{ts,tsx}
📄 CodeRabbit inference engine (desktop/src/features/agents/AGENTS.md)
desktop/src/features/agents/**/*.{ts,tsx}: Do not hardcode harness-ID checks in render code. Runtime-ID logic such asruntime.id === "claude"belongs once inderiveAgentConfigFieldModelwith a named reason; components must query field-model helpers such ashasRenderableAgentConfigFieldandgetRenderableEffortField.
Read and write effort through the effort descriptor’scurrentPersistencekey, never through a rawBUZZ_AGENT_THINKING_EFFORTliteral in UI code. Do not conflatecurrentPersistencewithtargetApplicationwithout performing the planned migration.
Represent field absence with namedAgentConfigOmission/renderreasons, such asownedByModelIdordeferredUntilNativeOptionsAvailable, rather than booleanshowXprops.
Use the named clearing policiesonContextChange: "resetDependentValues"andonCatalogMismatch: "explainOnly" | "onboardingCleanup"; do not introduce mutation booleans such asclearInvalidModel.
Treatruntime: undefinedas metadata unknown, not lack of capability. Surfaces must wait for runtime-catalog loading/error resolution and render explicit states instead of silently hiding fields.
Use one canonical configuration behavior and express surface differences throughdisclosurepresets, not new behavior boolean props.onboarding-essentialmay hide helper descriptions, but non-null model-discovery status must still render viashouldShowModelStatusMessage(). Empty successful discovery must synthesize a warning and remain uncached so reopening retries discovery.
Onboarding setup detects harness readiness and offers only install/sign-in actions; it must not select defaults. The defaults page alone selects and persistspreferred_runtime.
Hide the Model control only after confirmed successful empty discovery on an optional-modelacpNativeharness. Keep it during loading and failed/unavailable discovery, preserve persisted model/effort on failure, show it for required-model harnesses, and show it in full disclosur...
Files:
desktop/src/features/agents/lib/agentAutocompleteEligibility.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: electricsheephq/evaOS-Hive
Timestamp: 2026-07-30T11:10:02.894Z
Learning: Prefer Nostr events and existing event kinds over adding new HTTP endpoints; use HTTP only for genuinely HTTP-specific surfaces.
🔇 Additional comments (14)
desktop/src/features/evaosTeams/api.test.mjs (1)
6-6: LGTM!desktop/src-tauri/src/commands/identity.rs (1)
204-266: Correct ordering: recovery gate runs before any keyring mutation.
prepare_managed_identity_recoveryis invoked at Line 217, inside theidentity_mutationguard and before any filesystem/keyring writes — so a denied recovery (active entitlement) aborts cleanly with no partial state. Matches the stated contract of serializing entitlement install against identity mutation.desktop/src-tauri/src/evaos_teams.rs (1)
24-41: LGTM!Also applies to: 381-417, 500-526, 529-550, 681-780, 912-927
desktop/src-tauri/src/evaos_teams/authorization.rs (1)
1-18: LGTM!Also applies to: 29-39, 79-100, 102-133, 157-245
desktop/src-tauri/src/evaos_teams/http_api.rs (1)
1-87: LGTM!Straightforward extraction of the managed-API HTTP client into its own module; timeout, publishable-key guard, and error taxonomy (
means_session_is_absent) are all preserved from the description. This is a genuinely HTTP-specific surface (Supabase auth/entitlement functions), consistent with preferring Nostr events elsewhere and reserving HTTP for cases that require it.Based on learnings: "Prefer Nostr events and existing event kinds over adding new HTTP endpoints; use HTTP only for genuinely HTTP-specific surfaces."
Source: Learnings
desktop/src-tauri/src/huddle/relay_api.rs (1)
55-56: LGTM!desktop/src-tauri/src/shutdown.rs (1)
149-180: LGTM!The
AgentToStoprestructure and the new post-SIGKILL confirm-wait loop correctly close the prior gap of never reaping the trackedChildhandles (sotry_waitactually gets called and exit codes get captured before final reconciliation).Also applies to: 195-240
desktop/src-tauri/src/managed_agents/restore.rs (1)
285-289: 🎯 Functional CorrectnessNo change needed — this guard only blocks premature spawns. Launch-time restore is driven by
apply_workspaceaftermanaged_agent_restore_pendingis set and the managed relay/identity are in place, sorequire_managed_authorizationhere does not permanently skip auto-start agents. Confidence: 91%.> Likely an incorrect or invalid review comment.desktop/src/features/evaosTeams/api.ts (1)
29-31: LGTM!Also applies to: 47-65, 118-123
desktop/src-tauri/src/relay.rs (1)
107-107: LGTM!Also applies to: 550-551, 565-566
desktop/src/features/agents/lib/agentAutocompleteEligibility.test.mjs (1)
6-8: LGTM!Also applies to: 50-50, 109-112, 137-137, 179-179
desktop/src/features/agents/lib/agentAutocompleteEligibility.ts (1)
36-49: LGTM!Also applies to: 61-61, 71-87
desktop/src/features/channels/ui/MembersSidebar.tsx (1)
12-14: LGTM!Also applies to: 276-281, 292-292, 340-341, 371-385
desktop/src/features/messages/ui/useNewMessageRecipients.ts (1)
9-12: LGTM!Also applies to: 114-121, 189-191, 225-238
Refs #81
Outcome
Thin-adapter boundaries
Focused proof on exact head 915cf4c
Reset integration
The history-only merge c3371ad records the old fork main as replaced without changing the v0.5.2-es source tree. Its tree equals the reviewed pre-merge tree. The file-size ratchet uses exact v0.5.2 only at this adoption boundary and automatically returns to normal PR bases once main contains the adopted tree.
Proof boundary
This draft PR is source-only. It does not prove merge, artifact, installed runtime, internal acceptance, distribution, or customer release.