Saphan StudioDocs
Getting started

Watching the fleet

Every surface is a projection of one record - and the fleet health runbook.

All views are projections of the one record; none of them holds state of its own.

SurfaceWhat it gives you
saphan fleet showThe resolved fleet: one row per stream — state, last gate, executor liveness, what is pending — plus the machine roster and the one current notification.
saphan fleet nextPer stream: everything it still owes and the ready command for each legal next act.
saphan fleet healthTerminal run status counts over a lookback window. The headline counts work only; probe runs and historical rows without a recorded purpose are excluded and shown separately.
saphan wave showBranch → base → gate → merge across the wave: what is mergeable, what is blocked, what waits on you.
saphan board exportThe persisted record rendered as an artifact — delivery report (Markdown), flat data lanes (CSV), a paginated document (PDF), a styled report (HTML). This is the export you hand to someone who was not in the room.
The consoleThe web console at /console, served by saphan-gateway — the fleet in a browser, behind a sign-in, updating by itself as the record changes. The console.
The MCP serverThe same projections over the Model Context Protocol, so any MCP client — including an AI assistant — can read your fleet's state and answer questions from the record. Read-only without exception; documented fully in the MCP server.
The VS Code extensionThe fleet as a tree in your editor, with paste-ready gate acts — The VS Code extension.
The daemon (saphan-server)The background process that runs the fleet supervisor — it meters running sessions, watches owner-declared standing conditions (zero rules = zero dispatch, always), and delivers owner directives to running work through an insert-only mailbox — beside the projection service that serves the console and the MCP surface.

Fleet health runbook

  1. Run saphan fleet health --workspace <canonical workspace root> --window 2h. Increase --window when investigating a longer incident; the window is a duration ending now.
  2. Read work failures as the health headline. It includes terminal failures from real work and excludes runs whose recorded purpose is probe.
  3. Read the status table before diagnosing. refused, child-failed, permission-blocked, lane-exhausted, auth-failed, error, and vendor-error name different failure classes and remain separate rows.
  4. Check both excluded columns. PROBE(excluded) proves the instrument traffic was removed from the headline. UNCLASSIFIED(excluded) names historical rows written before purpose existed; do not silently add them to work or probes.
  5. Use --json for automation. The payload carries the same three populations plus an exclusion_notice; a consumer that drops that notice presents a filtered number as an unfiltered one.

The command is read-only and runs no probe. A zero probe count means no recorded probe failure occurred in that window; it does not claim that a probe was executed.

The console, concretely

The console is served by saphan-gateway on a loopback port; open it at the localhost address the product prints. It reads the record and is told when the record changes, so a screen is redrawn within a couple of seconds of a change without a reload; the header says Live while that holds and Paused — reconnecting while it does not. Every screen is behind a sign-in. (The previous console, served by the projection service that saphan-server runs, listens on localhost:7654.) The screens, their addresses, and which of them are drawn but not yet fed from the record are on Screens and routes; the small number of acts the console offers are on The console.

The design consequence worth noting: because every view is computed from the record, the answer you get from the console, the CLI, the exported report, the VS Code tree, and an AI assistant reading over MCP is the same answer. There is no privileged screen.

On this page