What Bubble is
What Bubble is, the core concepts it builds on, and how the rest of these docs fit together.
docs/concepts/10-bubble.mdxOn this page
Bubble is the live event bus that powers OctoStaff user/agent collaboration. At its core it does one thing: it stores threads of events and lets many clients append to and subscribe to those threads in real time.
Everything else in Bubble exists to make that core safe and composable — identities for the actors that read and write (principals), permissions that gate which actor can do what (grants/roles), and two transports that wire the API up to networks (HTTP and WebSocket).
The Three Building Blocks
The mental model is small. Once these three concepts are clear the rest of the package is a thin shell around them.
Thread
A thread is an ordered, append-only stream of events. Each event gets a monotonically increasing sequence number when it is written, so two subscribers reading the same thread see exactly the same sequence in exactly the same order. Threads have an id, a head sequence number, a creation time, and (optionally) a parent thread.
interface BubbleThread {
threadId: string;
parentThreadId?: string; // present on subthreads
headSeq: number; // 0 when empty, otherwise the latest seq
createdAt: string; // RFC 3339
participants: Participant[];
}Threads are covered in detail in Thread Model.
Event
An event is a single immutable record on a thread. Bubble defines a closed
set of event shapes — run lifecycle (run_started / run_finished),
streamed message content (message_part), tool-call review and results,
interrupt requests, and participant join/leave. A run is any bounded
principal-authored activity on a thread, including human input, agent
work, and system work. Each event is wrapped with a server-assigned seq
and createdAt when it is appended:
type BubbleSequencedEvent = BubbleEvent & {
seq: number; // monotonically increasing within the thread, starts at 1
createdAt: string; // RFC 3339
};Event shapes and the append/subscribe semantics live in Events.
Principal
A principal is the global identity that authored an event or holds a role.
There are three kinds — user, bot, and system:
interface Principal {
principalId: string;
kind: 'user' | 'bot' | 'system';
displayName?: string;
email?: string;
avatarUrl?: string;
}Principals authenticate; participants are the per-thread projection of principals that hold a write-bearing role on a thread. The full picture (authentication, registration, local bot tokens, the participant projection) lives in Principals.
What Bubble Provides
The package ships a set of cooperating pieces:
- A store contract (
BubbleStore) for the durable append/subscribe queue, principal profiles, local bot-token metadata, grants, and participant projections. - A default in-memory store (
InMemoryBubbleStore) for tests and local development. - HTTP and WebSocket transports for request/response and live delivery.
- Pluggable authentication with ordered dispatch across local bot tokens, Auth0/JWKS JWTs, master-key delegation, or custom authenticators.
- A capability-driven authorization policy built on a small fixed role set.
- A launcher (
launchBubbleServer) that wires all of the above into a Fastify instance from a single config object.
Where to Go Next
The remaining docs are arranged so that each one only depends on the ones before it. Read them in order on a first pass:
- Launching a Server — get a Bubble server running with the minimum config or the bundled dev config.
- Thread Model — the
BubbleThreadshape and how the store creates and inspects threads. - Events — every event shape, sequencing rules, and how subscribers replay backlog and receive live frames.
- Principals — the actor identity behind every
request: kinds, the
mealias, and bot-managed local tokens. - Authentication — how a bearer token becomes a known principal, the dispatcher, and every built-in driver.
- Authorization — targets, roles, capabilities, grants, the policy decision rules, and the participant projection.
- Bootstrapping — how an empty store goes from cold start to a fully wired system.
- HTTP Protocol — the REST surface.
- WebSocket Protocol — the live frame protocol.