Files
itpp-infrastructure/projects/buzz-agent-integration-spec.md

32 KiB

Server-Side Agent Integration with Buzz

Status: Speculative / Research Date: 2026-08-07 Author: Sho'Nuff Relay: wss://buzz.iamgmb.com (app3, Docker Compose)

Executive Summary

Buzz's native agent integration model (buzz-acp) is desktop-centric: it spawns ACP-compliant agent binaries as local subprocesses via stdio. Hermes is server-side (Core VPS) and cannot be spawned as a local binary on a user's laptop. This spec evaluates four integration paths to make Hermes a first-class participant in Buzz channels — able to receive @mentions and post replies — and recommends a Nostr-native WebSocket client approach modeled after the proven OpenClaw Buzz plugin.


1. ACP Protocol Research

1.1 What is ACP?

The Agent Client Protocol (ACP) is an open standard hosted at agentclientprotocol.com, governed by a spec repo at github.com/agentclientprotocol/agent-client-protocol. It is modeled after LSP (Language Server Protocol) and standardizes communication between code editors/IDEs and AI coding agents.

Protocol fundamentals:

  • Wire format: JSON-RPC 2.0 over stdio (primary transport today)
  • Roles: Client (editor/IDE/harness) ↔ Agent (AI coding tool)
  • Lifecycle: initializesession/newsession/promptsession/update (streaming) → StopReason
  • Concepts: Sessions, tool calls, cancellation, context window updates, authentication
  • Rust crate: acp-sdk provides typed wire messages

Key ACP methods:

Method Direction Purpose
initialize Client → Agent Handshake, negotiate protocol version + capabilities
session/new Client → Agent Create session, pass cwd + MCP server configs
session/prompt Client → Agent Send user prompt, agent loops LLM + tool calls
session/cancel Client → Agent Cancel ongoing session
session/close Client → Agent Close session, free resources
session/update Agent → Client Streaming updates: tool calls, text chunks, usage
authenticate Client → Agent Auth before session creation

AGENT NOTIFICATION — buzz-agent implementation:

  • Single binary, ACP-compliant. Speaks MCP to tools (stdio only, no HTTP MCP).
  • Up to 8 concurrent sessions per process.
  • Non-streaming HTTP POST to LLM providers (Anthropic, OpenAI, OpenRouter).
  • Not persistent (in-memory per process), no session/load.

1.2 Remote Transport Status

ACP remote transports are in active development but NOT shipped yet:

  • An RFD (Request for Discussion) exists at agentclientprotocol.com/rfds/streamable-http-websocket-transport
  • A Transports Working Group has been formed, co-led by Block/Goose and JetBrains
  • The RFD proposes:
    • Streamable HTTP (HTTP/2, long-lived GET streams, Acp-Connection-Id + Acp-Session-Id headers)
    • WebSocket (GET /acp with Upgrade: websocket header)
    • Unified /acp endpoint routing
  • This is an RFD, not implemented. No timeline published.

Current reality: ACP is stdio-only for production use. Remote agents are a documented goal, not a working feature.

1.3 How Buzz Uses ACP

Buzz's agent harness is buzz-acp — a Rust binary that bridges the Buzz relay to AI agents:

┌──────────────┐     WebSocket      ┌──────────┐     stdio ACP      ┌───────────────┐
│  Buzz Relay  │ ◄────────────────► │ buzz-acp │ ◄───────────────► │ Agent Binary  │
│  (Nostr)     │   (NIP-01 events)  │ (harness)│   (JSON-RPC 2.0)  │ (goose,codex, │
└──────────────┘                    └──────────┘                   │  claude-code) │
                                                                    └───────────────┘

How buzz-acp works (from .env.example + source analysis):

  1. Connects to relay via WebSocket using BUZZ_PRIVATE_KEY (Nostr keypair, NIP-42/98 auth)
  2. Subscribes to events where the agent's pubkey appears in p tags (i.e., @mentions)
    • BUZZ_ACP_SUBSCRIBE=mentions (default) — subscribe only to events mentioning agent
    • BUZZ_ACP_SUBSCRIBE=all — subscribe to all channel events
    • BUZZ_ACP_SUBSCRIBE=config — rule-based via TOML config file
  3. Spawns agent binary as subprocess (Goose, Codex, Claude Code, or any ACP agent)
    • BUZZ_ACP_AGENT_COMMAND / BUZZ_ACP_AGENT_ARGS
  4. Forwards prompts to agent via ACP session/prompt, streams results back to relay
  5. Manages presence (kind 20001 online/offline), typing indicators (kind 20002), dedup

