> ## Content Index
> Fetch the complete content index at: https://devinside.cloud/llms.txt
> Use this file to discover other available public pages before exploring further.

# Agent Spending Authority: Reservations, Approval Scope and Uncertain Charges
- URL: https://devinside.cloud/agent-spending-authority-reservations-approval-scope-and-uncertain-charges/
- Published: 2025-08-28T12:45:00.000Z
- Updated: 2026-11-12T17:08:24.000Z
- Description: A local SQLite reservation ledger shows why approval, shared task allowance and an uncertain receiver outcome require separate, testable state transitions.
- Author: Marcin Borecki
- Tags: Engineering, Performance & Runtime, #ai13, #devinside-review

START WITH THE MECHANISM

Interactive companion and laboratory update: 12 November 2026\. The editorial date places the topic on the timeline; this current explanation and its measured evidence retain their actual preparation and execution dates.

THE FULL INVESTIGATION

## Agent Spending Authority: Reservations, Approval Scope and Uncertain Charges

Editorial context: 28 August 2025 · Prepared and updated: 12 November 2026

Dates and technology context

This is a retrospective editorial timeline. Topic context: 28 August 2025\. First publicly available: 12 November 2026\. Current text, visuals and laboratory revisions were prepared on 12 November 2026.

SQLite10.0.0/runtime10.0.15, durable receiver and actual reservation checks require12Nov2026 labels. The100/60 race remains a synthetic example.

Two agent tools each ask to use sixty units from a task allowance of one hundred. Each checks that sixty is available. Each starts work. The final total is one hundred and twenty, even though both local checks appeared reasonable.

The failure is not that the agent misunderstood arithmetic. The application separated checking authority from reserving it. Between those actions, another caller could make the same decision against the same apparent capacity.

There is a second, less obvious problem. A tool starts an approved operation and loses the response. The application does not know whether the operation took effect. If it releases the reservation immediately, another tool may spend capacity that was already consumed. If it blindly retries without a stable operation identity, it may create another effect.

These are ordinary concurrency and distributed-state problems, made easier to overlook when the front of the system is a fluent agent. A prompt asking the model to stay within a limit cannot make two database updates atomic. A confident explanation cannot establish that an unacknowledged action failed.

This article builds a small reservation service using C# and two local SQLite databases. All quantities are synthetic accounting units under the code `SYN`. The task allowance is a field in a deliberately invented application domain, not a reading of an account budget, balance, quota or billing system. There are no real payments, purchases, wallets or model calls.

The code compiled and passed 33 checks on .NET 10.0.15 using SDK 10.0.400\. The fixture includes concurrent reservation requests, approval replay, expiry, resource changes, an independently committed simulated effect, and reconciliation after reopening the local ledger. The measurements concern serial SQLite reservation operations only. They do not establish payment-system safety, regulatory compliance or the quality of agent decisions.

## Separate the quote, approval and task allowance

A quote describes one proposed action. In this fixture it identifies a task, a resource and its version, an amount, a currency-like unit code and an expiry instant. The expiry uses a manually controlled logical clock so tests can reach the boundary without sleeping.

An approval binds a trusted actor to the exact quote digest. It is single-use for starting an operation. Repeating the same operation is allowed to retrieve its existing state; using the same approval to start a different operation is not.

The task allowance is a different object. It says how much total responsibility the task may take on across all its operations. A quote for sixty units can be individually valid while the task has only forty units available because another operation already holds a reservation.

The reference grant begins with one task owned by actor `alice`, resource `resource` at version one, and capacity one hundred. Those are fixture values, not product recommendations. An actual application would derive the actor from its authentication boundary and define who can issue or change the grant.

The public-looking `Actor` record in the example is not authentication. It represents context already established by trusted application code. The command-line tests construct both authorized and unauthorized contexts to exercise the policy. Exposing that constructor as a user-controlled HTTP argument would defeat the purpose of the design.

This separation gives each rejection a meaning. The actor can lack access to the resource. The quote can be stale or expired. The approval can refer to different content or already belong to another operation. The task can lack remaining capacity. Combining all of these into one model-generated instruction would make the actual enforcement boundary difficult to inspect.

## Make the approved content immutable and identifiable

01 / See the idea

### An approval names one immutable proposal

