INTERFACE
War Room
Every view, every control, every transport. The browser UI and the macOS desktop shell share one backend.
The views
Ten rooms in one War Room. Each view names its controls and exactly what they do. Nothing here hides a second backend: the browser tab and the desktop shell are two windows into the same services.
Deliberate
Streams a multi-seat session over /ws/deliberate.
Between rounds, when the server reports awaiting_input, the operator can send an intervention into the proceeding. The stream speaks in typed events, so the UI always knows which act it is in:
Direct Fire
One seat, one prompt.
A single-seat focused prompt for when you want one mind on the question, not the whole council.
History
The record of proceedings.
Saved sessions, their synthesis, their lineage, and their exports. What the council said stays findable.
Outbox
Reads signed Gateway directives.
This is where signed directives surface. An empty Outbox means there is no signed directive from the configured Gateway. It is not an error, it is a quiet gauntlet.
Watch
Sentinels, fires, and the watch plane.
Shows registered Sentinels, their fires, and watch-plane status. It stays readable while action production is disabled, because observing is not acting.
Discover
Scans exact transports, nothing more.
Three probes: non-empty API-key environment variables (names only, never values, no billable call), supported local CLI binaries, and reachable local runtimes. Unavailable rows stay visible for setup guidance but are disabled in selectors. Rescan refreshes the browser-cached result. There is no background polling.
Cabinets
Reads and edits local cabinet YAML.
The server is the YAML-validity authority, and it refuses to overwrite built-ins. Cabinet keys must match ^[a-z0-9][a-z0-9_-]{0,63}$.
Drift
Compares normal versus blind reruns.
Same question, run with and without context, so you can see what the context actually bought. Notifications are delivered via COUNCIL_WEBHOOK_* environment variables.
Librarian
An optional tab, never a dependency.
Proxies a separately configured local Librarian service. If that service is offline, Council and Gateway carry on untouched. Memory is a guest here, not a load-bearing wall.
Settings
The bases and the token.
API base, WS base, Gateway base, Librarian base, auth token, and Council root, all stored in local storage. Prefer loopback: a non-loopback endpoint can leak the token.
The transport matrix
A seat is bound to exactly one transport, and that binding is never silently switched. These are the built-in transport IDs and what each one actually talks to.
grok CLI.XAI_API_KEY.ANTHROPIC_API_KEY.OPENAI_API_KEY.agy CLI.VERTEX_PROJECT, VERTEX_LOCATION set to global, and VERTEX_GEMINI_MODEL.NVIDIA_API_KEY.NOUS_API_KEY.DEEPSEEK_API_KEY, or a configured NIM or Nous model.Seat ID rules
- One seat ID equals one transport. The binding is never silently switched.
- Legacy IDs stay readable:
grok,grok_cli,hermes_cli,claude,gpt,gemini,agy_cli. - Custom slugs via
~/.config/council/providers.tomlcannot redefine reserved built-in IDs. - Gateway adapters exist only for
grok_api,claude_api,claude_code,openai_api,codex_cli,gemini_vertex,gemini_cli, andnvidia/nim. Everything else is Direct-only.
The REST surface
The whole spoken surface of the Council backend, plus the one WebSocket. Authentication is a bearer token when COUNCIL_AUTH_TOKEN is set; the WebSocket carries that token via a negotiated subprotocol, and Gateway may require X-Gateway-Auth.
Real receipts
Not mockups. These frames come from an actual proceeding on the actual UI.
Persistence caps
Storage has hard edges, and the edges are numbers. Chat patches use optimistic concurrency via If-Match, so two writers cannot silently trample each other.
Fine print, read before trusting
- A detected CLI binary is not proof its login is still valid. The first real seat call is.
- Discovery and routing YAML never prove model entitlement.
- The War Room blocks a Governed start when the cabinet references a Direct-only transport.
COUNCIL_DEV_NO_AUTH=1must never run on a network-accessible service.- Do not delete or rewrite historical sessions without a migration plan. New fields need serde defaults.