Key insight: buzz-acp itself IS the WebSocket-to-stdio bridge. It doesn't expose a remote API — it IS the client that connects to the relay and spawns agents. There is no existing buzz-acp HTTP API to connect remote agents to.

1.4 The @mention Mechanism

In Buzz/Nostr, "mentioning" an agent means including its Nostr pubkey as a p tag in a channel message event. The relay's subscription registry fans out matching events to all subscribed WebSocket clients. buzz-acp subscribes with a filter like {"#p": [agent_pubkey]} and receives all events that tag that pubkey. There is no special server-side routing — it's standard Nostr subscription fan-out.


2. Integration Architecture Options

2.1 Option A: Bridge Agent (Stdio ACP Proxy)

Deploy a lightweight binary on Core (or app3) that:

  1. Implements the ACP client side (speaks JSON-RPC 2.0 over stdio to a dummy agent)
  2. OR implements the ACP agent side (so buzz-acp can spawn it) that proxies to Hermes
┌──────────┐  WS   ┌──────────┐  stdio ACP  ┌──────────────┐  HTTP/WS  ┌──────────┐
│  Relay   │◄─────►│ buzz-acp │◄──────────►│ Bridge Binary │◄────────►│  Hermes  │
└──────────┘       └──────────┘             └──────────────┘          └──────────┘
                                              (runs on Core)

How it works:

  • buzz-acp spawns the bridge binary as an ACP agent subprocess
  • Bridge binary receives ACP session/prompt containing the user's message
  • Bridge forwards it to Hermes via REST API or WebSocket
  • Hermes processes, returns response
  • Bridge sends response back through ACP session/update notifications

Pros:

  • Uses Buzz's native agent machinery (presence, typing, turn lifecycle)
  • Agent appears in Buzz Desktop's agent panel naturally
  • Gets @mention routing for free via buzz-acp

Cons:

  • buzz-acp must run on a machine that can reach Hermes (not a laptop — would need to run on Core or app3)
  • Stdio bridge is fragile (subprocess lifecycle, crash recovery, binary distribution)
  • ACP is designed for local coding agents, not remote conversational agents — impedance mismatch
  • Bridge must implement full ACP agent spec (initialize, sessions, tool calls, cancellation)
  • buzz-acp is a desktop-side component — running it headless on a VPS is an off-label use
  • Requires compiling and maintaining a Rust binary (ACP SDK crate)

Effort: High. Requires implementing an ACP-compliant agent from scratch.

Hermes connects directly to the Buzz relay as a Nostr WebSocket client with its own keypair — exactly how buzz-acp and the Buzz Desktop app connect.

┌──────────┐       WebSocket (NIP-01/42/98)        ┌──────────┐
│  Relay   │◄─────────────────────────────────────►│  Hermes  │
└──────────┘    Signed Nostr events (kind 9)       └──────────┘
                 @mentions via p-tag subscriptions

How it works:

  1. Hermes generates or is assigned a Nostr keypair (pubkey = Buzz identity)
  2. Hermes connects to wss://buzz.iamgmb.com via WebSocket
  3. Hermes authenticates via NIP-42 (signed AUTH challenge) or NIP-98 (HTTP auth)
  4. Hermes subscribes to events with {"#p": [hermes_pubkey]} — receives all @mentions
  5. When a mention arrives, Hermes routes it to its AI pipeline, generates a response
  6. Hermes publishes a signed Nostr event (kind 9 or 40002) back to the same channel
  7. Hermes manages presence (kind 20001) and typing indicators (kind 20002)

