An AI Agent Should Not Move Money Until It Logs This
A chat transcript is not an audit trail. Before an agent submits a payment, its log must preserve the evidence, authorization, and exact action that crossed the boundary.
August 9, 2026 · 8 min read

Consider an accounts-payable agent handling a supplier invoice. It reads the invoice email, retrieves the vendor record and purchase order, checks the amount, prepares a bank instruction, shows that instruction to an employee, then submits it through a payment API after approval.
The important line in its audit log is not “payment completed.” It is the record written immediately before submission, when the agent has assembled a specific payment instruction but the bank has not accepted it. Call that event `action.prepared`.
That line needs enough evidence for a reviewer to establish which inputs shaped the decision, which software produced it, what the employee approved, and what the agent was about to send. After the call, a separate event must record what happened.
The requirement at the action boundary
A useful internal policy can be stated precisely:
Before a side-effecting tool call, the system must durably record the proposed action, its decision inputs, the applicable authorization, and the software configuration that produced it; execution must stop if that write fails.
“Side-effecting” means a call that changes another system, such as releasing a payment, sending an email, modifying a customer record, or booking travel. A search request can still deserve logging, especially if it exposes sensitive data, but it does not carry the same immediate risk as a command that commits funds.
This is a proposed engineering baseline, not a universal legal rule. Article 12 of the EU AI Act states: “High-risk AI systems shall technically allow for the automatic recording of events (logs) over the lifetime of the system.” That requirement applies within the Act’s high-risk framework and applicable timetable; it does not prescribe one schema for every business agent. NIST guidance and management standards can inform controls, but they do not turn every suggested field below into a blanket statutory mandate.
The payment agent’s control is stricter and easier to test. If it cannot persist `action.prepared`, the payment API does not run. An asynchronous logger, which queues the record for later, is cheaper in latency but can lose the decisive evidence if the worker crashes after payment and before the queue flushes.
The minimum event record
The record needs stable identifiers before it needs prose. A run identifier links the whole invoice workflow; trace and step identifiers locate the payment within that run; an attempt number separates the first call from a retry. Record timestamps in a consistent time standard, while preserving service-side timestamps returned by external tools when available.
A compact schema might group the evidence like this:
```text event_id, run_id, trace_id, step_id, attempt prepared_at, actor, environment, policy_result prompt_refs, model_identity, model_settings retrieval_refs, tool_identity, tool_arguments proposed_output, approval_ref, idempotency_key ```
`actor` should identify the agent service and the account or workload identity under which it operates. `environment` distinguishes production from testing and points to the deployed code, orchestration configuration, policy bundle, and container or build artifact. Without those references, a reviewer may know which model answered while missing the application code that converted its answer into a bank instruction.
The policy result belongs in the same event. Record which rule set was evaluated, its version, the decision, and any limit applied. For the invoice workflow, that might show that human approval was required because the proposed operation was a payment, regardless of amount. Logging only “policy passed” hides the rule that passed and makes later changes impossible to separate from the original decision.
Preserve the prompt the model received
“Prompt” must include more than the employee’s request. The model may have received a system instruction, developer instructions, conversation history, tool descriptions, retrieved invoice text, and an automatically generated note saying an approval was present. Preserve the exact rendered input or store a content-addressed snapshot, where a cryptographic hash points to immutable retained content.
A hash by itself proves only that later material matches earlier material. It cannot tell an auditor what the prompt said if the original has been deleted. If retaining full prompts would capture bank details, personal information, or confidential contracts beyond their allowed retention period, store protected snapshots with field-level redaction, encryption, access controls, and a documented deletion schedule. Secret values such as API keys should never enter the log; record the credential reference and version instead.
Prompt templates also need versions. Saving the user text while omitting the template can conceal the instruction that told the model to prefer one purchase order, disregard stale vendor data, or emit a particular JSON structure. The payment agent should preserve the rendered prompt and point back to the template and orchestration code that produced it.
Record the model and retrieved evidence
Model names often behave like aliases. The log should retain the identifier requested by the application and the model or deployment identifier reported by the provider, plus the region or endpoint, routing configuration, inference parameters, and any seed the service accepts. Inference is the model’s act of generating an output from supplied input. A seed may improve repeatability, but it does not guarantee identical output across changed infrastructure or model revisions.
Retrieved data needs similar treatment. For the supplier invoice, record the query, filters, access identity, document identifiers, versions or hashes, and the exact excerpts placed in model context. Logging that the agent “checked the vendor database” is insufficient when the database contained several addresses or when a later update replaced the bank account the model saw.
Rank and retrieval scores can help explain why one purchase order entered the prompt while another did not, although they are secondary to preserving the selected content. For live API responses, retain the response fields that influenced the decision or an authorized snapshot of the response. A pointer to a mutable record will lead a reviewer to today’s data, not necessarily the data used before payment.
Approval must bind to one action
The employee should approve the proposed bank instruction, not a generic invoice task. The approval record must preserve the material shown on screen, the approver’s authenticated identity, the time, the permitted action, any limit or expiry, and a hash of the exact tool arguments. If the agent changes the amount, destination, currency, or payment date afterward, the hash changes and the approval no longer matches.
This closes a common gap between interface and execution. An approval screen might display a supplier name and total while hiding the destination account embedded in the API payload. The log then proves that someone clicked Approve, but not that the person saw the consequential fields. For the payment-release step, the displayed review object and submitted command should be generated from the same structured data rather than assembled separately.
Approval also needs scope. Permission to pay one invoice should not authorize a retry with modified arguments, a second invoice, or an unrelated transfer later in the run. When a human edits the proposal, record the change as a new prepared action and require the policy engine to evaluate it again.
Append the output, result, and failure
Before execution, preserve the raw model output and the parsed command derived from it. The distinction matters because an application parser may round a number, choose the first of several model suggestions, or fill a missing field from another database. Validation results should show whether the command matched its schema and which checks ran before approval.
After execution, append `action.succeeded` or `action.failed` rather than overwriting `action.prepared`.
Store the tool’s status, response reference, external transaction identifier, completion time, and confirmed side effects. If the bank rejects the instruction, the prepared record remains evidence of intent without falsely implying that money moved.
Timeouts need special handling. A timeout does not prove failure; the bank may have accepted the payment after the agent stopped waiting. The log should mark the outcome as unknown, retain the idempotency key used to prevent duplicate submission, and record the reconciliation check performed before any retry. Also capture exceptions, policy denials, canceled approvals, fallback paths, and partial completion, including which system changed before the workflow stopped.
An audit log is not a replay machine
A complete-looking log cannot guarantee a bit-for-bit replay. The model provider may have changed weights or routing behind an alias, sampling can produce another answer, and hidden safety systems may behave differently. An external vendor record can be corrected; a search index can reorder documents; a payment API can return a different result because the account balance and date have changed.
The log supports reconstruction: a reviewer can inspect what was supplied, what was proposed, who approved it, and what each system reported. Replay requires more. Teams would need retained model artifacts where available, immutable input snapshots, executable application builds, preserved tool schemas, and simulated external services that return captured responses instead of touching live systems. Closed model APIs may make exact replay unavailable at any price.
More evidence also costs more. Synchronous writes add storage and network delay at every action boundary, while full prompt and retrieval snapshots increase retention expense and create another sensitive dataset to protect. For low-impact drafting, that burden may not be worth paying. For the line that releases the supplier payment, a durable pre-action write is the cheaper failure mode.
Questions people ask
Is a chat transcript enough for an AI agent audit?
No. A transcript can omit system instructions, retrieved records, model settings, parser changes, policy decisions, and the exact tool payload. It also may be written after the action. An audit record should connect the transcript to immutable input snapshots, software versions, approval evidence, and separate prepared and completed events.
Should the log be written before or after the tool call?
Both, as separate events. Write the proposed action and its evidence durably before a side-effecting call, then append the returned result or failure afterward. If the pre-action write fails, stop execution; otherwise the system can create an external effect without preserving the record needed to authorize and investigate it.
Can a seed make an agent run fully reproducible?
Usually not. A seed can constrain sampling when a model service supports it, but model revisions, provider routing, retrieval changes, application code, and external system state can still alter the run. Treat the log as evidence for reconstruction unless the entire execution environment and all relevant inputs have been preserved.
What should happen when a payment API times out?
Record the outcome as unknown rather than failed. Before retrying, query the payment system using the external reference or idempotency key and append that reconciliation result. A blind retry can create the duplicate payment that the audit trail was meant to help prevent.
One story a day
The story of the day, in your inbox
One real story about AI each morning — no hype, no alarm, just company for the road.



