# 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](https://agentclientprotocol.com/), governed by a spec repo at [github.com/agentclientprotocol/agent-client-protocol](https://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:** `initialize` → `session/new` → `session/prompt` → `session/update` (streaming) → `StopReason` - **Concepts:** Sessions, tool calls, cancellation, context window updates, authentication - **Rust crate:** [`acp-sdk`](https://crates.io/crates/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](https://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. ### 2.2 Option B: Nostr-Native WebSocket Client (RECOMMENDED) 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](https://docs.openclaw.ai/channels/buzz) 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/prompt` → `end_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. Recommended Path: Nostr-Native WebSocket Client ### 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):** ```json ["REQ", "hermes-mentions", {"#p": [""], "kinds": [9, 40002], "since": }] ``` **Message format (kind 9 — NIP-29 group chat):** ```json { "id": "", "pubkey": "", "kind": 9, "tags": [ ["h", ""], ["p", ""], ["e", "", "", "reply"] ], "content": "{\"text\": \"@Hermes what's the status of the backup?\"}", "sig": "", "created_at": 1234567890 } ``` **Response message (kind 9):** ```json { "id": "", "pubkey": "", "kind": 9, "tags": [ ["h", ""], ["e", "", "", "reply"], ["p", ""] ], "content": "{\"text\": \"The backup completed successfully at 03:00 UTC. Latest snapshot: backup-2026-08-07.tar.gz\"}", "sig": "", "created_at": 1234567895 } ``` **Presence (kind 20001, ephemeral, not stored):** ```json ["EVENT", { "kind": 20001, "content": "{\"status\": \"online\"}", "tags": [], ... }] ``` **Typing indicator (kind 20002, ephemeral):** ```json ["EVENT", { "kind": 20002, "content": "", "tags": [["h", ""]], ... }] ``` ### 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 --role member` - Channel membership: `buzz channels add-member --channel --pubkey --role bot` - NIP-98 HTTP auth for REST API calls (if using REST fallback) **NIP-42 authentication flow:** 1. Relay sends `["AUTH", ""]` 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", ]` 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: ```python # 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 |