Post-policy CI found the shared launcher calls the pure captured-policy helper removed with the obsolete live-app wrapper. Restore only the command writer; keep captured preflight authority and no live state reads. Cover both policies overriding inherited environment.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Keep existing full native tests and add the Unix no-default-features fixture invocation to the Linux desktop job. Initialize the main-only idle ACP fixture with non-strict model policy while preserving its hold-decision regression.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Route signed lifecycle requests through ordinary async preflight and shared captured launch admission. Require an already provisioned matching local agent key, revalidate after awaits and teardown, and retain independent Stop.
Persist named launch lifecycle metadata without migrating or restoring captured credentials. Add isolated signed receiver and actual teardown regressions for revoked keys, missing executables, request expiry, and fresh same-host Start.
Native fixtures require Unix --no-default-features and remain unexecuted locally; dependency-complete CI owns compilation and runtime validation.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Carry the identical producer-owned compiler repair without rewriting the published validation head. Preserve capture, preflight and admission semantics. CI run34144148717 diagnosed these errors; native validation follows on the successor head.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Use producer preflight authority and shared captured Start/Restart admission. Capture the existing explicit Start Stop fence and runtime generation before await; keep probes and Restart without resume authority and preserve Failed after destructive Stop. Broker remains provisioning-unavailable. Native compilation remains gated on CI-only draft authorization; local formatting and integrated frontend checks pass.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Move the existing descriptor resolver and discovery record fixture into sibling modules without changing their behavior or dropping cases. The required CI changes job rejects their producer-added growth in inherited oversized files; no policy limits or allowlists changed. Native fmt and actual size ratchet pass; native compilation is still awaiting CI-only draft authorization.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Recover shared Default/named launch capture; cover direct pair Start/Restart, bulk and restore with locked same-plan admission. Classify mesh recovery by running pair snapshots. Route UI Restart through native admission while preserving old-turn cleanup. Native orchestration regressions remain a dependency-complete CI gate; frontend6295 and bounded exact-source policy checks pass. Local checkpoint only; no publication or remote broker-policy change.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Integrate ACP strict model verification with the named native caller. Bind app session inputs, require declared named MCP tools, and fence Default selection and restore preflight. Local checkpoint: native compilation and async workflow validation remain pending dependency-complete CI; no publication approval assumed.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Local integration checkpoint; native compilation and strict ACP model enforcement remain validation gates. Scope and async prepared-launch APIs are stable for lifecycle integration; not publication-ready.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Bind owner delegation, installation, agent and community before ordinary Stop. Persist admission before effects and retain exact signed outcomes for retries across reopening and bounded eviction.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Bind explicit Start permission before preflight and release it only after child registration. Reuse ordinary platform-specific pair Stop and refuse success for an unscoped live legacy child.
Signed-off-by: Logan Johnson <loganj@squareup.com>
Keep exact-request retry owner/community private without repeating relay side effects. Exclude request/result ciphertext from search on fresh and upgraded databases.
Signed-off-by: Logan Johnson <loganj@squareup.com>
## Buzz Desktop release v0.5.23
- **Frozen main:** `dad5a33865fc81a2e55b3b60746632f615ec1e3a`
- **Reviewed candidate:** `b9392d9d78744df365f9276e1ffe8c1baa5ea903`
- **Previous desktop release:** `desktop-v0.5.22`
- **Proposed immutable tag:** `desktop-v0.5.23`
This PR may be **squash merged** after the Desktop Release Candidate
check and all protected-branch checks pass. Merging authorizes
publication of the exact reviewed candidate; later or unrelated changes
on `main` cannot alter it.
The checked-in changelog accounts for every non-merge commit in the
release range. The Desktop tag points to the reviewed candidate commit,
not the later squash commit. Publication remains bound to that immutable
candidate tag.
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Release Automation <release-automation@users.noreply.github.com>
## Root cause
`tauri-command.mjs` points `frontendDist` at a `mkdtemp` directory so
concurrent OSS/internal packages cannot overwrite each other's assets.
On Windows that is an absolute path with a drive letter.
`FrontendDist` is an untagged serde enum whose **first** variant is
`Url(Url)`, and `C:\Users\...` is a valid WHATWG URL with scheme `c:`,
so serde selects `Url`. `tauri-codegen` then does:
FrontendDist::Url(_url) => Default::default(), // embed nothing
A missing *directory* panics with a clear message; a URL is silent. The
build exits 0 and produces an installable app with no frontend assets,
which boots to `ERR_FILE_NOT_FOUND` in the WebView.
Linux and macOS are unaffected — `/tmp/...` has no scheme, so it falls
through to `Directory`.
This affects every Windows build that goes through `pnpm tauri build`,
including `release.yml`'s NSIS job and `windows-canary.yml`.
## Fix
Pass the path relative to the config's own directory. `tauri-codegen`
resolves `frontendDist` with `config_parent.join(path)`, so a relative
path reaches the same directory and cannot parse as a URL. When the temp
directory is on another drive there is no relative form, so the scratch
root is created beside the config instead.
`BUZZ_PROTECTED_BUILD_OUTPUT` still receives the absolute path, and
cleanup is unchanged.
## Testing
`tauriCommand.test.mjs` asserted against the value it had just been
handed, so it could not observe this. Its fake CLI also resolved
`frontendDist` against the process cwd, which is not what Tauri does.
- Fake CLI now resolves against the config directory, matching
`config_parent.join(path)`.
- New case asserts the packaged `frontendDist` is not absolute and does
not parse as a URL. The absolute check is what fails on Linux/macOS, so
the regression stays covered on every platform.
- Verified the new case fails on the unpatched wrapper and passes with
the fix; the two existing cases pass either way.
- Desktop suite: 5844 passed. `useDocumentVisible` has a pre-existing
load-dependent flake that also reproduces on an unmodified checkout.
- Biome check clean on both files.
Verified end to end by rebuilding the Windows NSIS installer: embedded
asset keys in `buzz-desktop.exe` went from 0 to 490, and the app
launches.
---------
Signed-off-by: Jeff Hedlund <jhedlund@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
**Category:** fix
**User Impact:** The sidebar now presents unread activity consistently:
unread rooms are bold, offscreen activity is counted by destination, and
DMs or directed activity receive stronger emphasis.
**Problem:** Sidebar unread state was split across competing signals:
agent work could trigger overflow, message totals inflated its count,
non-DM rows showed redundant numerals, and routine room activity looked
as urgent as DMs or directed messages. This made the sidebar noisy and
made the overflow value harder to interpret.
**Solution:** Use one stable offscreen unread control that counts rooms
and DMs—not messages—and remove agent work from that signal. Keep
ordinary room activity quiet; promote DMs, mentions, broadcasts, and
relevant thread replies; preserve DM avatars and targeting; bold every
unread room; and retain thread dots while removing non-DM numerals.
<details>
<summary>File changes</summary>
**desktop/src-tauri/src/unread_catch_up.rs**
Classifies relevant thread replies as priority activity during native
unread catch-up so startup state matches live rendering.
**desktop/src/app/AppShell.tsx**
Passes the priority unread destination set into the sidebar.
**desktop/src/features/channels/useUnreadChannels.ts**
Projects unread destinations, priority state, and thread replies
consistently while keeping Dock badge behavior separate from sidebar
emphasis.
**desktop/src/features/sidebar/lib/useOffscreenActivityChannelIds.test.mjs**
Removes tests for the superseded agent/activity overflow projection.
**desktop/src/features/sidebar/lib/useOffscreenActivityChannelIds.ts**
Removes the old agent-plus-message overflow projection so agent work
alone no longer creates the unread indicator.
**desktop/src/features/sidebar/lib/useSidebarActivityOverflow.ts**
Replaces activity-volume overflow state with unread-destination overflow
state.
**desktop/src/features/sidebar/lib/useSidebarUnreadOverflow.test.mjs**
Covers priority detection and destination-count labels for the new
overflow projection.
**desktop/src/features/sidebar/lib/useSidebarUnreadOverflow.ts**
Counts distinct offscreen unread destinations and determines quiet
versus primary treatment per direction.
**desktop/src/features/sidebar/ui/AppSidebar.tsx**
Renders one stable overflow control, preserves protected-DM visibility
filtering, and prioritizes visible unread DMs for previews and
navigation.
**desktop/src/features/sidebar/ui/AppSidebar.types.ts**
Adds the priority unread destination set to the sidebar contract.
**desktop/src/features/sidebar/ui/CustomChannelSection.tsx**
Stops forwarding non-DM unread counts into custom channel rows.
**desktop/src/features/sidebar/ui/MoreUnreadButton.test.mjs**
Updates control coverage for explicit emphasis, destination labels, and
DM targeting.
**desktop/src/features/sidebar/ui/MoreUnreadButton.tsx**
Applies quiet or primary treatment without changing geometry,
accessibility text, DM avatars, or click behavior.
**desktop/src/features/sidebar/ui/SidebarSection.tsx**
Removes non-DM row numerals while retaining unread weight and thread
preview affordances.
**desktop/src/shared/ui/UnreadPill.tsx**
Shares one composition between quiet and primary states so only color
treatment changes.
**desktop/tests/e2e/badge.spec.ts**
Covers destination counting, promotion without count inflation,
DM/thread priority, row bolding, and removed numerals; also captures the
reviewed UI states.
**desktop/tests/e2e/channel-activity-popover.spec.ts**
Updates channel activity assertions for the numeral-free row treatment.
**desktop/tests/e2e/channels.spec.ts**
Updates channel unread expectations to use bold text rather than a row
count.
**desktop/tests/e2e/thread-unread.spec.ts**
Keeps thread unread-dot and popover coverage while asserting the room
itself is bold.
</details>
## Reproduction steps
1. Open a workspace with enough sidebar destinations to scroll rooms
above or below the viewport.
2. Receive ordinary unread activity in an offscreen room; verify one
quiet `N unread` indicator appears and counts the room once regardless
of message volume.
3. Receive a mention, broadcast, or relevant thread reply in an
offscreen room; verify the same count becomes primary without changing
its geometry or adding a badge.
4. Receive an unread DM, including thread-only activity; verify the
indicator is primary, shows the DM avatar when available, and navigates
to that DM.
5. Scroll the destination onscreen or mark it read; verify the count and
treatment update from the remaining offscreen destinations.
6. Inspect unread non-DM rows; verify their names are bold, numeric
badges are absent, and thread dots still open the unread-thread preview.
## Screenshots
### Ordinary unread room
Routine offscreen room activity uses the quiet treatment.

