> your AI agent picks dependencies from memory; give it dated facts — try starlog.dev ↗ vet your agent's deps ↗ vibe-coding is fine. vibe-importing isn’t. — try starlog.dev ↗ vibe-importing isn’t fine ↗ your agent has never seen your private packages — try starlog.dev ↗ facts for private packages ↗ a linter for the dependencies your AI agent picks — try starlog.dev ↗ a linter for agent deps ↗ whois is redacted, cdns mask the rest — get the real operator — try whoisgeni.us ↗ who really runs that domain ↗ domain attribution that shows its work — full evidence chain — try whoisgeni.us ↗ domain intel w/ evidence ↗

← Back to Articles

Buzz: The Event-Sourced Workspace Where Your CI Pipeline Is Just Another Chat Message

[ View on GitHub ]

Buzz: The Event-Sourced Workspace Where Your CI Pipeline Is Just Another Chat Message

Hook

What if your deployment approval, the Slack thread debating it, the git commit it references, and the AI agent that ran your tests were all the same type of database row—queryable with one SQL statement?

Context

Modern development workflows are archaeological nightmares. A production incident surfaces, and you're spelunking through Slack for the discussion, GitHub for the PR, Linear for the ticket, Jenkins for the build logs, and PagerDuty for who approved the deploy—each system a separate source of truth with its own authentication, audit log, and search limitations. The 'why did we ship this?' question requires correlating timestamps across six browser tabs.

The agent integration tax makes this worse. Your AI code reviewer needs GitHub API access. Your deployment bot needs Slack webhooks and Jenkins credentials. Your documentation updater needs Confluence permissions. Each agent is a bespoke integration with custom auth, separate audit trails, and permission models that don't compose. When an agent makes a mistake, tracing its decision chain means correlating logs across every system it touched. Buzz's architectural bet is radical simplification: everything is a cryptographically signed event in a Postgres table, and humans and AI agents are protocol-level identical.

Technical Insight

Buzz is a Nostr relay implementation, but that undersells what's happening. Nostr provides the substrate—WebSocket event streaming, Schnorr signature validation, JSON event schemas—while Buzz layers workspace semantics on top. Every action becomes an event with kind, content, pubkey (identity), and sig (cryptographic proof). A chat message is kind 1. A git commit notification is kind 1617 (NIP-34). A workflow approval is a custom kind. All flow through the same relay, stored in the same Postgres table, queryable together.

Here's what agent participation looks like in practice. An AI agent generates an nsec (Nostr secret key) just like a human. When it wants to post a code review comment, it creates a signed event:

// Agent generates event client-side
let event = EventBuilder::new(
    Kind::Custom(1621), // Code review comment
    json!({
        "repo": "block/buzz",
        "commit": "a4f392c",
        "file": "src/relay.rs",
        "line": 156,
        "comment": "This mutex lock is held across an await point"
    }).to_string(),
    &[]
)
.to_event(&agent_keys)?;

// Relay validates signature, stores event
let valid = event.verify_signature()?;
if valid {
    sqlx::query!(
        "INSERT INTO events (id, pubkey, created_at, kind, content, sig) VALUES ($1, $2, $3, $4, $5, $6)",
        event.id.to_hex(),
        event.pubkey.to_hex(),
        event.created_at,
        event.kind.as_u64(),
        event.content,
        event.sig.to_hex()
    ).execute(&pool).await?;
}

The relay doesn't care that this came from an agent. The signature proves the holder of that nsec authorized this event. Audit logs, permission checks, and attribution work identically for humans and agents. No separate 'bot user' abstraction, no API tokens to rotate, no webhook delivery mysteries.

The git integration is where this architecture pays compounding dividends. When you push a commit, Buzz creates a NIP-34 event with the patch as content. Code review comments are events with e tags referencing the commit event. CI results are events tagged to the same commit. Merge approval is another event. Now you can query: 'Show me all commits where the AI reviewer flagged concurrency issues and the CI passed but humans overrode the merge block.' That's one database query across events of different kinds:

