Resources · Budgets and reservations

Budgets, reserved before spent

A budget checked only at the moment of purchase is a budget with a race condition in it.

Why commit-time checks fail

Enforce a cap only when money moves and two concurrent actions can each pass the check and jointly exceed the cap. Nothing about the agent is at fault; the accounting is. A looping agent makes this failure routine rather than rare.

SproutPad uses two-phase accounting instead, so headroom is consumed at the moment an action is allowed, not at the moment it is paid for.

The three phases

Reserve
Pricing an action the policy gate allows places a reservation for the full amount, with a short TTL measured in minutes.
Commit
Executing converts the reservation into committed spend. The committed amount cannot exceed the reserved amount without re-evaluation.
Release
Expiry, cancellation, or failure returns the reservation to headroom. Compensation paths always release.

When an action waits on a human, the reservation is taken (or renewed) after approval, so a multi-hour gate cannot hold headroom hostage or expire mid-flight.

Two words that are not synonyms

Estimate
Anonymous, side-effect free, and explicitly not held. It creates no policy verdict and no reservation. This is what an agent can call before anyone has an account.
Quote
Project-bound and policy-aware. An allowed quote enters the reservation lifecycle above.

These names are load-bearing. A conforming implementation must not use them interchangeably, because the difference is exactly whether headroom has been consumed.

One number, computed one way

headroominvariant
budgetRemainingUsd = cap − committed − active reservations

That is the number policy evaluates and the number reported in budgetRemainingUsd on every mutating response. There is no second, friendlier figure shown anywhere.

Worked example: a $25.00 monthly cap, a launch priced at $20.00 maximum, actual cost $19.00. During execution headroom reads $5.00. On commit, $19.00 becomes committed and $1.00 returns — headroom reads $6.00.

When the database is not enough

Everything above still asks you to trust SproutPad's own accounting. An optional profile removes that: the human principal signs an open AP2 payment mandate — an SD-JWT verifiable credential whose budget constraint is the ceiling — and SproutPad registers it against a project through a human-gated, ledgered step.

With the mode on, both the local cap and the mandate are enforced at reserve time. A mandate can only make enforcement stricter, never looser.

Optional profile. This is an opt-in binding, not the default posture. See §9 of the specification for the exact rule.

Keep reading