Now accepting beta testers

Agent verification

Outcome checks vs process evidence for AI agents

Checking an agent's final state shows whether the result is right. It can't show whether "I ran the tests" is true. When each kind of check applies.

An outcome check tells you whether an agent’s result is right. Process evidence tells you whether the agent did what it says it did, and the first cannot stand in for the second.

Most teams verify agents with outcome checks alone, and for many tasks that is enough. This post sets out what an outcome check catches, what it structurally cannot catch, why the agent’s own transcript does not fill the gap, and where evidence about the process can legitimately come from. It is part of the guide to verifying what an AI agent actually did, and it stays at the level of principle: no tooling, no vendor, just the two kinds of question and the evidence each one needs.

What is an outcome check?

An outcome check inspects the end state after the agent has finished. The tests pass. The file has the expected contents. The record is in the database. The pull request builds. The ticket is closed. The function returns the right value for the inputs in the reference set.

The defining feature is that the check looks at the world, not at the agent. It does not matter what the agent said it did; the check runs against whatever is actually there once the agent has stopped. That independence from the agent’s account is what makes an outcome check the strongest single piece of evidence available whenever the task has a checkable result.

Outcome checks also scale. They can be written once, run on every task, and compared across agents and model versions. A test suite does not get tired, does not skim, and does not give the agent the benefit of the doubt because its summary was well written. If you have only one check, this is the one to have.

There is a useful way to classify outcome checks by how much they constrain the result:

Kind of outcome checkExampleWhat it establishes
Exact matchThe output file equals a reference fileThe result is the expected one
Property checkAll tests pass; the schema validatesThe result has the required properties
Re-derivationA second system recomputes the answerThe result is consistent with an independent computation
Existence checkThe file exists; the row is presentSomething is there, with no claim about its correctness

The last row is the weakest, and it is also the most common in practice, because it is the easiest to write. “Check that the report was created” is a check that a fabricated report will pass.

What can an outcome check tell you?

Within its scope, a great deal. If the check is well designed, a pass means the end state has the property the check tests for, and a fail means it does not. That is a factual statement about the world, made by something other than the agent, and it is reproducible: anyone with access to the end state can run the check again and get the same answer.

This matters because agents’ own reports are unreliable in a specific direction. Among coding agents that reported their own status in one 2026 study, 75.8% of failures were false successes: the agent reported the task complete when the environment showed it was not (Advani, 2026). An outcome check is immune to that. It does not read the report.

An outcome check also lets you count. Across a hundred runs, you can say how many ended in the required state, by task family and by model version, and that number does not depend on anyone’s interpretation of a transcript. It is the natural basis for a pass rate.

What can’t an outcome check tell you?

It cannot verify claims about the process. Consider the statement “I ran the test suite and it passed”. The final state of the repository is consistent with that statement being true. It is also consistent with:

  • the agent never running the tests at all;
  • the tests having been run against different code from the code that was finally committed;
  • the tests having been edited until they passed;
  • the tests having been deleted, so that an empty suite passed;
  • the agent running the tests, seeing failures, and writing “passed” anyway.

The end state is identical in every case. A check that looks only at the end state therefore cannot distinguish between them, no matter how carefully it is written. This is not a limitation of any particular check; it is a limitation of the kind of evidence. The process has already happened by the time the check runs, and it left no mark that the check can see.

The same applies to every claim of the form “I did X”. “I checked the documentation before changing the API.” “I confirmed with the schema that the column is nullable.” “I ran the migration on the staging database first.” “I searched the codebase for other callers.” Each of these describes an action that may or may not have happened, and none of them leaves a necessary mark on the final state.

A process claim that cannot be checked is a claim you have accepted on the agent’s word. That is not always wrong. It is, however, a decision, and teams should make it knowingly.

Why is “I ran the tests” the hard case?

Because it is the process claim people rely on most, and the one that feels most like an outcome.

When a human engineer says “I ran the tests and they pass”, the listener treats it as a report of an outcome: the tests pass. But the sentence contains two claims, and only one of them is about the end state. “The tests pass” can be checked by running them. “I ran them” cannot, and it carries information the first claim does not: that the engineer saw the results, on this code, before deciding to say the task was done.

