Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Buzz Architecture

> **Note:** this document has been migrated into [docs/architecture/](docs/architecture/overview.md) (one page per section; §9 lives in [docs/reference/known-limitations.md](docs/reference/known-limitations.md)). The docs tree is canonical; this file is retained temporarily and may be removed in a follow-up.

## 1. Executive Summary

Buzz is a self-hosted team communication platform built on the Nostr protocol (NIP-01 wire format), where AI agents and humans are first-class equals. Every action — a chat message, a reaction, a workflow step, a canvas update, a huddle event — is a cryptographically signed Nostr event identified by a `kind` integer. Adding a new feature means defining a new kind number; existing clients see nothing and break nothing.
Expand Down
2 changes: 2 additions & 0 deletions NOSTR.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Using Third-Party Nostr Clients with Buzz

> **Note:** this document has been migrated: protocol semantics → [docs/architecture/protocol.md](docs/architecture/protocol.md), client-interop how-to → [docs/guides/nostr-clients.md](docs/guides/nostr-clients.md). The docs tree is canonical; this file is retained temporarily and may be removed in a follow-up.

Buzz is a Nostr relay that speaks NIP-29 (relay-based groups) natively. Third-party Nostr clients connect directly to `buzz-relay` using NIP-29 and NIP-42 authentication. The old NIP-28 compatibility proxy has been removed.

## Community scope
Expand Down
2 changes: 2 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Releasing Buzz

> **Note:** this document has been migrated to [docs/guides/releasing.md](docs/guides/releasing.md). The docs tree is canonical; this file is retained temporarily and may be removed in a follow-up.

Buzz has three independent release lanes, each driven by a release PR — no human
ever pushes a git tag:

Expand Down
2 changes: 2 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Testing

> **Note:** this document has been migrated into the docs tree: local relay setup → [docs/getting-started/local-relay.md](docs/getting-started/local-relay.md), testing guide → [docs/guides/testing.md](docs/guides/testing.md), agent harness → [docs/guides/agents.md](docs/guides/agents.md), configuration tables → [docs/reference/configuration.md](docs/reference/configuration.md). The docs tree is canonical; this file is retained temporarily and may be removed in a follow-up.

## Automated Tests