SELECT DISTINCT c.content->>'commit' 
FROM events c
JOIN events ai_review ON ai_review.tags @> ARRAY[ARRAY['e', c.id]]
JOIN events ci ON ci.tags @> ARRAY[ARRAY['e', c.id]]
JOIN events merge ON merge.tags @> ARRAY[ARRAY['e', c.id]]
WHERE c.kind = 1617 -- git commit
  AND ai_review.kind = 1621 -- code review
  AND ai_review.content LIKE '%concurrency%'
  AND ci.kind = 1630 -- CI result
  AND ci.content->>'status' = 'passed'
  AND merge.kind = 1631 -- merge decision
  AND merge.pubkey != ai_review.pubkey; -- human override

This isn't duct-taping API responses together. The discussion, the code, the automation results, and the decision are siblings in the same event log. Postgres full-text search, time-range queries, and pubkey filters work uniformly.

The buzz-cli tool exposes this as JSON for LLM function calling. An agent framework like Goose can treat Buzz as a native protocol:

{
  "function": "buzz_send_message",
  "arguments": {
    "channel": "eng-platform",
    "content": "Deployment to prod blocked: 3 flaky tests in payment service",
    "references": ["commit:a4f392c", "workflow:deploy-prod-42"]
  }
}

The CLI translates this to a signed Nostr event with appropriate tags, posts it to the relay, and returns the event ID. The agent's message appears in the channel alongside human messages, tagged to the commit and workflow it references. The audit log shows the agent's pubkey. If this agent is compromised tomorrow, you revoke its nsec and see exactly what it posted—same process as a compromised human account.

Multi-tenancy happens in the data layer, not relay instances. When you query events, Postgres row-level security filters by community_id based on your auth token. Redis cache keys are prefixed with tenant namespace. S3 media uploads bucket to tenant paths. From the client's perspective, wss://buzz.yourcompany.com is your entire universe—there's no global namespace, no cross-tenant event visibility. Self-hosters run one relay per organization. Hosted operators run one relay serving many organizations with database-level isolation.

Gotcha

The relay federation story is conspicuously absent, which undermines Buzz's Nostr foundation. Nostr's value proposition is censorship resistance through multi-relay redundancy—clients connect to many relays, and no single operator controls your data. Buzz documents 'one URL = one community' with tenant isolation at the data layer, which means you're trusting a single relay operator. There's no mechanism for syncing your workspace events to backup relays, no relay discovery protocol, no handling of relay operator disputes. If your relay goes down, your workspace is offline. This is a centralized system using decentralized protocols, not a decentralized system. The architecture could support federation, but it's not implemented or roadmapped.

Performance characteristics are underdocumented for an event-sourced system. Postgres full-text search will degrade as event tables grow into millions of rows without partitioning strategies. There's no discussion of event log compaction, snapshot strategies, or how to archive old communities. The demo likely works beautifully with 10,000 events; a year-old workspace with 10 million events is a different animal. Mobile client sync after hours offline is marked 'pending code'—which means the hardest part of offline-first architectures (conflict resolution, incremental sync, battery-efficient polling) isn't solved yet. Key rotation and compromised key revocation are punted to operators without tooling or documented procedures.

Verdict

Use if: You're a platform team at a 50-500 person company tired of duct-taping Slack, GitHub, and CI into a workflow, you can self-host Postgres infrastructure, and you value 'query everything in one place' more than mobile-first collaboration. The architectural bet on event-sourced workspaces with cryptographic identity is compelling if you're building internal tooling and can absorb rough edges. AI agents as first-class workspace members with their own keys solves real authorization problems that role-based systems struggle with. Skip if: You need mature mobile clients (they're not ready), you want a hosted SaaS offering (doesn't exist), you require actual decentralization rather than self-hosted centralization (federation is vaporware), or you're a small team that just needs chat-plus-integrations (Slack works fine and you don't need this complexity). This is a pioneer tax situation—interesting primitives, incomplete execution, honest about gaps.