Economics, workflow design and recovery / Field essay 26

Budget agent work before dispatch, then reconcile what actually happened.

A token counter after completion cannot enforce a hard pre-dispatch exposure bound across parallel work and ambiguous provider outcomes.

Published

ARCHITECTURE
FIELD ESSAY 26 / ECONOMICS, WORKFLOW DESIGN AND RECOVERY
THE OVERVIEW FILMWatch the full argument

Budget agent work before dispatch, then reconcile what actually happened

Our allocation check returns current available funding. It deliberately reserves nothing.

That distinction is the starting point for budgeting an agent system. A caller can be authorized, a funding reference can be current, and a balance can be sufficient at the instant of observation. None of those facts means a parallel request has not claimed the same capacity before the provider call begins.

We separate that observation from atomic admission. The reservation claims both the money account and any member allowance. Dispatch then rechecks the quote, current authority and funding state before the external call. If the outcome becomes unknown, the hold remains until authoritative reconciliation can resolve it.

A token counter at completion cannot substitute for those transitions. It tells us something useful about usage after work has happened. It cannot, by itself, decide which parallel requests were allowed to create exposure before the work began.

Availability is a snapshot, not a spend permit

Our AllocationTx checks a trusted allocation reference alongside an authenticated member principal. The reference binds member identity, issuer, subject, eligibility, tenant, environment, funding evidence, account and allowance. Caller-selected allocation strings do not provision that authority.

The implementation checks explicit expiry and blocking, rejects future-dated eligibility checks, and limits the age of the authoritative eligibility observation to thirty seconds. That is a source policy window, not a measured authentication or inference latency.

It also verifies that a funding reference has an actual journal entry. A claim about an asset or an invented balance does not become collected funding merely because a request names it. The result contains available funding and eligibility; the function's own contract says it creates no money and reserves nothing.

I want that limitation visible in the API name, return type and caller contract. A cached positive eligibility response is especially dangerous if a later consumer treats it as a durable permit. The check must remain connected to the transaction that creates the key binding or inference admission.

At issuance, the key is bound to the allocation and trusted reference. At inference, the same binding must exist and match. This separates authentication, eligibility and money authority instead of assuming one successful lookup proves all three.

The implementation also exposes an integration boundary worth preserving. Its documentation explicitly rejects a legacy callback that lacks the authenticated member and trusted reference at issue time. Adding another string argument would not repair the missing authority provenance. The owning foundation interface has to provide the facts the check requires.

Reserve the scarce facts together

The admission path does the part an availability snapshot cannot do. It constructs the affected account list, includes the member allowance where configured, sorts accounts globally and updates each reservation under the caller's transaction.

The decisive balance condition is in the update itself:

UPDATE money.accounts
SET reserved = reserved + $1
WHERE tenant_id = $2
  AND environment = $3
  AND id = $4
  AND book = $5
  AND NOT blocked
  AND balance - reserved >= $1

The code checks that exactly one row changed. A separate read followed by an unconditional write would leave the scarcity decision outside the committing mutation. Here the predicate participates in the state change.

The allowance path uses the same conditional reservation idea against a different table. Those two rows represent different limits. The money account supplies funding. The allowance restricts a member's permitted use. An allowance is not additional money, and sufficient sponsor funding does not override an exhausted member cap.

The caller must roll back on any error. If the money reservation succeeds but the allowance reservation fails, committing the partial result would violate the composition. The transaction is part of the contract, not an implementation detail the caller can discard.

Global lock ordering matters too. Stacked funding sources can otherwise acquire overlapping account sets in opposite orders. Sorting gives competing operations a common acquisition order. It does not make every possible transaction deadlock impossible; all participants that touch the same resources need compatible ordering.

Make the exposure arithmetic concrete

Consider an illustrative account with ten dollars available and two simultaneous requests, each allowed to create seven dollars of exposure. These are hypothetical amounts to explain the invariant, not a production-spend measurement.

Both requests can observe ten dollars if they read before either reservation commits. That does not authorize fourteen dollars of combined exposure. Under atomic reservation, the first successful claim leaves three dollars available. The second seven-dollar claim cannot pass the same condition.

If the member allowance is only six dollars, the first seven-dollar request should fail even though the sponsor account has ten. Both limits must survive the same admission transaction.

The retained hold also changes what availability means after a timeout:

Illustrative state Balance Reserved Available
Before admission $10 $0 $10
After reserving the ceiling $10 $7 $3
Provider outcome unknown $10 $7 $3
Authoritative final cost is $5 $5 $0 $5

