Tvijo wiki
Catalog

Topics

When you cannot tell what a model call cost: freeze, then reconcile

Sometimes a model call times out and you do not know whether the provider charged you. Never record that as zero. Mark it uncertain, stop new paid calls, and let a named person reconcile it with the provider's statement. Refusals before generation are the exception.

🎯 For A developer or operator who pays for model calls through an API

πŸ“š You will learn
  • Why an unknown cost must never be stored as zero
  • How a freeze and a named reconciliation work
  • Which failures cost nothing and which stay uncertain

❓ The problem

You send a request. The connection drops after thirty seconds. Was it charged? The provider might have generated the whole answer, part of it, or nothing. If your ledger stores zero, your books are wrong in the cheerful direction. If it stores a guess, they are wrong in an unknown direction.

🧊 The rule: unknown is unknown

In our metered transport every attempt writes a row, including retries and fallbacks. The cost column can hold a number or the explicit state "uncertain". An uncertain row freezes new paid calls on that lane. The freeze is lifted by one action only: a named person reconciles the row against the provider's activity page and records the real amount and a reason. The agent that hit the problem cannot lift the freeze. An empty name is rejected on purpose.

Three kinds of failure get different treatment.

  • Refused before generation. A client error such as a rejected request or "no funds on the account" means the provider produced nothing. The cost is zero and the row is not uncertain. Recording it as uncertain once stopped a pipeline for a day for no reason.
  • Timeout or server error. The provider may have done the work. The row stays uncertain.
  • Charge above the reservation. Before each task the transport reserves a maximum. If the provider reports a larger charge, the lane freezes until a person acknowledges the difference.

πŸ“‹ Where we are today

On 3 November 2026, 22:06 UTC the ledger held 10,150 rows. Open uncertain rows with no reconciliation: 0. Reconciliations recorded in total: 2. Over-reservation acknowledgements: 1.

The acknowledgement is a good example. A provider charged $0.08773 against a reservation of $0.08566, an overrun of $0.00207, about a fifth of a cent. The lane stayed frozen until the account was checked and a person recorded the decision. It is a tiny amount, and the point is the procedure, because the same rule applies when the amount is large.

πŸ› οΈ Practice: add the freeze to your own setup

  1. Store cost as a number or as an explicit unknown. Never default to zero.
  2. Write one row per attempt, including every retry and fallback, with the provider's request id when you have it.
  3. Classify failures: refused before generation (zero), timeout or server error (unknown), success (provider-reported cost).
  4. Before a task starts, reserve its maximum cost. Refuse the task when the daily cap would be passed.
  5. When a row is unknown, block new paid calls and send a message to the person who owns the account.
  6. Write a short reconciliation command that needs a row id, the actual amount, a reason and a non-empty name. Log it.

βœ… Check yourself

  • Simulate a timeout. The row is uncertain and the next paid call is refused with a clear reason.
  • Simulate a rejected request. The row costs zero and nothing is frozen.
  • Try to reconcile with an empty name. It fails.
  • After a reconciliation, paid calls resume and the record shows who did it and why.

🚧 When this does NOT work

  • Providers with no activity page. If you cannot see what was charged, you cannot reconcile. Treat every uncertain row as spent at its reservation until the invoice arrives.
  • Delayed billing. Some charges appear a day later. Reconcile after the statement is final, not on the first look.
  • Shared accounts. Charges from other users on the same key look like overruns. Use separate keys per lane.
  • Freezes that block too much. A freeze on the whole system for a one-cent uncertainty is costly. Scope it to the lane that has the unknown.
  • Human bottleneck. If only one person can reconcile, the lane waits for them. Name a deputy.

πŸ“Š Evidence

What we measured Open uncertain rows, reconciliations and acknowledgements in our metered transport ledger
When 3 November 2026, 22:06 UTC
Artifact The transport ledger database in our private deployment: 10,150 rows, 0 open uncertain, 2 reconciliations, 1 acknowledgement
Limit One ledger, one team. The example amounts are small and are shown for the procedure

➑️ Next

See how a daily cap and session ids fit with this in A daily AI budget that fails closed, and what a record of a run proves in Agent task receipts.

Sources

πŸ”— Article connections

Open the full knowledge graph β†—

Published article links. Select a node to open its article at the heading.

100%
β†’ Linked articles← Linked fromβ‹― Same topic
Article links Β· keyboard / text view

πŸ’¬ Comments

Comments are public and moderated. Do not post personal data.
  • No comments yet. Be the first!

Next steps