mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
docs: comprehensive README accuracy pass — verified against every line of code (#233)
This commit is contained in:
@@ -16,24 +16,30 @@ append-only and audited.
|
||||
| | |
|
||||
|-|--|
|
||||
| ✅ | **Nostr wire protocol** — any Nostr client works out of the box |
|
||||
| ✅ | **YAML-as-code workflows** — automation with approval gates and execution traces |
|
||||
| ✅ | **YAML-as-code workflows** — automation with execution traces (approval gates: planned) |
|
||||
| ✅ | **Agent-native MCP server** — LLMs are first-class participants |
|
||||
| ✅ | **ACP agent harness** — AI agents connect out of the box via `sprout-acp` |
|
||||
| ✅ | **Tamper-evident audit log** — hash-chain, SOX-grade compliance |
|
||||
| ✅ | **Permission-aware full-text search** — Typesense, respects channel membership |
|
||||
| ✅ | **Enterprise SSO bridge** — NIP-42 authentication with OIDC |
|
||||
| ✅ | **All Rust** — memory safe, single binary, no GC pauses |
|
||||
| ✅ | **Pure Rust backend** — memory safe, no GC pauses |
|
||||
|
||||
## Supported NIPs
|
||||
|
||||
| NIP | Title | Status |
|
||||
|-----|-------|--------|
|
||||
| [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md) | Basic protocol flow — events, filters, subscriptions | ✅ Implemented |
|
||||
| [NIP-05](https://github.com/nostr-protocol/nips/blob/master/05.md) | Mapping Nostr keys to DNS-based internet identifiers | ✅ Implemented |
|
||||
| [NIP-09](https://github.com/nostr-protocol/nips/blob/master/09.md) | Event deletion | ✅ Implemented |
|
||||
| [NIP-10](https://github.com/nostr-protocol/nips/blob/master/10.md) | Conventions for clients' use of `e` and `p` tags in text events | ✅ Implemented |
|
||||
| [NIP-11](https://github.com/nostr-protocol/nips/blob/master/11.md) | Relay information document | ✅ Implemented |
|
||||
| [NIP-17](https://github.com/nostr-protocol/nips/blob/master/17.md) | Private Direct Messages | ✅ Implemented |
|
||||
| [NIP-25](https://github.com/nostr-protocol/nips/blob/master/25.md) | Reactions | ✅ Implemented |
|
||||
| [NIP-28](https://github.com/nostr-protocol/nips/blob/master/28.md) | Public chat channels | ✅ Via `sprout-proxy` (kind translation) |
|
||||
| [NIP-29](https://github.com/nostr-protocol/nips/blob/master/29.md) | Relay-based groups | ✅ Partial (kinds 9000–9008 implemented; 9009, 9021 deferred) |
|
||||
| [NIP-29](https://github.com/nostr-protocol/nips/blob/master/29.md) | Relay-based groups | ✅ Partial (kinds 9000–9002, 9005, 9007–9008, 9021–9022 implemented; 9009 stubbed) |
|
||||
| [NIP-42](https://github.com/nostr-protocol/nips/blob/master/42.md) | Authentication of clients to relays | ✅ Implemented |
|
||||
| [NIP-50](https://github.com/nostr-protocol/nips/blob/master/50.md) | Search capability | ✅ Implemented |
|
||||
| [NIP-98](https://github.com/nostr-protocol/nips/blob/master/98.md) | HTTP Auth | ✅ Partial (`POST /api/tokens` bootstrap only) |
|
||||
|
||||
## Architecture
|
||||
|
||||
@@ -59,21 +65,17 @@ append-only and audited.
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ sprout-relay │
|
||||
│ │
|
||||
│ NIP-01 handler · NIP-42 auth · channel REST · admin API │
|
||||
└──────────┬──────────────────────┬───────────────────────────────────────┘
|
||||
│ │
|
||||
┌──────▼──────┐ ┌──────▼──────┐
|
||||
│ Postgres │ │ Redis │
|
||||
│ (events, │ │ (pub/sub, │
|
||||
│ channels, │ │ presence) │
|
||||
│ tokens) │ └─────────────┘
|
||||
└──────┬──────┘
|
||||
│
|
||||
┌──────▼──────┐
|
||||
│ Typesense │
|
||||
│ (full-text │
|
||||
│ search) │
|
||||
└─────────────┘
|
||||
│ NIP-01 handler · NIP-42 auth · channel/DM/media/workflow REST │
|
||||
└───┬──────────────────┬──────────────────┬──────────────────┬────────────┘
|
||||
│ │ │ │
|
||||
┌──▼───────┐ ┌──────▼──────┐ ┌──────▼──────┐ ┌─────▼─────┐
|
||||
│ Postgres │ │ Redis │ │ Typesense │ │ S3/MinIO │
|
||||
│ (events, │ │ (pub/sub, │ │ (full-text │ │ (media │
|
||||
│ channels,│ │ presence, │ │ search) │ │ uploads) │
|
||||
│ users, │ │ typing) │ └─────────────┘ └───────────┘
|
||||
│ workflows│ └─────────────┘
|
||||
│ …) │
|
||||
└──────────┘
|
||||
```
|
||||
|
||||
## Crate Map
|
||||
@@ -81,36 +83,43 @@ append-only and audited.
|
||||
**Core protocol**
|
||||
| Crate | Role |
|
||||
|-------|------|
|
||||
| `sprout-core` | Nostr types, event/filter primitives, kind constants |
|
||||
| `sprout-relay` | Axum WebSocket server — NIP-01 message loop, channel REST, admin routes |
|
||||
| `sprout-core` | Zero-I/O foundation types — `StoredEvent`, NIP-01 filter matching, Schnorr verification, kind constants, channel/presence types |
|
||||
| `sprout-relay` | Axum WebSocket server — NIP-01 message loop, channel/DM/media/workflow REST, Blossom media upload |
|
||||
|
||||
**Services**
|
||||
| Crate | Role |
|
||||
|-------|------|
|
||||
| `sprout-db` | Postgres access layer — events, channels, API tokens (sqlx) |
|
||||
| `sprout-auth` | NIP-42 challenge/response + Okta OIDC JWT validation + token scopes |
|
||||
| `sprout-pubsub` | Redis pub/sub bridge — fan-out events across relay instances |
|
||||
| `sprout-db` | Postgres access layer — events, channels, users, DMs, threads, reactions, workflows, tokens, feed (sqlx) |
|
||||
| `sprout-auth` | NIP-42 challenge/response + Okta OIDC JWT validation + NIP-98 HTTP Auth + token scopes + rate limiting |
|
||||
| `sprout-pubsub` | Redis pub/sub fan-out, presence tracking, typing indicators, and rate limiting |
|
||||
| `sprout-search` | Typesense indexing and query — full-text search over event content |
|
||||
| `sprout-audit` | Append-only audit log with hash chain for tamper detection |
|
||||
| `sprout-audit` | Append-only audit log with SHA-256 hash chain for tamper detection |
|
||||
|
||||
**Agent interface**
|
||||
| Crate | Role |
|
||||
|-------|------|
|
||||
| `sprout-mcp` | stdio MCP server — 43 tools for messages, channels, workflows, and feed |
|
||||
| `sprout-mcp` | stdio MCP server — tools for messaging, channels, DMs, canvas, workflows, forums, search, profiles, and presence |
|
||||
| `sprout-acp` | ACP harness — bridges Sprout relay events to AI agents over stdio (goose, codex, claude code) |
|
||||
| `sprout-workflow` | YAML-as-code workflow engine — triggers, actions, approval gates, execution traces |
|
||||
| `sprout-huddle` | LiveKit integration — voice/video session tokens for channel participants |
|
||||
| `sprout-workflow` | YAML-as-code workflow engine — message/reaction/diff/schedule/webhook triggers, action dispatch, execution traces |
|
||||
| `sprout-huddle` | LiveKit integration — voice/video session tokens, webhook verification, in-memory session tracking |
|
||||
|
||||
**Client compatibility**
|
||||
| Crate | Role |
|
||||
|-------|------|
|
||||
| `sprout-proxy` | NIP-28 compatibility proxy — standard Nostr clients (Coracle, nak, Amethyst) read/write Sprout channels via kind translation, shadow keypairs, and guest auth. See [NOSTR.md](NOSTR.md) |
|
||||
|
||||
**Shared libraries**
|
||||
| Crate | Role |
|
||||
|-------|------|
|
||||
| `sprout-sdk` | Typed Nostr event builders — used by sprout-mcp, sprout-acp, and sprout-cli |
|
||||
| `sprout-media` | Blossom/S3 media storage, validation, and thumbnail generation |
|
||||
|
||||
**Tooling**
|
||||
| Crate | Role |
|
||||
|-------|------|
|
||||
| `sprout-cli` | Agent-first CLI for interacting with the relay |
|
||||
| `sprout-admin` | CLI for minting API tokens and listing active credentials |
|
||||
| `sprout-test-client` | WebSocket test harness for integration tests |
|
||||
| `sprout-test-client` | Integration test client and E2E test suite — relay, REST API, tokens, MCP, media, media extended, Nostr interop, and workflows |
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -136,7 +145,7 @@ just build
|
||||
|
||||
`just setup` does the heavy lifting:
|
||||
- Starts Docker services (Postgres, Redis, Typesense, Adminer, Keycloak, MinIO, Prometheus)
|
||||
- Waits for all services to be healthy
|
||||
- Waits for core services (Postgres, Redis, Typesense) to be healthy
|
||||
- Runs database migrations
|
||||
- Installs desktop dependencies (`pnpm install`)
|
||||
|
||||
@@ -227,11 +236,32 @@ Copy `.env.example` to `.env` and adjust as needed. All defaults work out of the
|
||||
| `SPROUT_PROXY_SALT` | — | Hex 32-byte salt for shadow key derivation |
|
||||
| `SPROUT_PROXY_API_TOKEN` | — | Sprout API token with `proxy:submit` scope |
|
||||
| `SPROUT_PROXY_ADMIN_SECRET` | — | Bearer secret for proxy admin endpoints (optional — omit for dev mode) |
|
||||
| `SPROUT_CORS_ORIGINS` | — | Comma-separated allowed CORS origins (unset = permissive) |
|
||||
| `SPROUT_HEALTH_PORT` | `8080` | Port for health check endpoint (separate from main bind) |
|
||||
| `SPROUT_MAX_CONCURRENT_HANDLERS` | `1024` | Max concurrent EVENT/REQ handlers |
|
||||
| `SPROUT_MAX_CONNECTIONS` | `10000` | Max simultaneous WebSocket connections |
|
||||
| `SPROUT_MAX_GIF_BYTES` | `10485760` | Max GIF upload size in bytes (10 MB) |
|
||||
| `SPROUT_MAX_IMAGE_BYTES` | `52428800` | Max image upload size in bytes (50 MB) |
|
||||
| `SPROUT_MEDIA_BASE_URL` | `http://localhost:3000/media` | Public base URL for media files |
|
||||
| `SPROUT_MEDIA_SERVER_DOMAIN` | auto-derived from `RELAY_URL` | Media server domain as `host[:port]` |
|
||||
| `SPROUT_S3_ENDPOINT` | `http://localhost:9000` | S3-compatible endpoint URL (MinIO in dev) |
|
||||
| `SPROUT_S3_ACCESS_KEY` | `sprout_dev` | S3 access key |
|
||||
| `SPROUT_S3_SECRET_KEY` | `sprout_dev_secret` | S3 secret key |
|
||||
| `SPROUT_S3_BUCKET` | `sprout-media` | S3 bucket name for media uploads |
|
||||
| `SPROUT_METRICS_PORT` | `9102` | Port for Prometheus metrics endpoint |
|
||||
| `SPROUT_PUBKEY_ALLOWLIST` | `false` | Restrict NIP-42 pubkey-only auth to allowlisted keys (`true`/`1`); API token and Okta JWT auth bypass |
|
||||
| `SPROUT_SEND_BUFFER` | `1000` | WebSocket send buffer size |
|
||||
| `SPROUT_UDS_PATH` | — | Unix domain socket path (alternative to TCP) |
|
||||
| `OKTA_JWKS_URI` | — | Okta JWKS endpoint URI for JWT verification |
|
||||
| `SPROUT_TOOLSETS` | `default` | MCP toolsets to enable (comma-separated: `default`, `channel_admin`, `dms`, `canvas`, `workflow_admin`, `identity`, `forums`, `all`, `none`; append `:ro` for read-only) |
|
||||
| `SPROUT_MINT_RATE_LIMIT` | `50` | Max API token mints per pubkey per hour |
|
||||
| `SPROUT_RELAY_PUBKEY` | — | Relay's hex pubkey — required by `sprout-proxy`; also used as fallback auth by `sprout-workflow` when no API token is set |
|
||||
|
||||
## MCP Tools
|
||||
|
||||
The `sprout-mcp` server exposes 43 tools over stdio, covering messaging, channels, threads,
|
||||
reactions, DMs, workflows, search, profiles, presence, and more. Agents discover tools
|
||||
The `sprout-mcp` server exposes tools over stdio, organized into toolsets: `default` (25 tools
|
||||
active out of the box), `channel_admin`, `dms`, `canvas`, `workflow_admin`, `identity`, and
|
||||
`forums`. Set `SPROUT_TOOLSETS=all` to enable every tool. Agents discover available tools
|
||||
automatically via the MCP protocol — see [AGENTS.md](AGENTS.md) for integration details.
|
||||
|
||||
## Development
|
||||
@@ -269,6 +299,7 @@ just reset # ⚠️ Wipe all data and recreate environment
|
||||
|
||||
```bash
|
||||
cargo run -p sprout-relay
|
||||
cargo run -p sprout-cli -- --help
|
||||
cargo run -p sprout-admin -- --help
|
||||
cargo run -p sprout-mcp --bin sprout-mcp-server
|
||||
cargo run -p sprout-proxy
|
||||
@@ -281,8 +312,8 @@ cargo run -p sprout-proxy
|
||||
Run `just test-unit` for unit tests (no infra required) or `just test` for the full suite.
|
||||
See [TESTING.md](TESTING.md) for the multi-agent E2E suite (Alice/Bob/Charlie via `sprout-acp`).
|
||||
|
||||
**Database schema** lives in `schema/schema.sql`. The relay applies it automatically on startup.
|
||||
To run manually: `just migrate`.
|
||||
**Database schema** lives in `schema/schema.sql`. Apply it with `just migrate`; `just setup`
|
||||
runs migrations automatically as part of environment setup.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
Reference in New Issue
Block a user