Saphan StudioDocs
Cost management

Worked examples

The commands, in the order the money actually moves: price it, check capacity, compose it, then read what it cost — and two refusals that cost nothing.

Every example below uses invoice-export as the name of the piece of work, and build-2 as the name of a machine. Substitute your own.

1. Price it, check capacity, then compose the dispatch

The budget block in the order is the decision, and the composer holds you to it:

## Budget
- model: sonnet · quote: $5.00 · cap-usd: 10.00 (per run; cap = 2x quote)

Capacity before commitment — a report, and it cannot become a dispatch:

saphan fleet headroom --model sonnet --estimate-usd 5.00

Then compose the run. The prediction is a required argument, and the ceiling is derived from it rather than passed separately:

saphan dispatch command --stream invoice-export --machine build-2 \
  --model sonnet --cost-estimate-usd 5.00

2. The composer refusing a budget that disagrees with itself

Declare a ceiling in the order that is not twice the prediction, and composition stops with both numbers on the table:

the order declares a cap of 7.00 but the derived budget is 10.00
(2x the declared quote of 5.00) — a composed command never silently
picks one over the other
  -> reconcile the order's cap with the estimate passed on the command line,
     or pass the estimate the order's own quote actually implies

Nothing runs and nothing is billed. ⇒ A disagreement between two people's numbers is resolved by a person, rather than by whichever code path read its argument last.

3. The routing gate earning its keep

saphan route channel-lint --request-client

The step is routed to the deterministic tier, so the request for a model-capable context is refused — with its own exit code — and the refusal is booked in the ledger at zero. The cheapest rows in these books are the model calls that never happened.

4. Declaring who pays for a seat

saphan machine seat --identity finance-lane --machine build-2 --slot 1 \
  --backend codex --billing-class subscription --added-by platform-admin

--billing-class takes exactly subscription, metered, or local-energy. ⛔ Anything else refuses with nothing written, and an omitted flag reads back as unknown — which anything gating spend treats as metered until somebody says otherwise.

Declaring the class on the seat does not by itself make that seat's runs book a real zero. That takes a matching row in the pricing registry, written by hand. The seat says who pays; the registry says what the rate is, or that there is no rate at all.

5. Read what one piece of work cost

saphan cost invoice-export

Per run: the actual in one normalised currency column, the prediction where one was recorded, and the difference where both are known — plus totals across continuations, and any unpriceable runs counted and named rather than counted as zero.

Because a stream closes into exactly one observed merge, this rollup is also the cost of the merged change: one piece of work, one merge, one number.

6. Read what the fleet cost

saphan ledger show
saphan ledger export > fleet.jsonl
saphan board export --format csv --csv-lane streams

The first is session and workspace totals — tokens in, out and cached, currency, calls, refusals. The second is every row and every dimension, one object per line, for your own reporting tool. The third carries the cost lanes into a report you can hand to somebody outside the team.

7. The register that keeps predictions honest

One row per prediction-and-actual pair, appended the day it happens, newest first, and ⛔ no row without a reference:

| date | work | act | actor and model | predicted | actual | difference, with cause | pass class | reference |

The pass class is one of first-pass, rework, refusal, manual-seam. The weekly question is not "how much did we spend" — that number is on the dashboard already — but "what share of it was rework and manual seams, and is that share going down."

8. What a saved dollar looks like in the record

Three rows, all of which most cost tools would simply not have:

The rowWhat it tells you
A refusalA malformed dispatch, refused a minute before it would have spawned, booked at zero with its reason
A named failure statusA run a provider limit ended — distinct from a vendor error, distinct from a ceiling hit, and never blended into the cost of the work it failed to deliver
A deterministic actBooked at zero, so the share of the work that needed no model at all is visible instead of merely absent

⇒ The books distinguish money spent on work, money spent on friction, and money the guardrails kept in your pocket. Only the first of those three appears on a vendor invoice.

Next