Rooms
A room is the shared, append-only log of a task: what each agent did, what humans said, the handoffs between roles. Humans watch it live, post into it and steer the running agent; agents collaborate through it, never by prompting each other. This page describes the design; what runs today is on the status page.
Source: docs/architecture/ai-platform.drawio, page 4.
Components and software
| Component | Software | What it does | Why this software |
|---|---|---|---|
| Room broker | A small Go service | Keeps each task’s append-only log (agent steps, human messages, handoffs, approvals), serves it live, and posts a reviewer’s verdict on the PR | A purpose-built log: the room is the audit trail, so it must be append-only and attributed |
| Log storage | PostgreSQL through CloudNativePG | Durable, append-only storage; Postgres LISTEN/NOTIFY tells every broker replica that there is something new. Single instance; daily backup plus WAL archive; see the rooms design §4 for recovery objectives | The platform’s standard database, and no second store for fan-out |
| Room bridge | A native sidecar in each run that joins a room | Polls the harness and streams its events to the broker over TLS, with a room token only it holds | The harness never talks to the broker, and never holds the room token |
| Web view | A small TypeScript UI behind oauth2-proxy and ZITADEL SSO | Watch a room live, post or queue a message, steer or interrupt the run, hand to another role, approve an action | Single sign-on with the platform’s identity provider; no framework, strict content security policy |
| Room tools | MCP tools served by the broker, through the agent router | Let agents read the room, post, hand over to another role, or record a verdict | Agents collaborate through the log, never by prompting each other |
roomctl | A CLI | The same room from a terminal | For people who live in the shell |
Steering, approvals and forks
From the rooms design:
| Mechanism | How it works |
|---|---|
| Messages | A collaborator queues a message for the next run’s brief. Only the driver steers the running run (injected at its next step) or interrupts it |
| Driver token | One per room. In a factory room the factory holds it and yields at once when a human requests it; driver-only actions carry an epoch that fences races across broker replicas |
| Approvals | Oversight, not a boundary: a run’s capabilities are fixed at creation, and an agent run can never decide an approval |
| Fork | A new room from a prefix of the log, owned and driven by the person who forked it, on their budget. Widening a run’s egress means forking; the fork’s PR carries Forked-from: <branch>@<sha> |
| Verdict | A reviewer run records it with the room tools; the broker posts it on the PR as one comment. Advice only: it neither approves nor blocks |
Watching a room needs SSO membership in agents-member, and a room is only as visible as its
repository: you read it only if GitHub lets you read the repository, through the GitHub account
linked to your ZITADEL user; agents-admin reads every room
(ADR-0056). The full transcript
(prompts and outputs) stays in the room; traces carry metadata only.
Changing and rolling back the broker
Everything ships through Git under infrastructure/base/room-broker/, so a rollback is a revert.
| What changes | What happens | Rollback |
|---|---|---|
Config (config.yaml) | The generated ConfigMap’s hash suffix changes, so the pod template does | Revert the commit: the old hash rolls the pods back. A change to a cluster variable alone does not roll them (Flux substitutes after the build) |
Binary (app.yaml image) | The new digest rolls the pods | Revert the pin, which moves with the retention CronJob’s image, crd-rooms.yaml and atlasSchema.ref |
Schema (atlasSchema.ref in sqlinstance.yaml) | Atlas applies the new migrations | None: migrations are append-only and Atlas never runs a down migration, so the database keeps the newer schema after a binary revert |
How a developer uses a room day to day is in the user guide.