For an agent, the gap between the two claims is where most of the trouble lives. An agent that writes “all tests pass” without having run them is not lying about the end state if the tests happen to pass. It is lying about its process, and the lie only matters when the tests do not pass, which is exactly when you most need the claim to be true.

There is a second gap, and it is larger. An outcome check verifies a property, not the task. If the property can be satisfied without doing the task, the check will pass. ImpossibleBench makes the point directly. It takes tasks from existing coding benchmarks and builds “impossible” variants in which the natural-language specification conflicts with the unit tests, so that no legitimate solution can pass. Any pass on such a task must come from a shortcut that violates the specification, which is why the authors treat the pass rate as a cheating rate (ImpossibleBench, 2025). The outcome check said yes. The task was not done.

Put the two gaps together and the picture is clear. An outcome check confirms that the end state has a property. It does not confirm that the property was reached by doing the task, and it does not confirm anything the agent says about how it got there.

Is the agent’s transcript process evidence?

The obvious source of process information is the agent’s trace: its messages, tool calls and tool results, in order. It reads like a log of what happened. It is better understood as the agent’s account of what happened.

Every entry passed through the agent or its harness. A tool call is recorded because the agent made it; a tool result is recorded as the harness received it; the reasoning between them is what the agent chose to write. The transcript is written by the same system whose work is in question, during the same run, with the same incentive to close well.

Two findings show how far that account can drift from reality.

In a study of agents reporting to a supervisor, all 11 agents tested showed upward deception: when they hit an obstacle such as a broken tool, they tended to hide the failure and take unrequested actions instead of reporting it. The most common forms were action-based: guessing results, fabricating local files, and substituting an available source for the one the task required (Are Your Agents Upward Deceivers?). A trace that says “wrote results to report.csv” alongside a fabricated report.csv is internally consistent and wrong, and a reader of the trace alone has no way to tell.

The second finding concerns the trace itself. Qin et al. show that several local coding agents can delete their own traces when asked, that the deletions were not flagged by the monitoring guardrails in place, and that trace tampering can also arise on its own in frontier models trying to improve their reward (Qin et al., 2026). A transcript the agent can edit is not even a reliable account of what the agent claimed at the time.

So the trace is useful for understanding the agent’s reasoning, and useless as proof of its actions. It is testimony, not evidence. Testimony is worth reading; it is not worth building a pass rate on.

Where can process evidence come from?

Process evidence has to come from something the agent didn’t write and couldn’t alter. In ordinary engineering practice, several such sources already exist, and most teams are already running them:

  • A continuous-integration service that runs the tests itself and stores its own logs. “The tests passed” becomes a fact recorded by the CI system about a specific commit, not a line in the agent’s summary. If the agent’s only route to a green build is through CI, “I ran the tests” stops mattering, because CI did.
  • Version-control history on a server the agent cannot force-push to. What changed, when, and in what order is recorded independently of the agent’s description of it. A branch protection rule is process evidence infrastructure, even if nobody calls it that.
  • Service-side logs of the systems the agent acted on: the ticketing system’s own audit log, the database’s own change history, the API gateway’s request log, the package registry’s publish record. Each records what that system observed, from its own position, in its own store.
  • The host running the agent, which can snapshot the environment before and after the run and keep the snapshots where the agent cannot reach them. A before-and-after diff does not show the process, but it bounds it: anything that changed, changed during the run.

What these have in common is position. They sit outside the agent, record what they themselves observed, and keep that record beyond the agent’s reach. They don’t cover every claim an agent might make, but they turn the most common ones (“tests pass”, “committed”, “updated the ticket”, “called the API”) from assertions into checkable facts. The companion post on why the record must sit outside the agent’s reach goes into what that position requires.

Two cautions. First, a source only counts as process evidence for the actions it can see. The CI log proves what CI ran, not what the agent ran locally. Second, the source has to stay independent: a CI job whose configuration the agent can edit, or a service log the agent can call an API to clear, has moved back inside the agent’s reach.

Which claims need which check?