![Amount, unit, resource version and expiry feed a versioned quote digest that the approval and operation both reference.](https://devinside.cloud/content/images/2026/11/devinside/AI13-v1.svg)

[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI13-v1.svg)

Changing the amount or target version creates different approved content. The hash identifies that content; the trusted actor and database policy still supply the authority.

Interpretation and evidence
- Bind approval to exact content.
- Hashing is not authentication.
- A changed quote needs a new approval.
synthetic tested invariant; not real payment

The quote is a C# record, but a record alone does not make stored data immutable. The SQLite schema keeps quotes in a dedicated table and installs a trigger rejecting ordinary updates. The service inserts quotes and provides no update method.

The digest includes every field that affects this fixture's action. A versioned binary encoding avoids depending on the whitespace or property ordering of an arbitrary JSON representation:

```csharp
public sealed record Quote(
    string Id, string TaskId, string Resource,
    int ResourceVersion, long Amount, string Currency, long Expires)
{
    public string Digest()
    {
        using var bytes = new MemoryStream();
        using (var writer = new BinaryWriter(bytes, Encoding.UTF8, true))
        {
            writer.Write("authority-quote-v1");
            writer.Write(Id);
            writer.Write(TaskId);
            writer.Write(Resource);
            writer.Write(ResourceVersion);
            writer.Write(Amount);
            writer.Write(Currency);
            writer.Write(Expires);
        }
        return Convert.ToHexString(SHA256.HashData(bytes.ToArray()));
    }
}

```

The fixed field order, explicit primitive types and encoding version are part of the format. A future implementation in another language would have to reproduce those details or use a separately specified canonical representation. Simply saying that both sides hash the same object is not enough.

SHA-256 supplies a digest of bytes. It does not supply the actor's identity, authenticate a database administrator, prove that a price is fair or show that the quote was approved. Those properties come from other controls. [SHA256.HashData documentation](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.sha256.hashdata?view=net-10.0&ref=devinside.cloud).

At load time, the service recalculates the digest and compares it with the stored value. Approval and operation rows also retain that digest. The test suite checks that changing the amount, unit code or resource version changes the digest, and that an ordinary SQL update to the quote table is rejected.

The protection remains bounded. A privileged operator who can replace the database or remove its trigger is outside this fixture's threat model. There is no external signature or tamper-evident archive. The goal is an application contract that prevents accidental or model-proposed mutation from silently reusing an approval, not a claim of cryptographic immunity to all administrators.

## Reserve inside the transaction that checks availability

02 / Watch the mechanism

### Two checks must become one atomic decision

![Two sixty-unit requests compete for a hundred-unit synthetic allowance; serialized reservation lets one succeed and denies the other.](https://devinside.cloud/content/images/2026/11/devinside/AI13-v2.svg)

Two checks must become one atomic decisionTwo sixty-unit requests compete for a hundred-unit synthetic allowance; serialized reservation lets one succeed and denies the other.AI13 / MOTIONTwo checks must become one atomic decisionRequest A: 60 SYNRequest B: 60 SYNAtomic allowance: 100 SYNOne reserves 60Other sees 40: denySynthetic units only. No real funds or external payments.

Play animation[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI13-v2.svg)

Static view. Play to see how the mechanism unfolds.

The concurrency test starts two independent SQLite connections. The first reservation leaves forty units; the second observes that committed state and cannot reserve another sixty.

Interpretation and evidence
- Check and reserve in one transaction.
- Include held and committed amounts.
- One successful check is not a reservation.
synthetic tested invariant; not real payment

The critical operation opens a SQLite transaction before examining the shared state. It requests a non-deferred transaction, then loads the quote, checks the trusted actor, examines approval ownership and calculates the capacity already held or committed.

The decisive arithmetic is deliberately simple:

```csharp
long committedOrHeld = (long)used.ExecuteScalar()!;
if (q.Amount > grant.Capacity - committedOrHeld)
    throw new InvalidOperationException(
        "Synthetic task allowance exhausted");

```

The subtraction uses already validated positive amounts and a grant that is not decreased through the public fixture API. The SQL query includes every operation whose state is not `Released`. A `Reserved` operation counts. An `Unknown` operation counts. A `Succeeded` operation also counts because confirmed spending does not become available again merely because execution finished.

If the check succeeds, the service inserts the operation and marks the approval as used by that operation inside the same transaction. The transaction then commits. A separate preliminary check outside that transaction would not establish the invariant under concurrent callers.

The local invariant is:

```text
held = sum(amount where state is Reserved or Unknown)
committed = sum(amount where state is Succeeded)
available = capacity - held - committed

available must never become negative through the reservation API

```

Released amounts are retained as historical information but do not remain in held or committed. They are not subtracted twice. The tests compare the complete tuple of capacity, held, committed and released values with manually calculated expected values.

SQLite permits one pending writer transaction at a time, and competing operations can wait or time out. The fixture uses separate connections and a finite timeout. The transaction mechanism supplies the local serialization; the application supplies the meaning of the rows and the check performed within that boundary. [Microsoft.Data.Sqlite transactions](https://learn.microsoft.com/en-us/dotnet/standard/data/sqlite/transactions?ref=devinside.cloud).

The concurrent test starts two callers together using a gate. Each requests sixty units from the hundred-unit grant using a different quote and approval. Exactly one succeeds. The other receives the domain rejection after observing the committed reservation. A database timeout would fail this test rather than be quietly counted as the expected policy decision.

This proves the selected interleaving and local invariant in the fixture. It does not establish throughput for a large concurrent service or a distributed grant spanning several independent databases. The application should not widen that conclusion just because the word transaction appears in the implementation.

## Single-use approval and idempotent replay are compatible

Single-use does not mean that a caller is forbidden from asking what happened to an operation it already started. Networks and processes fail precisely when a caller most needs to repeat that question.

`Reserve` first checks whether the operation identity already exists. If it does, the quote identity, approval identity and digest must match. An exact replay returns the current state without creating another reservation. A replay with different content is a conflict.

For a new operation, the approval must still be unused and bound to the same quote, digest and actor. The operations table also makes the approval reference unique, so one approval cannot own two operation rows. Approval consumption and reservation creation share the transaction.

The distinction is easiest to see through an example. `operation-1` with `approval-1` may be retried to recover its state. `operation-2` with the same approval is a different proposed effect and must be denied. A new approval can authorize another operation if policy and remaining capacity allow it; the quote digest does not itself mean the action may happen only once forever.

Replays are still authorized against the trusted actor and resource relationship. Possessing an operation identifier does not grant another actor permission to inspect or continue it. The fixture does not expose the internal reconciliation method as a public anonymous endpoint.

An already-created operation can be read after the original quote expires. Expiry prevents starting new responsibility and is checked again before dispatch. It must not erase the history of responsibility already taken. Otherwise the application would lose the ability to answer what an expired operation actually did.

This pattern is about the semantics of a repeated request. It should not be advertised as exactly-once execution across arbitrary external systems. The simulated receiver has its own idempotency mechanism, which is why the second half of the design matters.

## Claim dispatch before crossing the external boundary

03 / See the idea

### Claim dispatch before asking the receiver

![A reserved operation is rechecked, marked Unknown durably, then sent to a separate receiver; stale authority releases it before dispatch.](https://devinside.cloud/content/images/2026/11/devinside/AI13-v3.svg)

[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI13-v3.svg)

Unknown is committed before crossing the simulated external boundary. A lost response therefore cannot erase the reservation or silently make its capacity available again.

Interpretation and evidence
- Recheck before dispatch claim.
- Persist uncertainty before the call.
- Release only with a known no-effect path.
synthetic tested invariant; not real payment

The service deliberately commits `Unknown` before asking the receiver to act. At that point the local ledger has durably claimed dispatch responsibility, but it has not yet established whether the receiver performed the operation.

This conservative naming may feel surprising. Why not call it Executing? Either name can be useful if its semantics are clear. Here `Unknown` means the operation must not be automatically dispatched again or have its capacity released until further evidence resolves the effect. It covers the interval around the call, including a process interruption immediately before or after the receiver commits.

The shortened control flow is:

```text
begin local transaction
    load reservation and immutable quote
    authorize trusted actor
    if already terminal or Unknown: return current state
    recheck expiry and resource version
    if invalid: record Released
    else: record Unknown
commit local transaction

if dispatch was claimed:
    call the simulated receiver using the stable operation identity
    if effect is confirmed: record Succeeded
    if definitely rejected before effect: record Released
    otherwise: retain Unknown

```

The second state change is not in the receiver's transaction. That is the gap we are studying. Keeping a local transaction open while calling another system would not magically make its commit atomic with the remote effect. It could instead hold locks through network delays.

The fixture rechecks quote expiry and resource version immediately before claiming dispatch. If either changed after reservation, the operation becomes `Released` without contacting the receiver. The approval remains consumed; a revised action needs a new authorization path rather than silently reusing the old agreement.

There is an explicit boundary here too. A resource change after dispatch has been claimed does not retroactively recall an in-flight external action. A real system needing stronger guarantees must arrange conditional execution at the receiver or another protocol binding the resource state to the effect. The local recheck narrows the interval; it does not abolish distributed uncertainty.

The example's `Actor` and grant checks are therefore necessary but not sufficient for every payment or purchasing domain. The entire exercise stays within a synthetic contract whose consequences can be inspected safely.

## Use a receiver with its own durable operation identity

The receiver is a second SQLite file with an `effects` table. It is intentionally separate from the reservation database. Its `Apply` method inserts an effect keyed by operation identity, with digest, amount and unit code stored beside it.

If the same operation arrives again with the same content, the receiver returns without inserting another effect. If the operation identity arrives with different content, it rejects the conflict. The lookup and insert occur within the receiver's own transaction.

This separation lets the laboratory reproduce an important failure without a real external service. The receiver commits its effect. The dispatch method then follows the injected `LostResponse` path and does not update the local ledger to `Succeeded`. The receiver has one effect, while the local reservation remains `Unknown` and still holds capacity.

The test reopens the local ledger through a new `Store` instance. That demonstrates persistence across connection and object lifetimes rather than relying on a variable left in memory. It is not a power-loss durability test: no machine crash or storage-controller failure is injected.

SQLite's atomic-commit design describes how a transaction is made visible as a unit and the storage assumptions on which that behavior depends. This reference uses file-backed databases with rollback journaling and full synchronous settings. Those settings do not justify claiming that two separate database files and two independent transactions form one atomic action. [SQLite atomic commit documentation](https://www.sqlite.org/atomiccommit.html?ref=devinside.cloud).

The package graph is pinned in the project and lockfile. The initial restore exposed a vulnerability warning in the older transitive SQLite native package. The fixture was changed to use `SQLitePCLRaw.bundle_e_sqlite3` 3.0.2 explicitly, then restored and tested again. The observed warning referred to the published [SQLite dependency advisory](https://github.com/advisories/GHSA-2m69-gcr7-jv3q?ref=devinside.cloud). The final native version is recorded by the measured process. This is part of documenting the actual environment rather than assuming the managed package version identifies every binary in use. [Microsoft.Data.Sqlite 10.0.0 package](https://www.nuget.org/packages/Microsoft.Data.Sqlite/10.0.0?ref=devinside.cloud), [SQLitePCLRaw bundle 3.0.2 package](https://www.nuget.org/packages/SQLitePCLRaw.bundle%5Fe%5Fsqlite3/3.0.2?ref=devinside.cloud).

## Unknown capacity must stay unavailable

04 / A concrete example

### Lost confirmation does not free the reservation

![Actual synthetic trace shows held seventy after lost response and committed seventy after reconciliation, with availability staying thirty.](https://devinside.cloud/content/images/2026/11/devinside/AI13-v4.svg)

[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI13-v4.svg)

The table is generated from the executed local trace. Reconciliation moves seventy units from held to committed without creating another receiver effect or restoring capacity.

Interpretation and evidence
- Unknown still consumes capacity.
- Reconciliation changes knowledge, not the effect count.
- Absence at one instant is not proof of no effect.
executed synthetic trace; example/trace.json

The concrete trace begins with one hundred synthetic units. A seventy-unit quote is approved. Approval alone leaves capacity available because no reservation has yet been taken. Reserving the operation moves seventy into held responsibility and leaves thirty available.

The receiver then commits the seventy-unit effect, but its response is deliberately lost. The local ledger still shows seventy held and zero confirmed committed. Its accounting is conservative: the seventy units cannot be used by another operation merely because the sender lacks confirmation.

A new forty-unit request is denied because only thirty units remain available. This is the important consequence of retaining uncertainty in the ledger. If the application released the first reservation on timeout, both operations could be allowed even though the receiver had already performed the first effect.

Reconciliation queries the receiver using the stable operation identity and checks its stored digest and amount. A matching effect changes the local operation from `Unknown` to `Succeeded`. Held responsibility falls from seventy to zero; committed responsibility rises from zero to seventy. Available capacity remains thirty. Nothing is charged again during this local state correction.

The example trace is generated by the actual program and saved as JSON. The corresponding figure reads that file. It is an executed synthetic state transition, not a fabricated example of a customer's spending or a live account balance.

There is also a deliberately unresolved path. The process can enter `Unknown` before sending anything to the receiver. A later query finds no effect. The fixture does not release capacity on that basis alone, because absence at one instant is not proof that no in-flight dispatch can still commit. Its safe default is to remain unknown.

A real integration needs a stronger resolution mechanism: a terminal rejection, a cancellation acknowledgment that closes the execution window, a receiver-side expiry contract or a carefully controlled manual decision. This reference does not invent that guarantee. Its unresolved reservation is a visible limitation, preferable to a false statement that no effect occurred.

## Expiry is not a cleanup policy for uncertain effects

Expiry answers whether authority may still be exercised at a defined boundary. It does not establish whether previously exercised authority already produced an effect.

The tests cover expiry before reservation and after reservation but before dispatch claim. Both prevent a new receiver effect. The latter releases the reserved amount because the local state machine knows dispatch was not claimed and the receiver was not called by this path.

Expiry after the operation becomes unknown has a different meaning. The system can no longer use the clock alone to infer what happened. Deleting old unknown reservations or returning their capacity to the grant would turn storage cleanup into an accidental overspending policy.

The same caution applies to approval retention. A single-use approval record is part of replay protection. Removing it while a caller can still repeat an operation can change the meaning of that repeat. A production retention design must account for operation history, receiver idempotency lifetime and reconciliation obligations together.

Our manual clock makes the tests exact at the boundary: `Now >= Expires` is expired. It does not model clock synchronization between machines or claim that the receiver independently enforces the same instant. The receiver accepts the explicit synthetic action it is given. Adding a signed, receiver-enforced deadline would be another protocol and another set of tests.

Keeping these limits visible is useful engineering. It separates the local invariant we actually enforce from a stronger end-to-end guarantee that would require cooperation elsewhere.

## Test denial by checking the absence of an effect

A rejection message is not enough to prove that policy worked. The service could create an effect and then throw while trying to update its ledger. For every denied path, the test should inspect the independently stored receiver effects as well as local state.

The suite checks an unauthorized actor, approval for a changed quote, reuse of one approval for another operation, conflicting replay content, expiry and a changed resource version. It verifies that denied pre-dispatch paths leave the receiver untouched. It also checks ordinary successful replay and receiver-side idempotency, including rejection of mismatched content under the same operation identity.

The arithmetic tests are intentionally hand-sized. Capacity one hundred with one sixty-unit reservation yields forty available. A seventy-unit unknown effect remains held. Reconciliation moves the same amount between categories. A definite pre-effect rejection creates released history while returning capacity. These expectations are calculated independently of the SQL aggregate.

The concurrency test uses two independent connections released from a synchronization gate. It verifies one successful sixty-unit reservation and a final held total of sixty. It does not create thousands of competing operations to make a dramatic chart; the point is to expose the check-and-reserve race under a bounded, reproducible condition.

The suite's 33 passing checks establish these declared behaviors. They do not audit authentication, prove tamper resistance against privileged administrators or test a real external payment provider. The command-line `Reconcile` method is treated as a trusted internal operation. A public service would need its own authorization, audit and rate-control boundary around that method.

## Measure the reservation boundary without pretending it is AI performance

05 / See the idea

### New reservation and exact replay do different work

![Measured local reservation latency contrasts a new committed reservation with an exact duplicate replay; values come from all seven samples.](https://devinside.cloud/content/images/2026/11/devinside/AI13-v5.svg)

[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI13-v5.svg)

A new reservation writes the operation and consumes the approval, while a duplicate returns existing state. The measurement includes connection and SQLite transaction work; it is not model or payment latency.

Interpretation and evidence
- Compare different responsibilities honestly.
- Keep all sample ranges.
- Do not turn local SQLite time into service capacity.
measured; benchmark-results.json

The benchmark has two paths. New reservations perform policy checks, create operation rows and consume approvals. Duplicate replays read existing matching operations and return their state without creating another reservation. Both paths open their own SQLite connection per operation with pooling disabled.

Each sample performs thirty-two serial operations against a fresh fixture prepared outside the timed interval. The new-reservation path writes thirty-two one-unit reservations into a thirty-two-unit grant. The replay path begins with those reservations already present and repeats their exact identities. Both must finish with the same held total, and that total is checked after the timed loop.

Seven measured samples follow one warm-up sample per path. Fixture provisioning, quote creation and approval creation are excluded. The measured new path includes connection open, transaction acquisition, policy, insertion and commit. Managed allocation is captured on the current synchronous thread; native SQLite memory and retained heap are not included.

This is a small durability-boundary experiment on a shared development machine. Storage caching, filesystem behavior and connection setup contribute to its time. It is not a concurrent capacity test, a hosted database benchmark, a payment-network latency estimate or a measurement of a language model deciding which tool to call.

The exclusive measurement run completed on 12 November 2026 at 13:54 UTC with exit code zero. The process reported .NET 10.0.15 and SQLite 3.50.4 on X64 Windows build 20348\. The host exposed 64 logical processors, but this benchmark issued its reservation operations serially.

Both measured paths are included below. Times are medians and observed sample ranges in milliseconds per reservation call. Allocation is managed bytes per call on the current thread; it excludes native SQLite memory and is not a retained-memory measurement.

| Path              | Median ms/call | Observed ms range | Allocated bytes/call range |
| ----------------- | -------------- | ----------------- | -------------------------- |
| new-reservations  | 1.599          | 1.569–1.724       | 21,808–22,192              |
| duplicate-replays | 0.292          | 0.286–0.335       | 16,240–16,448              |

The new-reservation path performs more work: it checks the available allowance, writes the operation, marks the approval used and commits those changes. The exact-replay path checks the existing identity and returns its stored state. Its lower observed time is not an optimization that can replace a new reservation; it is the cost of a different responsibility.

Every measured batch ended with capacity 32, held 32, committed zero and released zero. The replay batches began with those same 32 reservations already present. Their unchanged total confirms that replay did not consume additional allowance. The benchmark then closed its connections and removed the uniquely owned fixture files.

The allocation ranges are retained rather than collapsed to one attractive value. This short run does not isolate why all samples did not report an identical allocation total. It also does not isolate connection-opening cost from SQL execution or storage flush cost. A dedicated profiling experiment would be needed before attributing the observed timing to one internal mechanism.

The setup requests DELETE journaling and FULL synchronous mode. Per-operation connections use the normal full-synchronous default and have pooling disabled. These details matter: comparing this fixture with a pooled in-memory database would answer a different question about durability and setup work. Neither result could be advertised as payment-network latency or expected throughput for a distributed production service.

The honest conclusion is limited but useful. This implementation enforces the tested reservation invariant with a visible local cost, and exact replays recover state without another allocation of authority. The run did not measure model reasoning, simultaneous production traffic, storage power-loss behavior or real financial operations. Its purpose is to make the policy-and-persistence boundary concrete enough to inspect and improve without weakening the invariant.

## Keep the invariant when the integration becomes larger

Several natural extensions would require deliberate changes. Partial charging needs a rule for settling less than the reservation and, if allowed, requesting additional authority before settling more. Multiple currencies need explicit conversion and rounding policy; this fixture accepts only `SYN`. Shared grants across tasks require a different scope for the atomic check.

Retention and recovery also become more demanding with a real receiver. How long does it remember an idempotency key? Can it confirm a permanent no-effect outcome? Can the amount change between quote and execution? What happens if its response says success but the returned digest or amount differs? Those are integration contracts, not details to let the agent infer.

The reference deliberately refuses to solve uncertainty by guessing. Unknown operations continue to consume capacity. Exact replays recover state without consuming another approval. Different operations require their own approval. Expired or stale quotes cannot create a new dispatch claim. Those rules remain useful even if the eventual storage or transport changes.

The code can be reproduced with the pinned SDK and package lockfile. The test and example commands create isolated local files and remove their scratch databases after closing connections. The benchmark belongs in an exclusive measurement window:

```powershell
dotnet run -c Release -- test <owned-work-directory>
dotnet run -c Release --no-build -- example ../example
dotnet run -c Release --no-build -- bench ../benchmark-results.json <owned-work-directory>

```

No real account or payment endpoint is needed to learn the central lesson. A spending limit is meaningful only if taking responsibility for an operation changes the shared state atomically. An approval is meaningful only if it names the action actually executed. And a timeout is meaningful only if the ledger preserves what remains unknown after the caller stops waiting.

An agent can propose the next action. The application must still be able to explain why the action was permitted, what capacity it reserved, what the receiver confirms and which responsibility remains unresolved. That explanation is the foundation of controlled autonomy, long before a real unit of money enters the system.

## Source code and execution evidence

[Download the complete lab, source record and raw execution results](https://devinside.cloud/content/files/2026/11/AI13-lab.zip). This package supports the specific execution claims in this article. It is not a production certification.