How a turn runs — the assistant is a function, not a server
A Space keeps no process running. When a member posts, a turn opens the sealed room, runs the assistant with the room's tools, writes the reply, seals the room again and ends. Between turns a Space is ciphertext on disk, so an idle room costs almost nothing, and there is nothing running to read it.
This page follows one turn from the post to the reply, and then the tools, the approvals and the reads around it. The SDK does all of it for you (the SDK); this is what happens underneath.
One turn, step by step
- A member posts —
{ op: 'turn', room, mk, message }. - Proof of the key. The server checks the key against the room's stored commitment — proof that the sender is a member, and that the reply will be sealed to the room's key.
- Who wrote it. In a room that requires sign-in, the message is signed by the member's device and carries their sign-in; the turn checks both against the room's sealed allow-list and records only the verified author.
- The room opens. The sealed ledger is opened, and the new message appended.
- The assistant runs with the room's persona, model and tools.
- The result lands — the reply, any widgets and files it made, any proposals waiting for approval.
- The room is sealed again, and the key is dropped. Nothing about the turn is kept outside the sealed room.
Where it runs. In a standard room the turn runs on Witbitz's server, which holds the key for the length of the turn. In a confidential room the same turn runs inside a measured enclave the device verified first, and the key is sealed to that enclave alone (privacy tiers, the confidential tier).
When the assistant answers
Every message lands in the room. Whether the assistant replies is a per-room setting:
| Mode | Behaviour |
|---|---|
always |
Reply to every message. |
auto (default) |
Reply when the room is just you and the assistant, or the message is addressed to it. In a group, a small model decides whether a message not aimed at it wants help. |
ondemand |
Reply only when addressed by name or @-mention. |
A turn with no reply returns silent: true, so the page can drop its "thinking" indicator at once. A room made only to
observe (agentReplies: false) never replies. If the small model in auto cannot be reached, the assistant answers:
an outage must not silently mute a group.
Tools, and what they produce
A room's tools are named in its sealed config — the server cannot read the persona, the tool list or the admission policy. A room gets only what it declares: with no tools, the assistant can talk and nothing else. Your page can add its own tools to a turn (the assistant).
| Tool | What it does | Produces |
|---|---|---|
search_places · show_places · add_place |
find places, then put the chosen ones on the shared map | a places map |
search_flights · show_flights |
find real flight offers, then show the chosen ones | a flights card |
set_itinerary · add_to_itinerary · read_itinerary · edit_itinerary |
the day-by-day plan | an itinerary |
show_chart · show_diagram |
draw data, or a relationship graph | a chart / diagram |
show_photo |
an image in the reply | a sealed image |
read_file |
read a shared PDF, Word, Excel, CSV or text file — by its id, by who shared it, or by name | text |
read_url |
fetch a public page | text |
write_pdf |
make a PDF from Markdown | a file on the reply |
connection_call |
spend a service the member connected; the secret is added inside the Sentinel, and the call is proposed — an MCP tool granted to run on its own (auto) excepted (connections) |
the service's answer |
Find, then show. A search_* tool returns candidates to the assistant; a second call puts the ones it chose on the
shared view. Members see a curated set, not a raw result dump.
A widget is the room's, not one person's. A map, an itinerary or a chart is a shared document sealed in the room: every member sees the same one, edits reach everyone, and any shared view opens full-screen from the room's ⋯ menu.
Where a rule belongs. The persona says who the assistant is, and it is read at the top of every turn. A tool's
description — and each parameter's — is read at the moment the model fills that field, so a rule about a field belongs
on the field ("only if the member said one" on due). Rules moved from the persona onto the parameters are followed
more reliably. Which tools a turn offers is how a page steers the assistant; what it must never do is enforced by
approvals, below.
High-stakes tools become proposals
A tool that spends money, changes an outside system or crosses a policy line does not run in the turn. The turn records a proposal; a member approves or denies it; only an approved proposal runs, and only once. Your own tools can be declared the same way (proposals, end to end).
Reading the room
- Changes, without reading. A page asks with the last version it saw; the server compares a hash of the ciphertext. Unchanged, it answers at once and opens nothing.
- Sealed reads.
pollsealedreturns the new entries still sealed, and the device opens them with the key — the server takes no key and decrypts nothing. The SDK reads this way. The olderpollop returns server-decrypted plaintext instead, opening the room with the key the page sends. - The reply as it is written. While the model writes, the turn seals the partial reply and publishes it; every read carries it, and the page shows it growing. It is cleared the moment the finished reply lands, so it can never appear twice.
- Members who are away get a push that carries no content — only "something changed in this room". Their device wakes, reads, and shows the notification itself; the push service learns nothing.
- Gated reads. In a room that requires sign-in, every read needs an allow-listed sign-in too — the key alone does not open the history.
The sealed ledger
A room's conversation is its ledger, sealed under the room key and stored as ciphertext; there is no operator recovery key. New entries are sealed one by one as they are appended, and long ledgers are stored in segments, so a turn's work grows with what it adds, not with the room's whole history.
The operations
Every room operation is one call to POST /space, chosen by op (HTTP API):
| op | What it does |
|---|---|
create |
register a room: its key commitment and sealed config. The device makes the key; the server never sees it |
turn |
a member posts; the assistant replies, or proposes |
pollsealed · poll |
read what changed — still sealed, or opened by the server |
pending · decide |
list proposals · approve or deny one |
title · state |
the room's sealed name · a shared widget document |
blob |
sealed images and files, content-addressed and never opened by the server |
react |
an emoji on a message |
subscribe · unsubscribe |
push for members who are away |
mirror |
copy entries between a member's private assistant and the shared room — the device joins them, holding both keys |
view · fetchview |
a scoped, re-sealed slice of the room for an admitted outside agent, which never gets the room key |
import |
start a room from a public ChatGPT share link or a WhatsApp export |
policy · attest |
the room's governance and owner key · the source the running service was built from |
In your own boundary
In an on-premises deployment with AIRGAP=1, the tools that reach the internet are refused; chat, files, PDFs, charts
and diagrams keep working (deployment options).
Read next
Machine-readable source: how-a-turn-runs.md · Generated 2026-10-27T07:05:42Z · build f301388c · every doc in one fetch: llms-full.txt (HTML)