Evidence
Two-sided evidence: why an agent’s log is a claim, not a record
Agent runtimes record what an agent attempted. Systems of record record what changed. Accountability starts when you reconcile the two.
November 4, 2026 · 6 min read
When an AI agent posts a supplier invoice, two things get written down. The agent runtime records a tool call: the operation, the inputs and the result as the agent saw it — success, error or timeout. The ERP records a change document: a new invoice, posted by a user account, at a point in time. Each record is accurate about its own side. Neither knows the other exists.
That is the core problem with treating agent logs as an audit trail. A runtime trace tells you what the agent tried and what it believed happened. It’s a claim. The system of record tells you what actually changed, but it usually doesn’t know an agent was involved, let alone which run caused the change. To know what an agent did, you need both sides, linked.
Two logs, two blind spots
Agent runtimes — in-house orchestrators emitting OpenTelemetry spans, vendor agent platforms with activity exports — are built to debug agents. They capture prompts, tool calls, token counts and latency. They can’t see past the tool boundary. If the ERP accepted a posting but the response was lost on the way back, the runtime records a failure.
Systems of record — ERP change documents, CRM field history, HRIS audit trails, mailbox audit logs, approval workflows — are built to record business changes. They capture who changed what, when and under which credentials. They have no concept of a run, a prompt or a retry. A posting made by an agent looks like any other posting made by that account.
Most of the failures that matter happen in the gap between the two.
Four ways the two stories disagree
The examples below come from a demo environment with simulated data, but each pattern is ordinary.
Contradicted: the timeout that posted
An agent submits a supplier invoice to the ERP. The call times out, so the agent reports a failure and retries. But the first call succeeded: the ERP posted the invoice about two seconds later. The retry posts it again. Both documents go into the next payment run, and both are paid. The runtime shows one timeout and one success. The ERP shows two postings. Only putting them side by side reveals a duplicate payment.
Unconfirmed: the success that never landed
The runtime says the agent posted an invoice document, quotes its number, and marks the run complete. The ERP has no such document. Perhaps the write went to the wrong company code, or the tool reported success for a request the ERP later rejected. On the agent’s dashboard, the workflow finished. From the supplier’s side, the invoice was never processed. These ghost successes tend to surface weeks later, as payment reminders.
Unattributed: changes with no run behind them
The ERP shows postings made with an agent’s technical user at 02:13 on a Sunday, through an interactive transaction rather than the API. No agent run exists at that time. Either someone is using the agent’s credentials, or a script nobody registered is. The runtime can’t reveal this, because there is nothing in its logs. Only the system of record can — and only if someone is looking for writes that no run explains.
Delegated identity: agent and human look the same
Many agent platforms act with the credentials of the person who set them up. When an agent posts an invoice under a clerk’s delegated identity, the ERP attributes the posting to the clerk. Separation-of-duties checks see a human. The audit trail can no longer tell which postings the clerk made and which the agent made, and if the agent’s run log is incomplete, nobody can.
How linking works
Reconciling the two sides means linking each action an agent claims to the record it should have produced. There are three ways to do that, and they are not equally strong.
| Method | How it matches | Base confidence |
|---|---|---|
| Direct reference | The tool returned the ID of the record it created, and the same ID appears in the system of record | 95% |
| Business key | A shared business identifier — for example, a hash of vendor and supplier invoice number — appears on both sides within a time window, with matching identities | 85% |
| Time window | Only identity and timing line up | 70% |
Confidence then drops for known weaknesses. In ThetaLayer, a link loses 25 points when the identities on the two sides disagree and 10 points when the agent acted under a delegated human identity, and it is capped at 50% when more than one record could match. The confirmed retry in the example above is linked at 75% for exactly that reason: a business-key match, made under a clerk’s delegated credentials.
The exact weights matter less than the principle: every link carries its method and confidence, visibly. A time-window match presented as fact is false certainty, and false certainty is worse than a known gap, because it passes review. Auditors, controllers and engineers should be able to see how each link was made and decide how much weight it can bear.
The same goes for the decisions people make about exceptions. When a reviewer confirms a duplicate posting or dismisses a false alarm, the decision should be recorded with who made it and why, and it should survive reprocessing. Evidence arrives late — approvals, payment runs — and links get recomputed as it does. Human judgments shouldn’t be lost when that happens.
How to get there in any enterprise
You don’t need to replace your agent platforms to start closing the gap. Four practices make agent activity reconcilable, whatever tools you use.
- Inventory evidence sources per workflow. For each step an agent takes, name the system that independently records it — ERP change documents, CRM field history, HRIS audit, mailbox audit, the approvals log, payment runs — and check how long each keeps its records. Steps with no independent record are where claims go unchecked.
- Return record IDs and pass correlation IDs. Make every write tool return the ID of the record it created, and log it with the run. Where a system allows it, write the run ID into a reference field. This single change moves most links from time window to direct reference.
- Give every agent its own identity. A dedicated service principal per agent, with its own permissions, makes agent activity distinguishable from human activity and makes unattributed writes detectable. Delegated human credentials should be the exception, and recorded as such.
- Make consequential writes idempotent. Give posting and payment tools an idempotency key derived from the business object — vendor and supplier invoice number, for instance — so a retry after a timeout can’t create a second document. Where the target system doesn’t support that, check for an existing record before retrying.
None of this requires moving sensitive data around. If business keys are hashed the same way at every source, records can be correlated across systems without exporting invoice numbers or bank details.
How ThetaLayer helps
ThetaLayer’s collector runs inside your network with read-only access. It reads agent runtime traces and system-of-record audit logs, hashes or drops sensitive fields, and sends minimized events to the control plane. There, every claimed action is linked to independent evidence with an explicit method and confidence. Contradicted, unconfirmed and unattributed actions become exceptions for a named owner, with a durable audit trail of every review decision. Book a demo to see the evidence chain for one of your workflows.