Proof of concept: OpenClaw Buzz Plugin OpenClaw's Buzz channel plugin does exactly this. It connects an OpenClaw gateway (server-side agent platform) to Buzz as a Nostr client. Key details from their docs:

  • Connects to relay via WebSocket with a dedicated Nostr keypair
  • Bot identity must be added to rooms with Bot role via buzz channels add-member --role bot
  • Subscribes to room events, handles kind 9 (normal messages), kind 40002 (rich-content), kind 40008 (structured diffs)
  • Publishes presence every 30 seconds
  • Sends typing indicators (kind 20002) while processing
  • Supports NIP-27 native mentions in replies
  • Handles reconnection, dedup, and stale session recovery
  • One identity can serve many rooms

Pros:

  • Architecturally correct — Buzz IS a Nostr relay. Connecting as a Nostr client is the first-class path.
  • No desktop dependency — runs entirely server-side
  • Proven pattern (OpenClaw already does this successfully)
  • Hermes gets full Buzz citizenship: presence, typing, reactions, profile, DMs
  • Uses standard protocols: WebSocket + JSON (NIP-01), Schnorr signatures
  • No ACP impedance mismatch — Hermes processes messages its own way
  • Can be implemented in Python (websockets + nostr-py or secp256k1 bindings)
  • Coexists with other agents — Hermes is just another pubkey in the channel
  • Reuses Hermes's existing AI pipeline, tools, and skills