```bash
Expand Down
2 changes: 2 additions & 0 deletions VISION.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# 🐝 Buzz — The relay is the workspace

> **Note:** this document has been migrated to [docs/vision/README.md](docs/vision/README.md). The docs tree is canonical; this file is retained temporarily and may be removed in a follow-up.

> An engineer is debugging a production incident at 2am. They type in the incident channel: "What happened last time we saw this error?"
>
> An agent watching the channel searches six months of incident history and posts the threads, root causes, and fixes — then offers to page the engineer who deployed the last one.
Expand Down
2 changes: 2 additions & 0 deletions VISION_ACTIVITY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Vision: The Agent Activity Feed

> **Note:** migrated to [docs/vision/activity.md](docs/vision/activity.md); the docs tree is canonical. Retained temporarily.

## The Problem

When you delegate work to an agent, you are trusting a process you cannot see. The activity feed is the window into that process — but a window is only useful if you can read it at a glance. A raw input/output dump is not a window; it is a transcript you have to decode. It forces you to *parse* before you can *judge*.
Expand Down
2 changes: 2 additions & 0 deletions VISION_AGENT.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Vision: buzz-agent + buzz-dev-mcp

> **Note:** migrated to [docs/vision/agent.md](docs/vision/agent.md); the docs tree is canonical. Retained temporarily.

## The Problem

A coding agent should be small enough to hold in your head. If you cannot trace a failure from symptom to root cause in minutes, the system is too complex. If you cannot run ten instances in parallel without worrying about resource overhead, the system is too heavy.
Expand Down
2 changes: 2 additions & 0 deletions VISION_MESH.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# 🕸️ Buzz Mesh — Your community is your compute

> **Note:** migrated to [docs/vision/mesh.md](docs/vision/mesh.md); the docs tree is canonical. Retained temporarily.

> A small team runs their project on one Buzz relay. Three of them have GPUs that sit idle most of the day — a gaming PC, a laptop, a workstation under a desk. One flips a toggle: *Share compute.* The others point their agents at it. Now the whole team's coding agents answer from a capable model running on hardware they already own. No API keys. No cloud bill. Every prompt runs inside the relay community they already chose to trust.

A Buzz community is a trust group. The people in it already know each other — that shared membership is a decision they've already made. Buzz Mesh turns that decision into shared AI compute: the idle GPUs scattered across your community become one pool, usable by every agent in the community, gated by the membership you already have. And because the pool is many machines, not one, the community can run models larger and more capable than any one member could load alone. More intelligence becomes reachable when the group works as a group.
Expand Down
2 changes: 2 additions & 0 deletions VISION_PROJECTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# 🐝 Buzz Projects — A Nostr-Native Forge

> **Note:** migrated to [docs/vision/projects.md](docs/vision/projects.md); the docs tree is canonical. Retained temporarily.

> Someone pushes a fix. Buzz creates a channel for the branch. The CI agent picks up the push, runs the tests, posts results back to the channel. A co-maintainer reviews the diff inline, approves it — a signed event, cryptographic proof. Merge. The workflow runs the integration. The channel archives into a permanent record of why that code exists.
>
> Bug report to merged patch. One place. One search index. One identity system. The branch channel was the pull request, the CI dashboard, and the discussion thread.
Expand Down
2 changes: 2 additions & 0 deletions VISION_SOVEREIGN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Buzz — Your Project, Your Domain

> **Note:** migrated to [docs/vision/sovereign.md](docs/vision/sovereign.md); the docs tree is canonical. Retained temporarily.

`myproject.com` is your workspace. Not a GitHub org page that happens to have your
name on it. Not a Discord server that Discord could delete tomorrow. Your domain.
Your relay. One thing.
Expand Down
64 changes: 64 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Buzz Documentation

## Getting Started

- [Installation](getting-started/installation.md)
- [Quickstart](getting-started/quickstart.md)
- [Running a Local Relay](getting-started/local-relay.md)

## Architecture

- [Overview](architecture/overview.md)
- [Protocol](architecture/protocol.md)
- [Connection Lifecycle](architecture/connection-lifecycle.md)
- [Event Pipeline](architecture/event-pipeline.md)
- [Subscription System](architecture/subscriptions.md)
- [Crate Reference](architecture/crates.md)
- [Security Model](architecture/security-model.md)
- [Infrastructure](architecture/infrastructure.md)

## Guides

- [Development](guides/development.md)
- [Testing](guides/testing.md)
- [Working with Agents](guides/agents.md)
- [Workflows](guides/workflows.md)
- [Self-Hosting](guides/self-hosting.md)
- [Using Third-Party Nostr Clients](guides/nostr-clients.md)
- [Adding a New Event Kind](guides/adding-event-kinds.md)
- [Adding a New API Endpoint](guides/adding-api-endpoints.md)
- [Releasing](guides/releasing.md)

## Reference

- [CLI Reference](reference/cli.md)
- [Configuration](reference/configuration.md)
- [Known Limitations](reference/known-limitations.md)
- [Buzz NIPs Index](reference/nips.md) → [`nips/`](nips/)
- [Design Documents Index](reference/design-docs.md) → loose docs + [`spec/`](spec/)

## Vision

Aspirational direction — **not** current behavior (see [known limitations](reference/known-limitations.md) for what's real today):

- [The relay is the workspace](vision/README.md) — core vision
- [Agent Activity Feed](vision/activity.md)
- [buzz-agent + buzz-dev-mcp](vision/agent.md)
- [Buzz Mesh](vision/mesh.md) — community compute
- [Buzz Projects](vision/projects.md) — Nostr-native forge
- [Sovereign relay](vision/sovereign.md) — your project, your domain

## Root-Level Docs (stay at repository root)

GitHub-convention files remain at the root: `README.md`, `CONTRIBUTING.md`, `SECURITY.md`,
`GOVERNANCE.md`, `CODE_OF_CONDUCT.md`, `CHANGELOG.md`, `AGENTS.md`/`CLAUDE.md`.

`ARCHITECTURE.md`, `NOSTR.md`, `TESTING.md`, `RELEASING.md`, and `VISION*.md` have been
migrated into this tree. The originals remain at the root with pointer notes for now;
removing them is a follow-up decision. **This tree is canonical for migrated content.**

## Note on file locations

`docs/nips/`, `docs/spec/`, and the loose design docs (`docs/*.md`) are referenced by
code, tests, and migrations (55 references outside `docs/`). They stay at their current
paths; the `reference/` index pages link to them instead.
60 changes: 60 additions & 0 deletions docs/architecture/connection-lifecycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Connection Lifecycle

Every WebSocket connection to the relay follows the same sequence: community
binding, capacity check, NIP-42 challenge, authentication, active loops, and
cleanup. Client-side reconnection behavior lives in
[`crates/buzz-ws-client`](../../crates/buzz-ws-client); the relay side is
[`crates/buzz-relay`](../../crates/buzz-relay).

Every WebSocket connection follows this exact sequence:

## Step 0: Community Binding

The server resolves `TenantContext` from the request host before any handler can
observe tenant data. The URL/domain is authoritative for the community, matching
today's "the relay URL is the workspace" behavior. In single-community mode the
configured host maps to the default community. In multi-community mode, an
unknown or unmapped host rejects generically and never falls through to a default
tenant. Client-supplied `#h` tags are still channel identifiers; they must resolve
to a channel inside the host-derived community.

## Step 1: Semaphore Acquire

`state.conn_semaphore.try_acquire_owned()` — if the relay is at connection capacity, the connection is rejected immediately before any data is read. The permit is held for the entire connection lifetime and dropped on cleanup.

## Step 2: NIP-42 Challenge

The relay immediately sends `["AUTH", "<challenge>"]`. The challenge is a random string. The connection is registered in `ConnectionManager` after the challenge is sent.

## Step 3: Authentication

The client must respond with `["AUTH", <signed-event>]` before submitting events or subscriptions. Authentication paths:

| Path | Mechanism | Use Case |
|------|-----------|---------|
| NIP-42 | Signed challenge, pubkey verified | WebSocket connections |
| NIP-98 HTTP Auth | Schnorr-signed `kind:27235` event on HTTP bridge endpoints | HTTP clients |

On success, `ConnectionState.auth_state` transitions from `Pending` → `Authenticated(AuthContext)`. On failure → `Failed`. Unauthenticated EVENT/REQ messages are rejected with `["CLOSED", ...]` or `["OK", ..., false, "auth-required: ..."]`.

## Step 4: Active Loops

Three concurrent tasks run for the lifetime of the connection:

- **recv_loop** (inline): reads frames, parses `ClientMessage`, dispatches to handlers
- **send_loop** (spawned): drains the mpsc channel, writes frames to the WebSocket
- **heartbeat_loop** (spawned): sends WebSocket ping every 30 seconds; 3 missed pongs → disconnect

A `CancellationToken` coordinates shutdown across all three loops.

Slow clients: `ConnectionState::send()` uses `try_send` — if the send buffer is full, a grace counter increments. After `SLOW_CLIENT_GRACE_LIMIT` (3) consecutive full-buffer events, the connection is cancelled. A successful send resets the counter.

## Step 5: Cleanup

On disconnect (any cause):
1. `cancel.cancel()` — signals all loops
2. Await send_loop and heartbeat_loop tasks
3. `sub_registry.remove_connection(conn_id)` — removes all subscriptions from the DashMap indexes
4. `conn_manager.deregister(conn_id)` — removes from the send-channel map
5. `drop(permit)` — releases the connection semaphore slot

Loading
Loading