Sync upstream Buzz 014562c063ea - #14
Open
dcm-buzz-upstream-sync[bot] wants to merge 12 commits into
Open
Conversation
…ds (block#4802) User-facing error for missing ACP harness commands has been pointing released-build users to run `cargo build --release --workspace` and read TESTING.md — both dead ends for anyone not building from source. Updated message acknowledges that antivirus software can quarantine bundled binaries and provides practical remediation steps. Preserves pointer to TESTING.md for source builds. Fixes issue context from block#4491. Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub16v54tttfqacx9ycvc3k0ut0npj564ahcuajzy6qjvh57ntmsf4uq4806j2 <d32955ad69077062930cc46cfe2df30ca9aaf6f8e76422681265e9e9af704d78@buzz.block.builderlab.xyz>
### What changed? Serializes channel-section relay synchronization so a late relay `CLOSED` cannot overlap an in-flight retry and install duplicate subscriptions. Pending subscription results are invalidated and immediately closed when the manager is disposed or superseded. ### Why? The startup retry added in block#3004 could race with a late `CLOSED` or manager disposal, leaking an untracked live subscription. This keeps retry recovery single-flight and makes the lifecycle boundary explicit. ### How is it tested? Build and run. Added tests: - [`ChannelSectionsManager`](https://github.com/block/buzz/tree/main/mobile/test/features/channels/channel_sections/channel_sections_manager_test.dart) interleaving coverage for in-flight retry serialization and disposal during subscription setup *🤖 This PR was authored with a Buzz agent.* Signed-off-by: npub15w828kxsxu2684ynste0uah2jwkgatd99flt7ds4523hzm8ju6cshdr8hh <a38ea3d8d03715a3d49382f2fe76ea93ac8eada52a7ebf3615a2a3716cf2e6b1@buzz.block.builderlab.xyz> Co-authored-by: npub15w828kxsxu2684ynste0uah2jwkgatd99flt7ds4523hzm8ju6cshdr8hh <a38ea3d8d03715a3d49382f2fe76ea93ac8eada52a7ebf3615a2a3716cf2e6b1@buzz.block.builderlab.xyz>
## Summary - reserve kind `30179` for owner-private managed-agent aggregates - define the fail-closed owner-self NIP-44 v2 envelope and versioned payload codec - bind runnable identity/configuration to complete signed `30175`/`30177` recovery projections - validate NIP-OA owner→agent attestations and reject self-attestation - document NIP-PMA authority, migration prerequisites, privacy, and deployment order - keep generic relay ingest closed until private storage and atomic aggregate CAS exist ## Safety boundary This is the inert protocol/codec slice only. It does not publish secrets, change agent authority, migrate local records, or enable kind `30179` ingestion. The relay regression test proves generic EVENT ingest still rejects the kind. The finalized migration plan adds later prerequisites for relay-private storage/CAS, runtime lease/fencing, Desktop cutover, and harness authentication. Those belong in staged follow-up PRs rather than expanding this inert foundation. ## Validation At commit `67f0ea4ebb8d3ccba3a3eb9374e89a7178913f74`: - `cargo test -p buzz-core` — 246 unit + 2 doc tests passed - `cargo test -p buzz-relay private_managed_agent_kind_remains_rejected_until_atomic_ingest_exists` — passed - push hooks: Rust tests and desktop checks passed (`2145` desktop tests passed, `14` ignored) - `cargo fmt --all -- --check` - `git diff --check` ## Review Princess Donut cleared security/data integrity with no remaining high/medium findings. Mongo cleared migration compatibility and wire grammar. The later runtime lease/fencing protocol was also adversarially cleared as a plan; implementation slices still require independent evidence before activation. Deterministic plaintext/signed-projection/auth-tag interoperability vectors remain a valuable follow-up, not an S0 merge gate; random NIP-44 ciphertext is intentionally not snapshotted. --------- Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
… the turn (block#4896) ## Problem `buzz-dev-mcp` advertises `view_image` to every agent regardless of whether the session's model accepts images. When a text-only model (e.g. DeepSeek V4 Flash) takes the bait, the image lands in session history and every subsequent LLM request 404s with `No endpoints found that support image input`. The error was classified as `LlmModelNotFound` and propagated fatally out of the turn loop — history stays poisoned, buzz-acp retries the batch with exponential backoff, and the session burns its entire clock doing no work. In a recent trial run, **all 57 trials that called `view_image` on a text-only model died this way; none recovered.** ## Fix Capability-gating the advertised tool isn't reliable — there is no image-capability metadata at the agent layer across providers. Instead, recover at the turn loop: - **Typed error**: new `AgentError::UnsupportedImageInput`, classified narrowly on the exact provider phrase `No endpoints found that support image input` on both the generic 404 path and OpenRouter's 404 path. Unknown-model 404s and OpenRouter parameter-routing 404s keep their existing classifications. No deterministic retry. - **In-turn recovery**: on this error, `RunCtx::run` strips every image block from history — keeping the tool result (and therefore tool-call/result pairing) intact — marks the result `is_error`, appends actionable model-facing guidance ("The current model does not support image input. The image was removed from conversation history so this turn can continue. Use a text-based inspection tool…"), and continues the same turn. Base64 never replays again. - **Loop guard**: recovery only fires when at least one image was removed; if the provider says "image" and history has none, the error propagates as before. ## Tests - Unit: phrase classification (typed, not retried; unknown-model 404 unaffected), idempotent image-to-error history mutation preserving call IDs and text. - End-to-end (`fake_llm.rs` + `fake_mcp.rs`): tool call → MCP image result → 404 unsupported-image → same-turn recovery. Captured requests prove round 2 carried the image, round 3 replays no image, carries the guidance text, preserves pairing, and ends `end_turn`. - Loop guard: typed unsupported-image error with **no** image in history fails after exactly one provider request instead of spinning — mutation-testing showed deleting the `removed == 0` guard survived the suite, and `max_rounds` defaults to unlimited in production, so this branch needed direct coverage. Verified at `a210305019b33d5f56677b4c82bab79e4ac52d24`: `cargo test -p buzz-agent` (full package, 381 unit + all integration suites) green; `clippy --all-targets -D warnings` green; `fmt --check` green; pre-push hooks (rust-tests, desktop-tauri-checks, branch-skew) green. **Scope of the classification guarantee**: the classifier runs in the shared `post()` (which Anthropic and OpenAI paths route through) and in `openrouter_post()` — i.e., every 404 path in `llm.rs`. It only runs on 404 responses; providers that reject images with a different status (e.g. a 400) are out of scope for this PR — see the review-comment discussion for why broadening the phrase list alone would not cover them. Authored by Wren, loop-guard test by Sami, reviewed by Eva. --------- Signed-off-by: Wren <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@buzz.block.builderlab.xyz> Signed-off-by: Sami <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@buzz.block.builderlab.xyz> Co-authored-by: Wren <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@buzz.block.builderlab.xyz> Co-authored-by: Sami <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@buzz.block.builderlab.xyz>
This change rechecks the durable community ban in the shared Git HTTP authentication path for advertise, fetch, and push requests. A banned member is denied even if repository-channel membership still exists, and restriction lookup errors fail closed. The additional database lookup happens on every Git HTTP request so access revocation does not depend on stale session state. The check also cascades to the NIP-OA owner. Git accepts NIP-OA attestations on the NIP-98 token, so an agent key can act for its owner — without the cascade, a banned human would keep clone and push access through any agent key. This mirrors the NIP-42 gate in `handlers::auth`: either principal's ban denies the request. The check runs inside the `GitAuth` extractor, so all three Git routes inherit it. ## Testing - `git diff --check origin/main...codex/security-ban-revokes-git` - Rebased onto `origin/main` at `5c98932` - `cargo test -p buzz-relay --lib sec005_read_gate_tests`: 8 passed, 7 ignored (Postgres) - `cargo clippy -p buzz-relay --all-targets -- -D warnings` and `cargo fmt --check`: clean Pure tests cover the decision table (agent ban, inherited owner ban, no attestation). Postgres-gated tests cover the wiring: the real ban row, a live `compute_auth_tag` attestation, and the 503 fail-closed path. **Not yet verified:** the three Postgres-gated tests compile and skip but have not been run — no local Postgres, and CI does not run `--ignored`. They need `cargo test -p buzz-relay --lib sec005_read_gate_tests -- --ignored` against a migrated dev database. Originating Buzz thread: `buzz://message?channel=3928fe05-df61-4b5d-b9c7-d623b9b10ea1&id=3c6c02312f763fbe0d2bfc33a6c1a362f91d0354f3d18b039cf7a0558c1439d1` --------- Signed-off-by: Jordan Mecom <jm@squareup.com> Signed-off-by: Eli Foster <efoster@squareup.com> Co-authored-by: Eli Foster <efoster@squareup.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This change derives `trigger_author` exclusively from the signed event pubkey. Actor tags remain available as event data but cannot override the identity used by author-sensitive workflow conditions. This removes the impersonation path without changing workflow definitions or requiring stored-data migration. ## Testing - `bin/cargo test -p buzz-workflow` at `78819df`: 154 passed, 2 Postgres-dependent tests ignored - `git diff --check origin/main...codex/security-workflow-trigger-author` Originating Buzz thread: `buzz://message?channel=3928fe05-df61-4b5d-b9c7-d623b9b10ea1&id=3c6c02312f763fbe0d2bfc33a6c1a362f91d0354f3d18b039cf7a0558c1439d1` Signed-off-by: Jordan Mecom <jm@squareup.com>
This change removes the ACP permission-bypass mode, defaults managed sessions to `dontAsk`, and answers permission requests with `reject_once` or cancellation in both ACP read loops. Unattended operations that require interactive approval now fail closed instead of being silently authorized. Explicit non-interactive modes that do not bypass a permission request remain available. Both layers have to change together: `apply_permission_mode` treats an unsupported mode and a failed `set_config_option` as non-fatal by design, so a request can still reach the harness even in a non-interactive mode. Removing `bypassPermissions` from the enum rather than only changing the default means the mode cannot be restored by configuration alone. The scope of the guarantee is that `buzz-acp` never grants approval. An agent that pre-authorizes tools in its own configuration (for example Claude Code's `settings.json`) still runs them without asking, which is outside this harness. ## Testing - `env -u BUZZ_ACP_LAZY_POOL bin/cargo test -p buzz-acp` at `16fff4d`: 671 library tests and 9 integration tests passed - `cargo clippy -p buzz-acp --all-targets -- -D warnings` and `cargo fmt -p buzz-acp -- --check`: clean - `git diff --check origin/main...codex/security-acp-shell-auto-approval` The permission tests previously re-implemented the `reject_once` lookup in the test body instead of calling the code under test, so they would have passed unchanged if the harness went back to selecting `allow_once`. They could not call it directly, because `handle_permission_request` is a method on `AcpClient`, which owns a live `Child` and its stdio pipes. The choice is now a free function, `permission_denial_response`, and the tests exercise it: `reject_once` preferred over offered allow options, the cancelled fallback when no `reject_once` exists, an empty option list, and a `reject_once` missing its `optionId`. The cancelled fallback had no coverage before despite being the fail-closed backstop. ## Operator notes - `BUZZ_ACP_PERMISSION_MODE=bypassPermissions` no longer parses, so a process configured with it fails to start rather than silently downgrading. - Desktop managed agents do not set a permission mode, so they inherit `dontAsk`. The desktop has no permission prompt, so operations needing approval now fail with no in-app way to approve them. Originating Buzz thread: `buzz://message?channel=3928fe05-df61-4b5d-b9c7-d623b9b10ea1&id=3c6c02312f763fbe0d2bfc33a6c1a362f91d0354f3d18b039cf7a0558c1439d1` --------- Signed-off-by: Jordan Mecom <jm@squareup.com> Signed-off-by: Eli Foster <efoster@squareup.com> Co-authored-by: Eli Foster <efoster@squareup.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This change requires an active owner or administrator for third-party additions to private channels. The relay validator and transactional database authority enforce the same rule, including removed-member reactivation and role-change paths. Idempotent self-target behavior remains available, while ordinary members can no longer extend private-channel access to another identity. ## Testing - `git diff --check origin/main...codex/security-private-channel-invite-authority` - Rebased onto `origin/main` at `5c98932` - Full CI pending Originating Buzz thread: `buzz://message?channel=3928fe05-df61-4b5d-b9c7-d623b9b10ea1&id=3c6c02312f763fbe0d2bfc33a6c1a362f91d0354f3d18b039cf7a0558c1439d1` --------- Signed-off-by: Jordan Mecom <jm@squareup.com> Signed-off-by: Eli Foster <efoster@squareup.com> Co-authored-by: Eli Foster <efoster@squareup.com>
## Summary Redesign the permanent Desktop release flow so unrelated merges to `main` cannot invalidate an already reviewed, green release candidate. - Tag the immutable, API-confirmed release PR head instead of its later squash commit. - Treat the merged PR—including an authorized owner/admin bypass—as publication authorization, while requiring trusted check evidence that was complete at merge time. - Make tag creation idempotent and collision-safe: an existing tag succeeds only at the exact candidate SHA, and create races refetch before accepting equality. - Replace ancestry-based previous-release discovery with a validated metadata ledger for side-history candidate tags. - Compute the next release from the prior frozen base to the new frozen base, excluding only the prior release squash SHA so unrelated commits remain in the changelog. - Preserve schema-1 production-tag migration and reject malformed metadata or equal/decreasing versions. - Update operator documentation for the normal squash-merge workflow. This is the reusable release process for `0.5.6` onward, not the retired one-shot `0.5.5` recovery path. ### Invariants covered - Candidate creation → unrelated `main` merge → authorized squash merge → immutable candidate tag. - Trusted producer IDs and merge-time completion timestamps; DCO's bounded post-merge exception remains isolated. - Missing/spoofed checks, tampered candidates, ambiguous PR associations, conflicting tags, and equal/decreasing versions fail closed. - Same-SHA retries succeed; different-SHA collisions fail. - Legacy schema-1 tag-on-main migration and schema-2 side-history accounting both preserve the correct next-release changelog. ### Related issue N/A — follows the Desktop release failures in block#4788 and block#4800 and the recovery revert in block#4808. ### Testing At clean commit `6a91fbed8147a48cf174997de0c3e4cb2fb26474`: - `scripts/test-desktop-release-candidate.sh` - `scripts/test-release-ref-contract.sh` Both focused suites passed with HEAD unchanged. Princess Donut cleared the security/provenance surface, including the hostile merge-time timestamp cases. Mongo cleared the side-history ledger, migration, version-order, documentation, and contract-test surface. --------- Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
## Summary - Polish mobile Home, Activity, Search, and Settings navigation chrome. - Add progressive Buzz gradients/frost, aligned theme colors, dividers, typography, and section spacing. - Refine Search and Settings motion, including automatic keyboard focus on search activation. <img width="630" height="1368" alt="C78FA3CE-F2B3-45F2-B9F5-7EA7500778CC" src="https://github.com/user-attachments/assets/5935514b-d894-4010-80dd-a938363fee93" /> <img width="630" height="1368" alt="5C058A73-1879-476A-881C-531ACC256D84" src="https://github.com/user-attachments/assets/5266c841-17ee-49e8-9841-b06d84f4195f" /> <img width="630" height="1368" alt="3F50ADB7-9BDA-4A8D-A81E-20560C3B9EA6" src="https://github.com/user-attachments/assets/f615f61e-9e96-4bce-b261-ae5ec54db872" /> <img width="630" height="1368" alt="35ECE741-01F3-4B79-80C5-1DDD447121A7" src="https://github.com/user-attachments/assets/b5145186-9884-44eb-8ebc-f3303831c0a4" /> ## Validation - `flutter analyze` - Focused Home, Activity, Channels, Search, theme, and footer widget tests - Full pre-push checks, including mobile tests, desktop checks, and Tauri checks - On-device iPhone review during the visual polish pass --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: npub1glqcqfjxdens59scl477pmejh8lht4hqkhx0y4w38jxr6e6w6y2sm29y4e <47c18026466e670a1618fd7de0ef32b9ff75d6e0b5ccf255d13c8c3d674ed115@buzz.block.builderlab.xyz> Signed-off-by: Code Reviewer <037593536284cf40e221c96c931e9877d4166d54f6bb84e5341a86d7fd5d05a4@buzz.block.builderlab.xyz> Signed-off-by: Kenny Lopez <klopez4212@gmail.com> Co-authored-by: npub1glqcqfjxdens59scl477pmejh8lht4hqkhx0y4w38jxr6e6w6y2sm29y4e <47c18026466e670a1618fd7de0ef32b9ff75d6e0b5ccf255d13c8c3d674ed115@buzz.block.builderlab.xyz> Co-authored-by: Code Reviewer <037593536284cf40e221c96c931e9877d4166d54f6bb84e5341a86d7fd5d05a4@buzz.block.builderlab.xyz>
## Summary - admit relay-discovered agents to autocomplete when their response policy authorizes the viewer - require authorization in the exact active stream/forum channel for mentions, while keeping community-wide discovery for member invitation - fail closed for relay-only agents in DMs and unresolved composer contexts - re-authorize cached autocomplete rows after policy/channel changes so stale agent suggestions cannot leak back in - preserve managed-agent behavior and explicitly reject stale agent-marked channel members absent from both live directories ## Validation - `pnpm --dir desktop test` — 4,288 passed - `pnpm --dir desktop typecheck` - `pnpm --dir desktop check` - `pnpm --dir desktop build:e2e` - focused Playwright mention matrix — 12 passed - focused Playwright member-invitation matrix — 2 passed - pre-push hooks after rebase to current `origin/main` — desktop check and 4,288 tests passed - independent correctness/privacy re-review cleared with no remaining blocker ## Related competing PRs This supersedes or overlaps block#2333, block#3056, block#4242, block#4137, block#2314, block#4058, and block#2605. This version adds exact-channel authorization, fail-closed DM/context handling, cached-row reauthorization, forum coverage, outbound mention-tag coverage, explicit stale-member coverage, and add-member discovery coverage. Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated upstream sync
This PR integrates the newly mirrored block/buzz:main into dcm-production.
This PR never merges automatically. Review the complete diff, migrations, configuration changes, and all required checks before merging. Merge using Create a merge commit so upstream ancestry is preserved.
Recovery tag:
dcm-before-upstream-20260805-184846-014562c063eaUpstream commit:
014562c063eae6ab1b7c6e3d20f2be3024c5f3a8Upstream commits (first 20)\n- 014562c fix(desktop): allow shared agent mentions (block#4913)