### Directed unread activity
The same destination count becomes primary when an offscreen room has
directed activity; geometry and label remain unchanged.

### Thread-only unread DM
A DM stays primary and retains its avatar even when only its thread has
unread activity.

---------
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Adds a dependency-free `ifc-core` crate implementing reader-set
confidentiality labels and monotonic per-computation flow state.
- Defines flow ordering, join, and meet over caller-supplied principal
universes.
- Fails closed for unknown or cross-universe input and checks reader
widening at egress.
- Includes property tests for lattice laws and monotonic taint, plus the
design paper that motivates the broker integration.
The crate deliberately contains no Buzz, Nostr, channel, membership, or
grant policy; those remain in the Buzz adapter.
---------
Signed-off-by: Jordan Mecom <jm@squareup.com>
## Summary
- launch Pi through a private Buzz wrapper so managed Pi agents receive
Buzz's base prompt plus the configured thread/channel session model via
`--system-prompt`
- load the Buzz workspace skill directory with Pi's repeatable `--skill`
flag, making `~/.buzz/.agents/skills/buzz-cli` available alongside Pi's
normal global skill discovery
- report Pi and `pi-acp` installation states separately so setup
guidance points to the missing component
`pi-acp` does not currently consume the ACP `session/new` system prompt,
but its normal new-session and restore paths do honor
`PI_ACP_PI_COMMAND` as the executable used to launch Pi. Buzz reserves
that variable and sets it to a private generated launcher. The launcher
invokes `pi` from Buzz's effective `PATH`, adds `--system-prompt <file>`
and `--skill <workspace>/.agents/skills`, and forwards `pi-acp`'s RPC
and session arguments unchanged. This keeps the integration entirely in
`block/buzz`, without changes to Pi or `pi-acp`.
### How PI_ACP_PI_COMMAND works in `pi-acp`
`PI_ACP_PI_COMMAND` selects one executable; it does not accept
arguments. Therefore:
```bash
# Does not work
PI_ACP_PI_COMMAND="pi --skill ~/.buzz/.agents/skills"
```
Buzz does not expose this variable as user configuration. It creates a
private launcher and sets `PI_ACP_PI_COMMAND` only on the `pi-acp`
child. Conceptually, that launcher executes:
```sh
#!/bin/sh
exec pi \
--system-prompt "$PRIVATE_SYSTEM_PROMPT" \
--skill "$HOME/.buzz/.agents/skills" \
"$@"
```
### Related issue
Follow-up to #7208. No duplicate issue or open PR found.
### Testing
- `just ci`
- `cargo test -p buzz-acp pi_launcher`
- `cargo test --manifest-path desktop/src-tauri/Cargo.toml
managed_agents::env_vars::tests`
- `cargo test --manifest-path desktop/src-tauri/Cargo.toml
managed_agents::discovery::presets::tests`
- pre-push branch checks
No screenshots: the UI change is state-dependent setup guidance only.
---
**Update Sep 4, 13:35:** Made `PI_ACP_PI_COMMAND` entirely Buzz-owned.
- Managed agent configuration now rejects the variable as a user
override.
- Buzz always launches `pi` from its effective `PATH` and rejects
inherited values before creating its private launcher.
- Removed the custom Pi executable discovery path and its internal
environment alias.
---
**Update Sep 4, 14:03:** Reject inherited `PI_ACP_PI_COMMAND` values
instead of replacing them.
- Pi startup now fails with an actionable message telling the user to
unset the variable.
- Removed the Pi-specific exception from the generic ACP environment
injection path.
Generated with Codex
---------
Signed-off-by: Salman Mohammed <smohammed@squareup.com>
## Summary
Restore the missing **@ glyph for people and robot icon for agents**
after #7133, and incorporate the requested compact public-key display.
- Wrapping mention chips render their existing bounded icon-bearing
leading fragment.
- Readonly chips show bound keys using the same `8 leading…4 trailing`
formatter as the channel member list: `Scout (150b20bd…15dc)`.
- Full literal labels and exact keys remain authoritative in metadata,
profile targets, title/accessible-name attributes, editor text, saved
bodies and recipient tags. Display abbreviations are never used for
recipient lookup.
- Copy/paste restores the full literal label for a complete compact
chip; partial selections remain plain text. Two keys sharing the same
abbreviation still round-trip to their separate exact recipients.
- No recipient-resolution, authorization, wire-format, composer, or CSS
changes. Existing labels, icons, cloud markers and ordinary mentions
remain intact.
## Verification
Published candidate `9365ab9bc9d9c5d10802580cd576f8e378ff492f`, based on
main `e09f715c9d0ee2cb7bf8a39061e601f3a502f588`:
- **6,444 desktop unit tests passed** on this candidate's final source
tree.
- **44 mock-Chromium tests passed, zero retries in the final run**
across mention recipients, clipboard and cloud provenance: exact
recipient selection, ambiguity rejection, send/edit/reopen, forwarding,
full/partial copy, mismatched-key rejection, matching-abbreviation
collisions and 100%/150% narrow-window geometry.
- TypeScript, desktop Biome/check guards, protected-feature production
build and E2E build passed.
- The compact-renderer regression fails with the formatting call
removed. Original missing-icon and hidden-text accessibility regressions
have red/green evidence.
- Fresh self-review traced rendering, full-key metadata, copy
classifier, paste normalization and identity trust. The same display
formatter owns the accepted compact form on both clipboard sides.
Iteration exposed an existing team-insertion separator flake (passed
final full run) and two new fixture assumptions: non-member sends
require invitation, and Chromium rich paste may retain an NBSP
separator. Tests now exercise invitation and normalize only that
separator when comparing the captured full body and exact tags; no
product change was needed for either.
Earlier local repository-wide `just ci` completed in two invocations
because its initial call hit the ten-minute tool limit during Tauri
compilation. Unchanged native/mobile/backend evidence is reused; the
desktop delta received the full checks above and new remote CI. Native
VoiceOver, real Tauri selection, dark theme and non-Chromium observation
were not performed. Browser artifacts exercise real frontend with mocked
Tauri/relay boundaries, not an installed release.
## Review and visual evidence
Current-head CI and automated review must complete after this update;
the old `2997bfb5` green results do not establish this new head.
Required human review remains separate from agent approvals. No
merge/install/restart authorization.
Before/after icon evidence:
https://github.com/block/buzz/pull/7338#issuecomment-5544575866
Updated compact-key screenshots are posted below. The editor
intentionally retains the full literal address; only readonly chip
display is abbreviated.
Origin:
buzz://message?channel=3355d33a-b72a-423a-b064-a58275f9a8af&id=38b3a27e689f5a9604e273d45f4e3122fceba76081e7bcd3bbdbf439524a5a18
---------
Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>