The timeout row does not restore the available balance to ten. The final row debits five and removes the seven-dollar reservation. That frees only the unused part of the held ceiling while recording the actual cost.

These quantities need clear names in telemetry. Balance, reserved exposure, spendable availability, member allowance and observed provider usage answer different questions. Combining them into one budget-used percentage makes recovery and customer explanations unnecessarily difficult.

A quote is a versioned authority decision

Our quote contains route, rate, adjustment, rule and decision identities, a ceiling, funding allocations and expiry. Admission obtains it through server authority in the current transaction. The client does not choose a price or assert that a funding source is eligible.

The pure quote validator checks that the funding sum exactly equals the ceiling, rejects duplicate funding accounts, requires evidence and limits the funding-source count to sixteen. It rejects invalid money representations and prevents addition beyond the supported maximum.

The overflow check happens before adding the next allocation:

if n > MaxMicros-total {
    return ErrInvalid
}

Those are useful validation properties, but the helper does not own every part of admission. Quote expiry is checked by the transaction path against the database clock. Environment admission belongs to the scope contract. A valid quote object alone is not an authorization result.

The accompanying source-bound exercise makes those distinctions explicit. It accepts a structurally valid quote whose expiry is already in the past, because the pure helper does not check time. It also demonstrates that the book helper alone does not enforce the complete environment contract. The caller must apply the owning scope and transaction checks.

I would rather document those composition limits than claim a helper guarantees more than its code does. A security boundary is the complete enforced path, including the facts and transaction that reach the helper.

Keep exact money out of floating-point transport

The money representation uses USD, scale six and an integer microunit amount carried as a string. The wire validator and the admission validator have different responsibilities. The representation permits signed values; the admission amount conversion rejects negative amounts.

That difference matters when tests exercise a type without following its consumer. “The money type accepts a negative value” does not mean a negative reservation is accepted. Conversely, checking the representation alone would be insufficient for a caller that needs nonnegative funding.

We exercise leading zeros, negative zero, decimal strings, exponent notation, explicit plus signs, wrong currency, wrong scale and values beyond the supported range. These cases are about exact interpretation at the interface, not numerical model quality.

Money precision also needs to survive pricing and settlement. A server can validate an exact amount and still produce an incorrect charge if it applies an unpinned rate version, inconsistent rounding or a different route's usage. Exact transport is necessary; it does not replace the pricing contract.

Revalidate before crossing the provider boundary

A reservation and a provider dispatch occur at different times. Authority can change between them. A funding source can be blocked, a quote can expire, a route can change or the current policy can withdraw permission.

Our dispatch transaction reloads the reserved hold, rejects inappropriate states, checks expiry and obtains the current quote again. It compares the current quote with the reserved one, checks current account state and changes the hold to dispatching with its event in the same transaction.

The gateway has a corresponding durable attempt transition. It re-evaluates current route and policy facts, compares immutable dispatch bindings and changes only an exact reserved attempt. Principal, hold, route, provider, model, versions and epoch participate in that comparison.

The external effect must occur only after the dispatch transaction commits. Holding a database transaction open across a provider call would create a different failure problem: an external effect can survive a transaction rollback. The transaction records the commitment to dispatch; it cannot roll back the supplier's world.

This gives an ambiguous commit a meaningful state. If dispatch may have committed, cleanup cannot assume the request was never sent. The gateway's pre-dispatch release is guarded by the durable reserved-state transition. A hold already in dispatching cannot be released through that path.

Preserve unknown exposure instead of manufacturing a refund

After dispatch, a timeout, stream interruption or lost reply does not establish final provider usage. The ledger has a distinct outcome_unknown state. The gateway also separates completed output from usage observations, rather than using one success bit for both.

Without a usage evidence identifier, resolution permits release only from the never-dispatched reserved state. A post-dispatch resolution requires authoritative final usage or explicit no-cost evidence. A cancellation request alone is not that evidence.

The code makes the empty-evidence boundary narrow:

if usageID == "" {
    if h.State != "reserved" {
        return ErrUnknown
    }
    u = Usage{NoCost: true}
}

This is a different problem from expiring a worker lease. A lease can determine which worker may publish. It cannot erase supplier liability that may already exist. An operational deadline should trigger reconciliation ownership or escalation, not silently transform an unknown charge into free money.

I want the recovery interface to name the operation, retained exposure, last authoritative evidence and next owner. Its deadline should bound how long the case can remain unattended. The financial state should change only when the evidence justifies that change.

