execution evidence
Follow one approved tool call through its audit trail
Inspect the records from a real local file write using ActionProxy's Node.js example. Follow the action ID from proposal through human approval, grant consumption, and reported result.
- For
- Developers, platform operators, and security reviewers designing evidence for governed AI tool execution
- Reviewed
- Oct 1, 2026
- Length
- 1,525 words

A real example: approve a local file write
Start with the Node.js approval example and its setup instructions. The runner uses the published JavaScript SDK 0.1.1 to propose local.write_note. A person reviews the filename and content; a separate Node.js process consumes the execution grant, creates the file, and reports the result. The gateway does not write the file itself.
Copy the action ID printed by the runner. In the console's Audit view, paste it into Audit search and expand its events. This searches the latest 500 loaded records. For older actions, use the server-filtered command below. Replace PORT with the loopback port from ./actionproxy status and toolcall_REPLACE_ME with your action ID. These instructions use the local demo's authentication-disabled loopback setup; authenticated deployments require an authorized audit:read credential.
Retrieve this action's audit events
# Local demo only; use its current loopback port and action ID.
ACTIONPROXY_DEMO_URL=http://127.0.0.1:PORT
ACTIONPROXY_ACTION_ID=toolcall_REPLACE_ME
curl --fail --silent --show-error \
"$ACTIONPROXY_DEMO_URL/v1/audit?toolCallId=$ACTIONPROXY_ACTION_ID&limit=100"Read the captured sequence
The excerpt below comes from a local run on October 1, 2026. It shows selected events and fields, reordered from oldest to newest for reading; the endpoint returns newest first. The identifying tool-call ID is replaced consistently with toolcall_EXAMPLE. Other IDs, timestamps, hashes, payloads, and intermediate events are omitted. This is an illustration of observed records, not a complete export or a chain-verification input.
Selected records for one approved write
[
{
"type": "tool_call.submitted",
"toolCallId": "toolcall_EXAMPLE"
},
{
"type": "policy.require_approval",
"toolCallId": "toolcall_EXAMPLE"
},
{
"type": "approval.approved",
"toolCallId": "toolcall_EXAMPLE"
},
{
"type": "execution_grant.consumed",
"toolCallId": "toolcall_EXAMPLE"
},
{
"type": "execution.attempt_completed",
"toolCallId": "toolcall_EXAMPLE",
"data": { "state": "succeeded" }
}
]Separate the decision from the effect
- Find
tool_call.submittedandpolicy.require_approval. The proposed filename and content belong to the submission; policy pauses this unknown tool for review. At this point, the runner has not written a file. - Read
approval.approved. Itsdata.inputDecisiondistinguishes original from edited input. Compare the original and approved payload hashes when investigating an edit. Approval alone does not establish that execution happened. - Follow
execution_grant.created,tool_call.authorized, andexecution_grant.consumed. The runner must consume the bound grant before its local write; use the full export to correlate the grant and attempt IDs. - Inspect
receipt.outcome_recorded,tool_call.executed, andexecution.attempt_completed. In the captured success case, the attempt state issucceeded. Open the file separately to verify its actual contents; the audit trail records what the runner reported. - In a rejected run, look for
approval.rejected. No execution grant was consumed and no file was created. An execution attempt with stateunknown_outcomeafter a write error is different: inspect the file and action before deciding what to do. Never assume uncertainty means nothing happened.
Follow the action beyond the conversation
A chat transcript alone cannot establish which tool arguments reached an executor, which policy evaluated them, or what the downstream system reported. Make the structured action and its lifecycle the unit of investigation. Retain conversational context only when relevant and appropriate.
Start with a stable action identifier. Connect the proposed input, decision, review, execution authority, and outcome so an investigator can reconstruct one action without matching unrelated logs manually.
The records worth correlating
- The normalized action request, including the tool name, policy-relevant arguments, sourced identity and adapter context, and request hash.
- The policy decision, rule and policy identity, reason, and whether the result was allow, deny, or require approval.
- The approval record, reviewer eligibility, expiry, and the identity of the payload actually approved.
- The original and approved payload identities when an authorized reviewer changes supported input.
- The execution receipt or grant, attempt identity, executor identity, and transition into dispatch.
- The reported terminal result, including succeeded, failed, timed out, cancelled, or unknown.
Correlation is more useful than log volume
Typed records with stable relationships help an operator move from an approval to its proposal, or from execution authority to the corresponding attempt and outcome. Recording more conversation text does not supply those relationships.
Keep requester, asserted agent label, authenticated principal, reviewer, and executor identities separate. Preserve where an identity came from and whether it was verified. They can have different responsibilities.
Reconstruct one action in order
- Find the canonical request and confirm the tool, input identity, tenant, requester, adapter, and submission time.
- Read the decision record and identify the policy version, matched rule, outcome, and reason codes that applied to the request.
- If review was required, verify reviewer eligibility, the decision time, expiry, and whether the approved input differs from the original proposal.
- Confirm that execution authority is bound to the same request, decision, policy, approval, attempt, and executor identities.
- Inspect the attempt state and reported outcome without treating a timeout or unknown result as proof that the provider did nothing.
- Compare the chain against a trusted head when local chain verification is relevant, then investigate gaps or changed records rather than assuming the chain proves the underlying event was truthful.
Treat the audit store as sensitive application data
Tool arguments and results can contain customer text, recipients, internal identifiers, or secrets. Record enough to support policy, review, and incident reconstruction, then make a deliberate choice about the rest. Decide which fields need full values, which can use stable hashes or references, who can read exports, and how long each record should remain.
ActionProxy's current minimization, retention, and export-redaction controls are incomplete, and records can retain full action payloads. Protect the underlying JSONL, SQLite, Postgres, volumes, exports, and backups accordingly. Redacting a review screen changes its presentation; it does not remove the underlying value from storage.
Example: investigate an approved email
For a hypothetical email incident, follow the proposed recipients and attachment reference through approval, any edit, and the runner's reported outcome. The email approval guide covers the review fields; exact tool-call binding follows the approved payload into dispatch.
ActionProxy's review hash does not preserve the exact rendered card or redacted values a reviewer saw. If needed, capture that presentation separately in the review-channel integration and protect it as sensitive data.
Common questions
Questions developers ask
Can the audit trail prove exactly what appeared on the review screen?
Not from the current review hash alone. ActionProxy preserves proposed and approved payload identities and the approval binding, but it does not retain a byte-for-byte snapshot of the rendered, possibly redacted review card. Workflows that need that evidence should capture it separately in the review-channel integration and protect it as sensitive data.
Does ActionProxy provide an immutable audit log?
No. It provides a locally verifiable SHA-256 previous-hash chain. The chain is neither keyed nor independently anchored, and a storage administrator can rewrite or truncate the sequence and recompute it. Cross-process append ordering is not claimed.
Does the trail prove that the provider performed the effect?
It records the outcome reported by the executor or runner. A timeout, disconnect, or unknown result cannot establish whether the provider performed the effect, so high-consequence operations may need provider lookup and reconciliation through the runner/operator integration.
How long does ActionProxy retain audit records?
The Community implementation does not provide a complete retention and deletion policy. Operators must choose retention periods, restrict access to the underlying files or database, and cover exports and backups in the same data-handling plan.


