block / block/buzz

Desktop spawns duplicate buzz-acp daemons for the same (agent, community) after adding a second community — mentions processed twice

Open
#5,759 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

## Summary

When a second community is added, Desktop spawns an **additional `buzz-acp` daemon for an agent that already has one in an existing community**, and does not reap the previous daemon. The result is two live daemons for the same agent + same community, each holding its own relay connection and its own pre-spawned agent pool.

Because both subscribe with the same `#p` mention filter, a single `@mention` is delivered to both and processed twice — duplicated turns, duplicated replies, and doubled token spend.

This is **not** orphaned processes surviving an app restart. Every duplicate is parented to the *currently running* Desktop process.

## Environment

| | |
|---|---|
| Desktop | 0.5.8 (dev build from source) |
| Relay | 0.2.1 (hosted, `*.communities.buzz.xyz`) |
| Commit | `119a84897` (main) |
| OS | macOS 26.5.2, arm64 |
| Runtime | `claude-agent-acp` 0.66.0, `BUZZ_ACP_AGENTS=10`, `BUZZ_ACP_LAZY_POOL=false` |

Two communities: one created by me, one I was invited to.

## Reproduction

1. Run Desktop with one community (A) and at least one managed agent (`Fizz`).
2. Add a second community (B) — created or joined.
3. Observe the spawned `buzz-acp` processes.

## Observed

Five daemons, with `Fizz` appearing **twice for community A**:

```
pid=78205 Fizz @ community-A up 1:08:19
pid=81100 Honey @ community-A up 55:34
pid=81119 Bumble @ community-A up 55:32
pid=81602 Fizz @ community-A up 54:16 <-- duplicate
pid=81783 Fizz @ community-B up 53:53
```

All five share `PPID 7722` — the live Desktop process — so these are not leftovers from a previous run.

The uptimes show a re-spawn wave when community B was added (~55m mark): `Honey`, `Bumble`, a **new** `Fizz` for community A, and a `Fizz` for community B were all started, but the pre-existing community-A `Fizz` (78205) was never shut down.

Per-community keypairs are working as designed — the duplicate is at the *process/subscription* layer, not the identity layer.

### It recurs

This isn't a single leaked process. `78205` later exited on its own, and Desktop then spawned **another** community-A `Fizz` (`89052`) while `81602` was still running — returning to two live `Fizz` daemons for one community:

```
pid=81602 Fizz @ community-A up 1:28:26 conns=1 pool=10 procs
pid=89052 Fizz @ community-A up 20:52 conns=1 pool=10 procs
```

Both held an established relay connection and a full 10-process pool, i.e. both were genuinely subscribed and dispatch-ready — not one live and one idle husk.

## Impact

- **Duplicate delivery**: both daemons match the same `#p` filter, so one `@mention` starts two turns.
- **Duplicate publishes**: each turn independently follows the "you MUST publish" rule in `base_prompt.md`, so the same mention can produce two messages.
- **Wasted spend**: each duplicate holds 10 pre-warmed `claude-agent-acp` processes (`LAZY_POOL=false`) and doubles inference cost per mention. Agents on `opus`-class models make this expensive.
- **Confusing UX**: reads as an agent "replying twice" or "talking over itself" with no visible cause.

## Expected

Adding or switching communities should reconcile the desired daemon set against what is running: one daemon per (agent, community). Existing daemons for unchanged (agent, community) pairs should be left alone, or cleanly terminated before a replacement is spawned.

## Notes / possibly related

- #5128 — Agents tab is not community-scoped; per-agent settings land on the wrong instance.
- #2648 — Second Desktop install creates duplicate agent identities.
- #4577 — ACP bridge subprocesses never reaped after a turn (different layer: per-turn subprocesses vs. per-agent daemons).
- #2515 — Agents from different communities collide in channels.

Those cover identity/UI scoping and per-turn subprocess reaping; none appears to cover Desktop spawning a duplicate long-lived `buzz-acp` daemon for an (agent, community) pair that already has one.

A `SIGTERM` to the duplicate shuts it down cleanly and reaps its pool, so the daemon's own shutdown path is fine — what's missing is the reconcile step on the Desktop side.

## Separate but adjacent: naming

While reproducing this, agent naming also did not scope per community — renaming an agent in one community did not give it a distinct name there, and both communities retained the same name across all variants of the agent. Renaming after a restart *sometimes* took effect. That matches #5601, and I've added the detail there rather than duplicating it here.

Contributor guide

Open the contributing guide

Research direction

No source files or tests are named. Start by tracing the Desktop entry point that handles adding or switching communities and manages buzz-acp daemon lifecycles; reproduce the second-community flow and inspect the desired-versus-running daemon reconciliation. Done means unchanged (agent, community) pairs retain one daemon, replacements terminate the old process cleanly, and mentions are processed once.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.