The gateway also uses a bounded finalization context detached from the client request's cancellation. That lets accounting cleanup attempt its own work after a browser disconnect. It does not guarantee that cleanup succeeds. A failed finalization can leave retained exposure for recovery rather than pretending the interrupted request had no effect.

Idempotency and current authority are separate identities

The ledger's stable reservation digest excludes the mutable authority epoch. The epoch is checked independently. That prevents a harmless authority-version change from redefining the business operation while still refusing work under stale authority.

The gateway similarly separates an operation-key identity from a semantic payload digest. A repeated key with different request content is a conflict. A matching retry can return the existing state without creating another reservation or provider effect.

Those identities also need key-lifecycle rules. The gateway pins the operation-key namespace and retains versions for request-digest comparisons. Replacing the operation identity key as a routine configuration rotation could make old operations disappear from duplicate detection. Its source treats that as an explicit migration boundary.

The privacy consequence is useful too. The payload digest is keyed and includes principal and protocol facts. The durable attempt does not need to retain raw private request content merely to establish semantic retry identity. That still requires deliberate key management and retention policy; a hash is not a substitute for those decisions.

Settle only against the accepted subject

Usage resolution checks quote, route, rate and decision identities against the held subject. It obtains costs from server authority. The client cannot submit a convenient final price to release its reservation.

Each actual funding charge must fit its reserved maximum. The settlement transaction removes reserved exposure, debits actual cost, records journal effects where appropriate and stores a resolution digest. A repeat with the same resolution is idempotent; a different resolution for the terminal hold is a conflict.

The ceiling is an internal admission guarantee under the accepted quote and supplier contract. It does not make unexpected supplier overbilling physically impossible. If authoritative cost exceeds the reserved maximum, this implementation refuses ordinary settlement rather than silently normalizing the discrepancy.

That discrepancy needs its own owner and reconciliation path. A hard guarantee about external cash exposure depends on enforceable supplier limits, accepted rate semantics, bounded work and complete accounting. A local token cap or reservation table cannot promise all of those on its own.

Keep the integration state in the architecture

The source includes callable transaction-level ledger exports and separate integration requests for foundation authority, finance adapters, migrations, runtime privileges and provider evidence. Some transaction continuations are integrated in the documented source history; the complete legacy allocation callback and production composition are not established by the helper code.

That is why the article separates implemented mechanisms from the guarantee the composed service must demonstrate. I want a private transaction test for concurrent admission, rollback when the outbox fails, current-authority revocation before dispatch and repeated resolution. Then I want a controlled provider boundary test for ambiguous completion and no-cost evidence.

The retained concurrency test source launches thirty-two competing admissions against a fixture balance that permits exactly ten reservations. That is the authored test contract in the pinned source, not a new result from this content session.

The measurement I ultimately want is admitted exposure and accepted work under concurrency, with unresolved holds and reconciliation age visible. Spend dashboards remain useful, but they should explain a controlled workflow rather than try to enforce it after the provider has already accepted the work.

Explain retained exposure to the user

The user-facing status should distinguish a refused request, an in-progress request, an unknown outcome and a completed response whose body was not retained. Returning the same generic retry message for all four invites a new operation where the safe action may be a status read.

I would show available balance separately from unresolved reservations and explain which operation owns each hold. A reconciliation owner needs enough identity and evidence to resolve the operation without retaining the original private prompt or repeating the provider call. Support tooling should use that same operation boundary rather than issuing a fresh request to recreate a missing answer.

The useful metric is not simply how many holds exist. Track their amount, age, last authoritative observation and next action. A growing unknown-exposure queue can reduce admission capacity while reported completed spend looks normal. That is an operational condition worth detecting before users interpret the missing availability as a billing error or a reason to switch credentials and retry.

How this was verified

Nine immutable source snapshots cover allocation, ledger, gateway, ports and integration notes. A standalone Go exercise executes the actual pure money, quote and scope validators across 51 cases without database or provider calls. It does not establish transaction locking, production wiring, supplier billing or cash-spend results. The dollar timeline is illustrative; deployment and complete composition require their own receipts. The original 47-case exercise killed 26 of 30 independently designed non-equivalent mutations (one additional mutation is equivalent). Four isolating additions brought the exercise to 51 cases; the author replay killed 30/30 on that same set. This is targeted follow-up coverage, not a fresh independent score. Both exercises and the original receipt are retained.

CONNECTED READINGForward and back
Keep reading

The answer deserves
another experiment.

Back to the journal