Give Every Agent Commitment a Receipt

An agent can complete a task and still leave its operator unable to answer a basic question: what exactly happened? A small, structured receipt after each consequential step turns an opaque success message into something a person can verify.

This article shows how to add commitment receipts to an agent workflow: define the effect, capture evidence, record the result, and expose the next safe action without creating ambient noise.

Start by classifying the effect

Before an agent performs a step, describe what the step can change. A useful classification is deliberately simple:

  • Read: retrieves information without changing an external system.
  • Prepare: transforms information into a draft, comparison, or proposed command.
  • Commit: sends, publishes, books, purchases, or otherwise changes an external state.
  • Recover: compensates for or reports a failed or partial commit.

The classification should travel with the task, not live only in documentation. For example:

``json { "action": "book_hotel", "effect": "commit", "approval_required": true, "inputs": { "dates": "2026-09-10/2026-09-13", "guests": 2, "room_type": "standard" } } ``

This gives the runtime and the operator the same vocabulary. A research result can proceed automatically; a booking can stop at a review boundary. The distinction is especially important when one user request contains both kinds of work.

Do not infer authority from tone. “Please handle my trip” is a goal, not a durable authorization to spend money or transmit traveler data. The commit record should state what was approved and for which exact action.

Capture evidence before you need to explain it

A receipt is useful only if it contains the facts needed to reconstruct the decision. Capture evidence at the point of action, while the relevant context is available.

For a research step, record:

  • source or provider;
  • query or constraint set;
  • observation timestamp;
  • currency, price, and availability status;
  • assumptions and fields that were not verified.

For a commit, add:

  • the approval reference;
  • the exact payload or a safe redacted representation;
  • the external request identifier;
  • the response status;
  • the resulting resource or confirmation identifier;
  • any expiry, cancellation, or retry condition.

A compact receipt might look like this:

``json { "receipt_id": "r_0184", "action": "book_hotel", "status": "succeeded", "approved_at": "2026-08-21T15:30:00Z", "provider": "example-travel-api", "external_id": "booking_7812", "observed_total": { "amount": 642.10, "currency": "USD" }, "created_at": "2026-08-21T15:30:04Z" } ``

Avoid claiming more than the evidence supports. A provider response can establish that a request was accepted; it may not establish that a payment settled or that every itinerary detail will remain unchanged. Use statuses that match the provider’s semantics, such as requested, accepted, confirmed, partial, or needs_reconciliation.

Make the receipt the handoff between steps

The receipt should not be a terminal log line that disappears into an operator console. Make it the input to the next workflow decision.

A practical sequence is:

  1. 1. Prepare a proposed action and its assumptions.
  2. 2. Review the exact external effect.
  3. 3. Commit only after the required approval is present.
  4. 4. Write a receipt immediately, including failure details.
  5. 5. Route the next action from the receipt status.

If a travel provider returns a changed price, the receipt should say needs_reapproval, not silently retry with the new total. If a message API times out after accepting a request, use unknown or needs_reconciliation; do not issue a duplicate send merely because the first response was missing.

This design also keeps retries safe. Give each commit an idempotency key derived from the intended action and approval, then associate every attempt with the same receipt. Operators can distinguish a retry of one commitment from a second commitment with similar wording.

Keep the operator view calm and useful

More logging does not automatically produce more trust. The operator surface should show the smallest set of facts needed to decide what happens next:

  • what the agent intended;
  • whether approval was required and present;
  • what external system answered;
  • what changed;
  • what, if anything, needs human attention.

Group implementation details behind an expandable evidence view. Put unresolved conditions in a short “next action” field. For example: “Price changed from $642.10 to $681.40; review required before retry.” That is more useful than twenty lines of HTTP diagnostics, while the full request and response can remain available for audit.

Receipts should be append-only from the workflow’s perspective. If an operator corrects a label or adds a note, create an amendment rather than rewriting the original event. This preserves the difference between what the system observed and what someone later concluded.

For privacy, redact payment credentials, passport numbers, and access tokens before storing or displaying receipts. Retain a reference to protected material only when there is a legitimate operational need and an appropriate access boundary.

Test the uncomfortable states

The happy path proves little. Build tests around the states that make a receipt valuable:

  • approval is missing or applies to a different payload;
  • the provider changes price between preparation and commit;
  • the request succeeds but the response times out;
  • only part of a batch commits;
  • a retry arrives with the same idempotency key;
  • a downstream resource is later canceled or revoked.

For each case, assert both sides of the contract: no unauthorized external effect, and a receipt that accurately explains the outcome. Also test that a failed commit does not become a successful itinerary item merely because the model generated confident prose.

A useful acceptance check is to hand an unfamiliar operator one receipt and ask them to answer: what was attempted, what was authorized, what happened, and what should happen next? If they need to inspect hidden state or infer meaning from a vague status, improve the receipt schema before adding another integration.

Next steps for builders

Add commitment receipts to one workflow first. Define its effect classes, choose five or six stable statuses, and store the evidence fields that matter for that domain. Put the approval reference and idempotency key beside the action rather than in a separate, disconnected log.

Then expose a compact operator view and exercise stale, partial, and unknown outcomes. Keep external actions behind explicit review gates, and let the receipt—not a persuasive completion message—determine whether the workflow may continue.

The goal is not to make agents narrate every internal step. It is to make consequential steps leave a durable, bounded explanation. When every commitment has a receipt, operators can drain work predictably, recover safely, and trust the system without accepting ambient noise as proof.