Cons:

  • Must implement Nostr protocol handling (event signing, subscription management, NIP-42 auth)
  • Does NOT use Buzz's native ACP agent panel UI — Hermes appears as a "bot" member, not a managed agent
  • No turn lifecycle management (ACP's session/promptend_turn model)
  • Must handle WebSocket reconnection, event dedup, and subscription state
  • Nostr python libraries are less mature than JS/Rust ecosystems

Effort: Medium. Requires a Nostr client module in Python (~500-800 lines).

2.3 Option C: Webhook Adapter (Buzz Workflows)

Use Buzz's YAML workflow engine to detect @mentions and fire webhooks to Hermes's REST API.

┌──────────┐  Buzz Workflow   ┌─────────────┐  HTTP POST  ┌──────────┐
│  Relay   │────────►────────►│ Workflow     │────────────►│  Hermes  │
│ (event)  │   trigger on     │ Engine       │  webhook    │ REST API │
└──────────┘   kind 9 + p-tag └──────┬───────┘             └────┬─────┘
                                     │                          │
                              ┌──────▼───────┐          ┌──────▼─────┐
                              │  Response    │◄─────────│  AI reply  │
                              │  back to     │ REST API │  generated │
                              │  channel     │          └────────────┘
                              └──────────────┘

How it works:

  1. Create a Buzz workflow YAML that triggers on new messages in specific channels
  2. Workflow filter matches events where p tag includes Hermes's pubkey
  3. On match, workflow fires a webhook action to Hermes's REST API
  4. Hermes processes the message and generates a response
  5. Response is posted back to the channel via buzz-cli or relay REST API (NIP-98 signed)

Buzz workflow capabilities (from ARCHITECTURE.md):

  • Triggers: message, reaction, schedule, webhook
  • Actions: send message, add reaction
  • send_dm and set_channel_topic actions are stubbed (return NotImplemented)
  • Approval gates partially wired (WF-08: runs hitting approval gates fail)

Pros:

  • Zero new protocol code — uses HTTP webhooks and REST API
  • Leverages existing Buzz features (workflows are YAML-defined, relay-managed)
  • Simple mental model — "when someone @mentions Hermes, POST to this URL"
  • Hermes's existing REST API can be the webhook target
  • No Nostr key management for Hermes (workflow signs events on its behalf)

Cons:

  • Workflow engine has gaps: send_dm and set_channel_topic return NotImplemented (ARCHITECTURE.md §9, WF-07). Approval gates are partially broken (WF-08). Unknown if webhook→Hermes→response path works end-to-end.
  • Workflow execution latency — not real-time; workflow engine processes events on a schedule
  • Workflows can only react to events, not participate — no typing indicators, presence, or ongoing conversation state
  • Hermes would not have its own Nostr identity — it's the workflow acting on its behalf
  • No conversational context — each @mention is a fresh workflow run
  • The workflow engine is undergoing active development; breaking changes possible
  • Rate limiting unknown for workflow-triggered actions

Effort: Low to prototype, high risk of hitting engine limitations.

2.4 Option D: Future ACP Remote Transport

Wait for the ACP Transports Working Group to ship the Streamable HTTP / WebSocket remote transport, then have Hermes implement the ACP agent side over that transport.

Status: RFD stage — no timeline, no implementation.

Pros:

  • Eventually the "right" answer — fully standards-compliant
  • Hermes would be a first-class managed agent in Buzz Desktop
  • Remote transport is being designed for exactly this use case

Cons:

  • Does not exist yet. Building anything that depends on it today is blocked.
  • Timeline unknown — could be months or years
  • Would still need to implement ACP agent protocol (not just transport)
  • ACP is coding-agent-optimized; conversational agents are a secondary concern

Effort: Blocked. Cannot proceed until spec is finalized and implemented.


3. Comparison Matrix

Criterion Bridge Agent (A) Nostr-Native (B) Webhook (C) Future ACP (D)
Works today ⚠️ Off-label Proven (OpenClaw) ⚠️ Workflow gaps Doesn't exist
Deployment complexity High (Rust binary) Medium (Python module) Low (YAML + HTTP) Unknown
Latency Low (WebSocket → stdio) Low (WebSocket native) Medium-High (workflow poll) Low
Reliability Medium (subprocess mgmt) High (direct WS) Low (engine gaps) Unknown
Buzz agent UX Full (ACP panel) Bot member (no ACP panel) None (workflow) Full (ACP panel)
Hermes identity Via buzz-acp key Own Nostr keypair Relay-owned (workflow) Own ACP identity
Presence/typing
Conversational context Via ACP sessions App-level state (per-invocation) Via ACP sessions
Maintenance burden High Medium Low (but fragile) Unknown
Protocol maturity ACP v1 (stable) NIPs (stable) Buzz workflows (beta) ACP remote (pre-RFC)
Coexists w/ other agents

4.1 Justification

The Nostr-native approach is recommended for the following reasons:

  1. Architectural correctness. Buzz IS a Nostr relay. Connecting as a Nostr client is the protocol's first-class integration path. The relay doesn't distinguish between "human," "agent," or "bot" — all are Nostr keypairs publishing signed events. Hermes joining as another keypair is exactly how Buzz was designed to work.

  2. Proven in production. OpenClaw's Buzz plugin has already solved this exact problem — connecting a server-side AI agent platform to Buzz channels via WebSocket. Their docs describe a working implementation with presence, typing indicators, mention handling, and reconnection logic.

  3. No desktop dependency. This approach runs entirely on Core. No buzz-acp binary needed. No ACP stdio bridge. No subprocess lifecycle management.

  4. Full Buzz citizenship. Hermes gets its own Nostr identity, can have a profile (kind 0), presence status, typing indicators, and can participate in any channel it's added to.

  5. No blocking dependencies. The Nostr protocol is stable (NIP-01, NIP-42, NIP-98). The ACP remote transport is not.

  6. Leverages existing Hermes infrastructure. Hermes already has a REST API, Telegram integration, MCP tools, and an AI pipeline. The Nostr client becomes another input/output channel alongside those.

  7. Coexistence. If Buzz later ships remote ACP transport, a Nostr-native Hermes can operate alongside ACP-managed agents. The two approaches are complementary, not mutually exclusive.

Trade-offs accepted:

  • Hermes appears as a "Bot" member in Buzz, not in the managed-agent ACP panel
  • No turn lifecycle management from Buzz's perspective (Hermes manages its own conversational state)
  • Must maintain WebSocket connection health (but this is standard infrastructure)

4.2 What "Bot" Member Means in Practice

In Buzz, a bot member with a Nostr keypair:

  • Can be @mentioned like any other member
  • Can post messages, reactions, and edits
  • Has an online/offline presence indicator
  • Shows typing indicators while processing
  • Can be added to or removed from channels
  • Has a profile (display name, avatar)
  • Appears in the member list with a "Bot" role badge
  • Cannot be spawned/managed via ACP (no agent panel controls)

This is functionally equivalent to how Slack bots, Discord bots, or Telegram bots work — they're members of the room, not subprocesses managed by the client.


5. Implementation Outline

5.1 Components

┌──────────────────────────────────────────────────────────────┐
│                        Core (Hermes VPS)                       │
│                                                                │
│  ┌─────────────────┐     ┌──────────────────────────────┐    │
│  │  Hermes Core    │◄───►│  Buzz Nostr Client Module    │    │
│  │  (AI pipeline,   │     │                              │    │
│  │   tools, skills) │     │  ┌──────────┐ ┌───────────┐ │    │
│  │                  │     │  │ WS Conn  │ │ Event Sign │ │    │
│  │                  │     │  │ Manager  │ │ er (Schnorr│ │    │
│  │                  │     │  └──────────┘ └───────────┘ │    │
│  │                  │     │  ┌──────────┐ ┌───────────┐ │    │
│  │                  │     │  │ Sub Mgmt │ │ Presence  │ │    │
│  │                  │     │  └──────────┘ └───────────┘ │    │
│  └─────────────────┘     └──────────────┬───────────────┘    │
│                                         │                     │
└─────────────────────────────────────────┼─────────────────────┘
                                          │ WebSocket (WSS)
                                          │ NIP-01 events
                                    ┌─────▼──────┐
                                    │ Buzz Relay │
                                    │  (app3)    │
                                    └────────────┘

New components:

  1. buzz_client.py — Nostr WebSocket client module (~500 lines)

    • WebSocket connection management (connect, reconnect, heartbeat)
    • NIP-42 authentication (sign AUTH challenge)
    • Event signing (Schnorr signatures via secp256k1 or nostr-py)
    • Subscription management (REQ, CLOSE, EVENT delivery)
    • Event publishing (EVENT → relay)
  2. buzz_channel.py — Hermes channel adapter (~200 lines)

    • Bridges Buzz events ↔ Hermes message pipeline
    • Filters events (ignore self, dedup by event ID)
    • Converts Nostr events to Hermes internal message format
    • Routes Hermes responses back to Buzz channels
    • Manages presence updates (30s interval)
  3. Buzz identity — one Nostr keypair

    • Generated via buzz-admin generate-key on app3
    • Private key stored in Hermes secrets/env
    • Public key added to relay membership and target channels

5.2 Protocols & Wire Format

Connection:

Client                                    Relay (wss://buzz.iamgmb.com)
  │  WebSocket connect                       │
  │─────────────────────────────────────────►│
  │  ← AUTH challenge                        │
  │◄─────────────────────────────────────────│
  │  AUTH response (signed challenge)        │
  │─────────────────────────────────────────►│
  │  ← AUTH OK                               │
  │◄─────────────────────────────────────────│

Subscription (NIP-01 REQ):

["REQ", "hermes-mentions", {"#p": ["<hermes_pubkey_hex>"], "kinds": [9, 40002], "since": <last_seen_timestamp>}]

Message format (kind 9 — NIP-29 group chat):

{
  "id": "<sha256>",
  "pubkey": "<sender_pubkey>",
  "kind": 9,
  "tags": [
    ["h", "<channel_uuid>"],
    ["p", "<hermes_pubkey>"],
    ["e", "<thread_root>", "", "reply"]
  ],
  "content": "{\"text\": \"@Hermes what's the status of the backup?\"}",
  "sig": "<schnorr_sig>",
  "created_at": 1234567890
}

Response message (kind 9):

{
  "id": "<sha256>",
  "pubkey": "<hermes_pubkey>",
  "kind": 9,
  "tags": [
    ["h", "<channel_uuid>"],
    ["e", "<thread_root>", "", "reply"],
    ["p", "<requester_pubkey>"]
  ],
  "content": "{\"text\": \"The backup completed successfully at 03:00 UTC. Latest snapshot: backup-2026-08-07.tar.gz\"}",
  "sig": "<schnorr_sig>",
  "created_at": 1234567895
}

Presence (kind 20001, ephemeral, not stored):

["EVENT", {
  "kind": 20001,
  "content": "{\"status\": \"online\"}",
  "tags": [],
  ...
}]

Typing indicator (kind 20002, ephemeral):

["EVENT", {
  "kind": 20002,
  "content": "",
  "tags": [["h", "<channel_uuid>"]],
  ...
}]

5.3 Auth Model

Nostr keypair:

  • Generate via buzz-admin generate-key on app3 (or openssl rand -hex 32 for privkey → derive pubkey via secp256k1)
  • Hermes holds the private key (nsec or hex) in environment/secrets
  • Public key (64-char hex) is used for:
    • Relay membership: ./run.sh add-member <hermes_pubkey> --role member
    • Channel membership: buzz channels add-member --channel <uuid> --pubkey <hermes_pubkey> --role bot
    • NIP-98 HTTP auth for REST API calls (if using REST fallback)

NIP-42 authentication flow:

  1. Relay sends ["AUTH", "<challenge_string>"] on WebSocket connect
  2. Hermes constructs a kind 22242 auth event: {"kind": 22242, "tags": [["challenge", challenge], ["relay", "wss://buzz.iamgmb.com"]], "content": "", ...}
  3. Hermes signs the event with its private key (Schnorr)
  4. Hermes sends ["AUTH", <signed_event>] to relay
  5. Relay verifies signature and pubkey membership → connection authenticated

API token alternative: Buzz supports API tokens as an alternative to NIP-42/NIP-98 for service accounts. This would replace the WebSocket auth dance with a static bearer token. However, API tokens are less documented and may not support all event kinds.

5.4 Deployment

Component Location Details
Buzz Nostr client module Core (Hermes VPS) Python module imported by Hermes; runs in-process
Nostr keypair Core (secrets) Private key in .env or HashiCorp Vault
Relay membership app3 ./run.sh add-member once during setup
Channel membership app3 (via buzz-cli) buzz channels add-member --role bot per channel
WebSocket connection Core → app3:443 WSS through CloudPanel Nginx

Note: The WebSocket connection goes through CloudPanel's Nginx reverse proxy (wss://buzz.iamgmb.com). CloudPanel already includes WebSocket upgrade headers — no Nginx config changes needed.

5.5 Python Dependencies

Package Purpose
websockets Async WebSocket client
secp256k1 (or coincurve) Schnorr signature signing/verification
cryptography SHA-256 hashing for event IDs
bech32 npub/nsec encoding (optional, for UX)

Or: Use nostr-py / python-nostr if they're mature enough. Research needed.

5.6 Effort Estimate

Phase Work Est. Days
Prototype Nostr event signing + WebSocket connect + basic REQ/EVENT 2-3
Channel adapter Message routing, dedup, mention detection, response posting 2-3
Polish Presence, typing indicators, reconnection, error handling 2-3
Integration Wire into Hermes's message pipeline + tool access 2-3
Testing Multi-channel, concurrent mentions, reconnect scenarios 2-3
Total 10-15 days

This assumes the developer is familiar with Nostr protocol basics and Python async programming.

5.7 Alternate: Use buzz-cli as a Thin Proxy

As a lower-effort starting point, Hermes could use the existing buzz-cli binary for outbound messaging (posting replies) instead of implementing Nostr event signing from scratch:

# Post a reply via buzz-cli
subprocess.run([
    "buzz", "messages", "send",
    "--channel", channel_uuid,
    "--content", response_text,
    "--reply-to", thread_event_id
], env={"BUZZ_RELAY_URL": "wss://buzz.iamgmb.com", "BUZZ_PRIVATE_KEY": hermes_nsec})

This avoids implementing Schnorr signing in Python but still requires a separate mechanism for listening to inbound mentions (since buzz-cli is request-response, not a persistent listener). The WebSocket subscription must still be implemented.


6. Open Questions

6.1 Must-Answer Before Building

# Question How to Answer
Q1 Does buzz-cli support a persistent listen/subscribe mode? Current docs show only REST commands. If it has a hidden buzz listen or buzz stream mode, the implementation simplifies dramatically. Search buzz-cli/src/ for listen/stream/subscribe; test with buzz help
Q2 What Python Nostr library is production-ready? nostr-py, python-nostr, nostr-sdk? We need WebSocket client + Schnorr signing + NIP-42 auth. Test each library against wss://buzz.iamgmb.com with a test keypair
Q3 Can a non-ACP agent get the "Bot" role and appear in the member list? OpenClaw does this, but need to verify exact permissions/UX. Test with a manually-generated keypair added via buzz channels add-member --role bot
Q4 What happens when an agent is @mentioned in a channel it hasn't joined? Does the relay deliver the event anyway? Does Buzz Desktop show it? Test by subscribing to #p tag without channel membership
Q5 How does message threading work for agents? Can Hermes reply in-thread by including the root event tag? Examine OpenClaw's threading implementation; test manually
Q6 What's the rate limit for agent-standard tier? Config defaults show 120 messages/min, but enforcement is stubbed (AlwaysAllowRateLimiter). Check if rate limiting is enforced in our relay version

6.2 Would-Be-Nice Answers

# Question
Q7 When will the ACP remote transport ship? (Informs whether to invest in Nostr-native or wait for ACP)
Q8 Can Buzz workflows be used as a reliable event bridge, or are the NotImplemented stubs blocking?
Q9 Does the relay's REST API support subscribing to events via long-poll or SSE? (Alternative to WebSocket for listening)
Q10 Can Hermes's profile (kind 0) include custom metadata that Buzz Desktop renders (e.g., "AI Assistant" badge)?
Q11 How does agent-to-agent communication work in Buzz? Can Hermes @mention another agent?
Q12 What's the multi-community story? If we host multiple Buzz communities on the same relay, can one Hermes identity participate in all?

7. References

Resource URL
Buzz GitHub https://github.com/block/buzz
Buzz README https://github.com/block/buzz/blob/main/README.md
Buzz Architecture https://github.com/block/buzz/blob/main/ARCHITECTURE.md
Buzz Agent Vision https://github.com/block/buzz/blob/main/VISION_AGENT.md
buzz-acp crate https://github.com/block/buzz/tree/main/crates/buzz-acp
buzz-cli crate https://github.com/block/buzz/tree/main/crates/buzz-cli
buzz-agent crate https://github.com/block/buzz/blob/main/crates/buzz-agent/README.md
ACP Specification https://agentclientprotocol.com/
ACP Schema https://agentclientprotocol.com/protocol/v1/schema
ACP Remote Transport RFD https://agentclientprotocol.com/rfds/streamable-http-websocket-transport
ACP GitHub https://github.com/agentclientprotocol/agent-client-protocol
Buzz .env.example https://github.com/block/buzz/blob/main/.env.example
OpenClaw Buzz Plugin https://docs.openclaw.ai/channels/buzz
Buzz Self-Host Guide https://engineering.block.xyz/blog/run-your-own-buzz-relay
Buzz Skill (internal) ~/.hermes/skills/devops/buzz-self-hosted-relay/SKILL.md
Our relay deployment /opt/buzz/deploy/compose on app3 (152.53.241.111)

Appendix A: Nostr NIPs Used by Buzz

From ARCHITECTURE.md and source analysis:

NIP Name Buzz Usage
NIP-01 Basic protocol Event format, REQ/EVENT/CLOSE messages
NIP-02 Contact list User contacts/follows
NIP-05 DNS-based identity /.well-known/nostr.json
NIP-11 Relay info GET / returns relay metadata
NIP-16 Replaceable events Profile (kind 0), channel metadata
NIP-25 Reactions Kind 7 emoji reactions
NIP-27 Text note references nostr:npub1... and nostr:note1...
NIP-29 Group chat Kind 9 stream messages
NIP-34 Git hosting Repository announcements, patches
NIP-38 User statuses Profile status text+emoji
NIP-42 Auth AUTH challenge-response on WebSocket
NIP-98 HTTP Auth Schnorr-signed kind 27235 for REST API

Appendix B: Buzz Custom Event Kinds

Kind Name Description
9 Stream message Channel chat message (NIP-29)
7 Reaction Emoji reaction (NIP-25)
20001 Presence Ephemeral online/away status
20002 Typing Ephemeral typing indicator
22242 Auth NIP-42 authentication event
27235 HTTP Auth NIP-98 HTTP authentication
40002 Stream message v2 Rich-content channel message
40003 Stream message edit Edit of a previous message
40008 Structured diff Code diff with metadata
43001 Job request Agent job request (ACP)
40100 Canvas Channel canvas content