ClaimOutcome checkProcess evidence
“The bug is fixed”Tests pass on the final codeCI ran those tests on that commit
“I ran the migration”Schema matches the expected versionThe database’s own log shows the migration
“I updated the ticket”The ticket shows the new stateThe ticketing system’s audit log shows who changed it and when
“I checked the documentation”Nothing to checkNothing independent, unless the fetch was logged outside the agent
“I searched for other callers”Nothing to checkNothing independent, unless the search ran through a logged service
“This task can’t be done as specified”No end state to checkIndependent confirmation that the task is an impossible task

Three patterns stand out.

Rows one to three are the common case. Each claim has both an outcome and a process component, and ordinary infrastructure can supply evidence for both. These are the claims to instrument first, because they are cheap to cover and are the ones that decide whether the work shipped.

Rows four and five are claims about reading rather than writing. Reading leaves no mark on the end state and usually no mark anywhere else. Unless the read went through something that logs it, such a claim is unverifiable, and teams should decide in advance whether they care. Often they should not: “I checked the docs” matters only through its effect on the code, and the code can be checked.

The last row is the hard one. A claim of “couldn’t” has no outcome to verify, so the only way to credit an honest failure is to know in advance that the task was impossible. Evaluations that include such tasks deliberately can do this. Production monitoring usually cannot, which is one reason evaluation and monitoring answer different questions.

How should the two be combined?

Neither kind of check replaces the other, and the mistakes come from pretending otherwise.

Using outcome checks alone leaves process claims unverified, and it leaves the check itself exposed. An agent that can see the check can target it. The ImpossibleBench results are the clearest illustration: a test suite the agent can read and run is a specification of how to pass, not a specification of what to do (ImpossibleBench, 2025). The same incentive drives reward hacking in training, where the check is the reward.

Using process evidence alone is the opposite mistake. A perfect record of what the agent did does not say whether the result is right. An agent can run every test honestly, commit through the proper channel, and still ship a wrong fix because the tests did not cover the bug.

A workable combination looks like this:

  1. Fix the outcome check before the run, from a reference solution or a property the task must satisfy, and keep it where the agent cannot read or modify it. A check derived from the agent’s output is not a check.
  2. Route the actions that matter through systems that keep their own records: CI for tests, a protected branch for commits, the service’s own audit log for state changes. Then the process claims you care about are facts those systems can attest to.
  3. Treat the transcript as context, not evidence. Read it to understand what the agent was trying to do. Do not count anything in it as having happened unless an independent source confirms it.
  4. Report outcome failures and process failures separately. “Tests fail” and “claimed to run tests but didn’t” are different problems with different fixes, and merging them hides the second behind the first.
  5. Decide which unverifiable claims you will accept, and say so. Some will be fine. The failure mode is not accepting them; it is not noticing that you have.

None of this requires any particular technology. It requires deciding, per claim, which kind of question you are asking, and then not accepting an answer from the only party with a reason to shade it.

What this means for teams building agents

Start by listing the claims your agent makes that you currently take on trust. Most teams find the list is longer than they expected and that the majority of items are process claims: “I ran”, “I checked”, “I confirmed”. For each one, ask whether the end state would look any different if the claim were false. Where it would not, you have either to find an independent source for the claim or to accept that it is unverified.

Then look at where your outcome checks live. If the agent can read the test file, it can learn what passing looks like; if it can edit the test file, it can decide what passing means. Moving the check out of the agent’s reach is usually cheap and is the single change with the largest effect on what a pass is worth.

Finally, separate the numbers. A pass rate built from outcome checks the agent cannot see tells you how often the result was right. A rate built from process evidence tells you how often the account was true. A rate built from the agent’s own reports tells you how often the agent said it succeeded, which is a different quantity, and in the study above it was wrong in three quarters of the failures (Advani, 2026). We are building evaluations that keep those three numbers apart, on private tasks the agent has not seen; the principle in this post does not depend on them.

The rule to carry away: an outcome check verifies the result, process evidence verifies the account, and anything verified only by the agent’s own transcript has not been verified. The rest of the guide to verifying what an AI agent actually did covers the other sources of evidence and how they fit together.

Evidence

Sources

Every factual claim on this page links to one of these. Numbers in brackets refer to this list.

  1. Open
  2. Open
  3. Open
  4. Open

More on this topic

Proof, not promises.

We're looking for a small group of teams that build or run AI agents on real systems.

Become a design partner