AI agents
Tool Results, Provenance, and State Updates
Design result envelopes that support verification, recovery, and trustworthy state transitions.
By the end you can
- Define tool result semantics as an operational contract rather than a capability label
- Contrast Raw payload with Natural-language summary in “A shipping agent interpreted ‘accepted’ as ‘delivered’”
- Trace “Optimistic state updates can compound a partial failure” through a concrete execution path
- Produce “Design a result envelope for an asynchronous action” with evidence for “Dependent actions wait for a verified postcondition”
Comparison
Summaries describe outcomes the tool never confirmed
A raw payload, a natural-language summary, and a typed result envelope hand the runtime three very different things to update state from. Prefer whichever one lets dependent actions wait for a verified postcondition, not for text that merely reads as success. A summary is the weakest on that count. It can describe an outcome the tool never confirmed, in confident prose. The step that comes next then acts on the description rather than on the outcome.
This is not a matter of taste, and it has a date. In June 2025 the Model Context Protocol added a typed result channel alongside the prose one. Revision 2025-06-18 lets a tool declare an `outputSchema`. Where it does, the specification stops being permissive: “Servers MUST provide structured results that conform to this schema.” The conforming data travels in a `structuredContent` field, and clients should validate it against the declared schema. Sarah Gooding at Socket put it plainly the day after: “Tools can now declare an outputSchema, a JSON Schema describing the precise structure of their results”.
So the three columns are no longer a preference poll. A raw payload gives maximum detail, couples you to the backend, and is hard for a model to interpret. A natural-language summary is easy to read, ambiguous about state, and fragile as control flow. A typed result envelope supports validation and enables replay. It costs you an interface you now have to design and keep stable. That was the price a live protocol paid to hand its clients a result they can check rather than read.
Raw payload
The backend response is passed through unchanged.
- Maximum detail
- Backend coupling
- Hard for models to interpret
Natural-language summary
The tool describes the outcome in prose.
- Easy to read
- Ambiguous state semantics
- Fragile control flow
Typed result envelope
Stable fields plus optional human-readable detail.
- Supports validation
- Enables replay
- Requires interface design
Update durable state from typed fields, not wording
Tool results should distinguish request acceptance, asynchronous progress, completion, partial success, and failure. They should also carry resource identity, version, timestamps, provenance, and a verification path.
That distinction is not an invention of agent design. HTTP made it normative. RFC 9110, published in June 2022, defines the one status code built for exactly this case: “The 202 (Accepted) status code indicates that the request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility in HTTP for re-sending a status code from an asynchronous operation.”
Read the last sentence again. The protocol does not merely decline to promise completion. It tells you in advance that it will never come back to correct itself. Whatever confirms the outcome has to be something you go and read later. Microsoft's Azure Architecture Center gives API designers the same rule: “An asynchronous method should return HTTP status code 202 (Accepted) to indicate that the request was accepted for processing but is incomplete.”
Natural-language summaries are useful for the model. Durable state should be updated from typed fields. Otherwise wording changes can alter control flow.
A summary sentence is written to be read, not to be depended on: Knight's system named its own error 97 times before the open, on a channel nothing branched on.
Example
191 packages scanned “Delivered” while still at the unit
A status field can report an action finished while nothing has moved. That failure is not hypothetical. It has been sampled, counted and published. The US Postal Service Office of Inspector General reviewed parcels at 25 delivery units and issued a management alert on 19 February 2020. Of 1,126 packages sampled, 423 — 38 percent — had been improperly scanned. The alert itemises the worst category among them: “One hundred and ninety-one (191) packages that were scanned “Delivered” to the addressee, but which were still at the unit.”
It was not a one-off. A second audit covered select Chicago stations and went to the U.S. House Committee on Oversight and Reform. Dated 1 February 2021, it records the same finding under Improper Scanning: “One hundred fifty packages had a “Delivered” scan. A “Delivered” scan should only be made when a package is successfully left at the delivery address.” Of 249 improperly scanned packages there, 150 carried that scan.
Nothing about those records looks broken from downstream. The field is well typed, the value is terminal, the timestamp is real. The customer, the merchant, the refund workflow and any agent polling for completion all read the same word and all draw the same conclusion. The parcel was on a shelf.
- Decision at stake: Design result envelopes that support verification, recovery, and trustworthy state transitions. A “Delivered” value is written by the party responsible for delivering. It is a self-report, and 191 of them in one sample were wrong.
- Hidden assumption: that acceptance of a request proves the business outcome is complete. RFC 9110 says the opposite about the one 2xx code designed for this situation: the processing has not been completed, the request might or might not eventually be acted upon, and HTTP has no facility for re-sending a status code once the asynchronous work finishes.
- Primary control question: Optimistic state updates can compound a partial failure. Ask what those 191 records would have triggered next. Then ask how much of it can be reversed once a refund, a rating, a replacement shipment or a closed support ticket has already fired on the strength of the word.
- Evidence to collect: Dependent actions wait for a verified postcondition. The Office of Inspector General did not settle the question by reading the scans. It went to the 25 delivery units and looked at what was still sitting there. The software equivalent is a receipt, a job identifier or a safe read owned by something other than the actor that claimed success.
Case
Retrieved content can decide which API runs next
Protocol authors reached their own conclusion about what arrives from a tool. The Model Context Protocol specification is explicit about the standing of a tool's own self-description: “For trust & safety and security, clients MUST consider tool annotations to be untrusted unless they come from trusted servers.”
The demonstration behind that caution is peer-reviewed. In 2023 six researchers ran indirect prompt injection attacks against real deployed systems, including Bing's GPT-4-powered Chat and code-completion engines. Greshake and colleagues put the consequence in their abstract, for anyone whose control flow reads tool output: “We show how processing retrieved prompts can act as arbitrary code execution, manipulate the application's functionality, and control how and if other APIs are called.”
That is the whole reason a result envelope has a shape at all. If retrieved text can reach the part of the system that decides which call happens next, the boundary between data and instruction has to be drawn in the interface. It cannot be left to the model's judgement. A result is evidence about the world. It is not an instruction from the user.
Visual
Downstream trust needs status, identity, provenance, and an evidence handle
Downstream code can trust a result only when it carries execution status, resource identity, provenance, and an evidence handle. The evidence handle and the next actions have to belong to different owners, with a test each.
Execution status states whether the operation was rejected, accepted, pending, partial, or complete. Resource identity names the exact object and version affected. Provenance records source system, timestamp, and execution actor. The evidence handle provides a receipt, job ID, diff, or query for independent verification. Next actions declare the retry, poll, compensate, escalate, or finish options that are legal from here.
Provenance is the node most often left as a design word. It does not have to be. It has had a standard since 30 April 2013, when PROV-DM became a W3C Recommendation. The abstract defines the term: “Provenance is information about entities, activities, and people involved in producing a piece of data or thing, which can be used to form assessments about its quality, reliability or trustworthiness.” The model has three kinds of thing — entities, activities and agents — with time of creation, use and end recorded against them. That is what “source system, timestamp, and execution actor” turns into once someone writes it down properly. The Australian Research Data Commons points practitioners at the same model: “provenance information can be described directly in the W3C Provenance Data Model (PROV-DM) and Provenance Ontology (PROV-O).” The InterPARES Trust AI Terminology Database cites it too.
The evidence handle carries one extra condition, and it is the one most often skipped. It must not share a dependency with the action it reports on. A status surface hosted inside the system it monitors is an evidence handle only for as long as nothing is wrong — which is precisely when nobody needs it.
- 1
Execution status
States whether the operation was rejected, accepted, pending, partial, or complete.
- 2
Resource identity
Names the exact object and version affected.
- 3
Provenance
Records source system, timestamp, and execution actor.
- 4
Evidence handle
Provides a receipt, job ID, diff, or query for independent verification.
- 5
Next actions
Declares retry, poll, compensate, escalate, or finish options.
Key idea
Optimistic state updates can compound a partial failure
If the runtime marks success before the environment reaches the expected state, later actions operate on a fiction. Asynchronous tools and eventually consistent systems make this failure common. The variant that is harder to see is the one where the system did detect the problem and said so in the wrong format.
On the morning of August 1, 2012, Knight Capital Americas had the diagnosis and no channel that could act on it. The SEC's order of 16 October 2013 records what the system did with it: “Knight’s system sent 97 of these e-mail messages to a group of Knight personnel before the 9:30 a.m. market open. Knight did not design these types of messages to be system alerts, and Knight personnel generally did not review them when they were received.” The router then executed over 4 million trades in 154 stocks for more than 397 million shares in 45 minutes. The loss ran to over $460 million. The penalty for the Rule 15c3-5 violations was $12 million. Ninety-seven correct statements of the fault, delivered as prose on a channel with no consumer, produced no control flow whatsoever.
Update durable state only from explicit status fields, and verify material postconditions before dependent actions. A failure that can only be noticed by a person reading a sentence is, for the purposes of the running system, a failure that was never reported.
Forty-five minutes of steps taken on an unverified state cost over $460 million, and each one of them rested on a claim nobody had checked.
Analogy
A Parcel Tracking Record, Not a Green Checkmark
Label created, collected, in transit, delivered: a parcel system keeps those states apart. A single green check would erase every one that a recovery depends on.
The green check has a documented failure mode of its own, and it is worse than losing detail. It can outlive the state it claims to report. On 28 February 2017 the Amazon S3 disruption hit the US-EAST-1 region, and the public status surface could not report the outage because it was inside it. AWS's own summary of the event says so: “From the beginning of this event until 11:37AM PST, we were unable to update the individual services’ status on the AWS Service Health Dashboard (SHD) because of a dependency the SHD administration console has on Amazon S3.” That is roughly two hours during which the evidence handle told every reader the service was fine. Shaun Nichols put the mechanism plainly in The Register: “Its outage was so severe that Amazon was unable to update its own online public dashboard to warn users about the outage: the icons were stuck on green lights because the red icons warning of failures were hosted in the downed systems, apparently.”
A parcel has one destination, though. One software operation can touch several resources that finish at different times. So the envelope needs a status per resource rather than a status for the call. Each of those statuses needs a verifier that does not depend on the thing it is verifying.
Result design determines whether an agent reasons from evidence or from wishful state.
Steps
Design a result envelope for an asynchronous action
Take an action that completes later than the call returns, and design the result envelope it should have. The exercise is there to show how an early state update compounds. If the envelope reports acceptance as if it were completion, every step built on top of it inherits an outcome nobody has checked, and the error surfaces several actions later. Write down which field the runtime reads to decide the action is genuinely finished. Then write down who writes that field, and what the state should say in the meantime.
You do not have to invent the answer. Two public standards have published theirs, and you can copy either. Google's AIP-151 covers long-running operations. It dates from 2019 and states the rule: “Individual API methods that might take a significant amount of time to complete should return a google.longrunning.Operation object instead of the ultimate response message.” The field the runtime reads is the boolean `done`. Google's own operations.proto says precisely what it gates: “If the value is `false`, it means the operation is still in progress. If `true`, the operation is completed, and either `error` or `response` is available.” While `done` is false, neither branch of the `oneof result` is set. There is no prose to over-read and no half-answer to mistake for an answer.
Microsoft's Asynchronous Request-Reply pattern arrives at the same place from the other direction. The status endpoint's response carries a `status` field holding “a consistent, documented set of terminal and nonterminal values” — Pending, Running, Succeeded, Failed or Canceled. Alongside it sit `createdAt`, `lastUpdatedAt`, `percentComplete` and `error`. That field is written by the operation service, not by the caller and not by the model. The caller's only job is to poll it.
Now run the five steps against your own envelope. List the lifecycle states, keeping accepted, queued, running, partial, completed, cancelled and failed apart. Attach stable identity: job and resource identifiers that cannot be confused with labels. Expose provenance: timestamps, actor, version and source system. Define verification: a safe read or receipt that confirms the postcondition and is not produced by the actor. Map recovery actions: when to poll, retry, compensate, or escalate.
- 1
List lifecycle states
Separate accepted, queued, running, partial, completed, cancelled, and failed.
- 2
Attach stable identity
Return job and resource identifiers that cannot be confused with labels.
- 3
Expose provenance
Include timestamps, actor, version, and source system.
- 4
Define verification
Provide a safe read or receipt that confirms the postcondition.
- 5
Map recovery actions
State when to poll, retry, compensate, or escalate.
Acceptance of a call never earned the next step
Tool outputs are part of the agent's environment model. Stable result semantics are necessary for planning, monitoring, and incident reconstruction.
A reviewer of tool result semantics works backwards. Pick a step that depends on an earlier action. Ask what that step read in order to conclude the earlier action had succeeded. If the answer is the acceptance of the call rather than a confirmed outcome — a 202 whose own specification warns it will never be corrected, a summary sentence, a scan written by the party being audited — the dependency was never earned. Every step downstream of it rests on the same unchecked assumption.
The three failures in this lesson are one failure at three scales. A scan that said “Delivered” for 191 packages still sitting at the unit. A dashboard that stayed green for roughly two hours because it lived inside the outage it was meant to report. Ninety-seven e-mails that named an error correctly to nobody who was listening. In each case the information existed and the interface between the information and the next action did not.
If the meaning of a result field drifts, the planner, the monitor and the person reconstructing the incident are each reading a different environment.
Key takeaways
- Tool results should distinguish request acceptance, asynchronous progress, completion, partial success, and failure — RFC 9110 already separates those ends, and warns that HTTP has no facility for re-sending a status code once the asynchronous work finishes.
- Natural-language summaries are useful for the model, but durable state should be updated from typed fields; the Model Context Protocol revision 2025-06-18 made the typed channel a MUST for any server whose tool declares an `outputSchema`.
- Execution status must say whether the operation was rejected, accepted, pending, partial, or complete, and resource identity must name the exact object and version affected — 423 of 1,126 sampled packages in the US Postal Service Office of Inspector General's 2020 alert show what a status written by the actor is worth on its own.
- Provenance is a standard, not an intention: PROV-DM became a W3C Recommendation on 30 April 2013, and it records entities, activities and agents with time of creation, use and end.
- Update durable state only from explicit status fields and verify material postconditions before dependent actions; Knight's 97 e-mails identified the error before the open and changed nothing, while the router traded for 45 minutes.
- Tool outputs are part of the agent's environment model, and an evidence handle that shares a dependency with the action it reports is not one — the AWS Service Health Dashboard stayed green on 28 February 2017 because it was hosted inside the outage.