AI spend circuit breaker
An AI spend circuit breaker trips open when a tenant's LLM cost crosses a hard spend cap, blocking every further inference call with a 402 until an operator resets it. Caisson's @caisson/ai-meter checks the breaker before every reserve, so a runaway agent loop stops on the next call, not after the invoice.
In code
/**
* A spend cap reached / circuit breaker open. HTTP 402 (the credit-gate status, ADR-0007) — the
* tenant has no spendable budget for this call. Metadata only: `details` carries the `scope`, never
* the spend figures, so the envelope stays redaction-safe (mirrors `InsufficientCreditsError`).
*/
export class SpendCapError extends CaissonError {
readonly code = "spend_cap_reached";
readonly httpStatus = 402;
constructor(
scope: string,
message = "Spend cap reached: circuit breaker open",
) {
super(message, { scope });
}
}
// ...
/** Throw `SpendCapError` (402) when the breaker is open — the pre-reserve gate. */
export async function assertBreakerClosed(
tx: TenantExecutor,
accountId: string,
scope: string,
): Promise<void> {
const status = await readBreaker(tx, accountId, scope);
if (status.state === "open") throw new SpendCapError(scope);
}How it holds
Checked before every call
assertBreakerClosed() runs inside reserve() before any provider call: an open breaker throws SpendCapError (402), so a tripped tenant's next call never even reaches the model.
Hard cap trips it, soft cap only warns
reserve() evaluates soft and hard spend caps after each fresh, billable reservation. Crossing the soft cap sets softExceeded as a warning only; crossing the hard cap calls tripBreaker() in the same transaction.
Fail-closed until an operator clears it
The breaker's state lives per (account, scope) and does not auto-heal: only resetBreaker(), an explicit operator path, closes it again, so a runaway loop can't quietly resume spending on its own.
A separate gate from content guardrails
The breaker blocks on spend alone. @caisson/guardrails' fail-closed guard runs the same call through its own moderation and PII chokepoint (ADR-0063), so a call can be stopped for cost, content, or both, without either gate substituting for the other.