Skip to content

Coordinate parallel Claude Code sessions over a Buzz channel #4570

Description

@ashbrener

Duplicate check: searched open and closed issues and PRs for "session coordination", "Monitor", "parallel worktrees", "claude code sessions talk each other", "multi-session". Nothing covering this. The closest adjacent work is #3554 (machine-level enrolment for headless/self-host) and #3364 (repository-scoped managed agents), neither of which addresses interactive sessions coordinating with each other. #2270 is about ACP agents going deaf in threads — a different mechanism.

Problem

Several Claude Code sessions working in parallel — typically git worktrees of one repo — cannot talk to each other. Each is an isolated process with its own context. The human becomes the message bus: copy an answer out of terminal A, paste it into terminal B, and discover ten minutes later that B and C both edited the same file.

This is not hypothetical. I spent an evening relaying briefs between two sessions by hand before wiring them into a Buzz channel, after which they corrected each other's diagnosis of two bugs in about four minutes with no involvement from me.

Upstream in Claude Code this gap is acknowledged and unsolved: anthropics/claude-code#24798, #37213, and #28300 are all open requests for inter-session communication. The community fills it with same-machine, ephemeral message buses (claude-code-inter-session, claude-peers-mcp, an Interagent MCP server). Agent Teams, the official feature, is explicitly scoped to one lead spawning teammates within a single session — its limitations say a team cannot be shared across sessions.

Buzz already has everything this needs and none of those tools do: signed events, per-identity membership, channels, and durable searchable history that outlives any session. It also works across machines, which the local buses do not.

Proposed solution

A Claude Code skill under .claude/skills/, alongside the existing sprout-cli and desktop-screenshot. Each session:

  • derives its identity from its own /rename title, so a message in the channel is attributable to a terminal the user can go and find
  • enrols on the relay from a single invite code shared via ~/.buzz/config
  • joins one coordination channel, or a dedicated channel per piece of work
  • arms Claude Code's Monitor tool on that channel, so a peer's message wakes it

Messages are verb-prefixed (HELLO / CLAIM / RELEASE / STATUS / ASK / ANSWER / BLOCKED / DONE), with CLAIM <glob> as an advisory lock before editing shared paths — the piece that makes three sessions on one repo safe rather than merely chatty.

A concrete run

Three worktrees of one repo, three terminals. Each is /renamed so the Buzz
member is a terminal the human can actually go and find.

wt-a $ /buzz-connect
       session  : Claude Code (auth-refactor-a)
       relay    : enrolled from the configured invite code
       channel  : agent-coordination
       watcher  : armed

wt-b $ /buzz-join auth-refactor
       auto-admit: 'auth-refactor-a' owns this channel and its key is on this machine.
       channel  : auth-refactor  (created by a peer, joined)

wt-b $ CLAIM crates/buzz-auth/**
wt-a   [buzz] 7d98c4ef: CLAIM crates/buzz-auth/**      <- wakes, does not touch those paths
wt-a $ ASK does the NIP-42 challenge expire before or after the membership check?
wt-b   [buzz] 3f0a12a5: ASK does the NIP-42 challenge …
wt-b $ ANSWER before — auth.rs:141, the gate runs after
wt-a $ DONE
wt-c $ /buzz-status --all
       three identities, two watchers live, one stale

The human typed no message into any terminal on behalf of another.

Slash commands

/buzz-connect join the shared channel, arm the watcher
/buzz-join <name> a room for one piece of work; creates it if absent
/buzz-status [--all] connected? watcher alive? --all lists every identity on the machine
/buzz-leave done with the room, not the session
/buzz-disconnect [--retire] done entirely; --retire also archives the identity
/buzz-agent-provision <name> an identity + env block for a buzz-acp harness (goose, codex, hermes)

Separate skills rather than one with verbs, because Claude Code's slash menu
lists skill names — there is no completion into a skill's arguments, so a verb
nobody has been told about is a verb nobody finds.

Why a relay rather than a local bus

flowchart LR
  subgraph M1["laptop"]
    A["session A<br/>worktree a"]
    B["session B<br/>worktree b"]
  end
  subgraph M2["VPS"]
    H["hosted agent<br/>via buzz-acp"]
  end
  R(("Buzz relay<br/>signed events, searchable"))
  A <--> R
  B <--> R
  H <--> R
  P["phone / desktop<br/>human reads along"] <--> R
Loading

The same channel reaches a hosted agent and a phone. The local buses listed
above reach neither, and lose the history when the process exits.

The two gates, which is where the time goes

sequenceDiagram
  participant S as session
  participant R as relay
  S->>R: authenticated read
  R-->>S: 403 relay_membership_required
  S->>R: invites claim (code from ~/.buzz/config)
  R-->>S: joined
  S->>R: read the channel
  R-->>S: [] — member of the relay, not of the channel
  Note over S,R: indistinguishable from an empty room
  S->>R: channels add-member (owner key held locally)
  R-->>S: admitted
Loading

Relay membership and channel membership are separate, and the second failure is
silent — [] is indistinguishable from nothing having been said. Naming that
difference is most of what the skill does.

Status, and an apology for the ordering

I have this working and opened #4481 with it before filing here, which is the wrong way round per CONTRIBUTING — "entirely new features with no prior discussion" is on the list of PRs you're unlikely to merge, and that is a fair rule. Filing now so the direction can be judged on its own terms rather than through a 1,700-line diff.

If the answer is "not in this repo", that is a legitimate outcome and I will maintain it elsewhere; it costs you nothing to say so. If the direction is interesting but the shape is wrong, I would rather hear that before you spend review time on the code.

One dependency worth noting: enrolment uses buzz invites claim from #4479 (closes #3014). Without it a relay operator must add each session's pubkey by hand, which the skill documents as the interim path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions