Evidence When the Harness Is Vendor-Hosted: Export the AI Agent Audit Trail Before Access Changes
Vendors keep the agent session record. Export the AI agent audit trail: tool calls, approvals, costs, final diff, and environment before access changes.
Go deeper. Build your own.
Suppose the coordinator finished the migration overnight on a computer you have never logged into, and the pull request is open at 7:10 a.m. with forty commits and a green check. Six months from now an auditor asks who approved the schema change, what command the agent ran against the staging database, and what the run cost. The pull request is still there. The session is no longer available through the interface your team used that morning.
That gap is what an AI agent audit trail has to close when the harness is vendor-hosted, and it is a different problem from the one operators solved on their own disks. On a laptop the transcript is a file; you keep it as long as you keep the disk. On a managed harness the transcript is a row in someone else’s system, retained on their schedule and exported through whatever surface they expose. The evidence becomes yours only after it leaves that boundary.
This is the export discipline: the five artifacts that make an evidence pack, the surface each one comes from, a cadence that beats the retention cutoff, a naming and retention scheme that survives a vendor change, and the way replay thinking applies when you do not own the disk. The shapes fit the OpenAI Agents API, Cursor Projects, a managed harness on AWS, or a self-hosted sandbox that only borrows the vendor’s model.
The work moved off the laptop on September 10
On September 10, 2026, OpenAI opened the Agents API public beta: “Build and run cloud agents with the Codex harness, fully managed by OpenAI.” The primitives are Agent, Environment, Session, and Events. OpenAI “manages sessions, orchestration, context compaction, and recovery while your application provides tools and chooses its execution environment.” Sandboxes come from OpenAI, from nine partners, or from your own machines running codex exec-server, and billing follows “the selected model’s API rates,” standard tool rates, and “standard container rates” for OpenAI-hosted sandboxes (OpenAI; Agents API docs). The current docs say the API supports data residency only in the United States and does not support Zero Data Retention, including when the sandbox is self-hosted.
Screenshot: OpenAI Developers, “Agents API” docs overview, captured Sep 13, 2026.
The sidebar in that screenshot lists “Observability and usage” and “Tracing” pages alongside Sessions, Events, and Items. Read those current pages before the first production session, then inventory which data your account and API can export. Navigation labels prove that documentation exists; they do not prove that every field in the evidence pack below is available.
InfoWorld’s September 11 coverage put the dependency plainly: with one vendor providing “the model, context management, tools, orchestration, and execution environment, moving to another platform becomes harder,” and “that dependency could also weaken an enterprise’s negotiating position on pricing and terms.” It placed the launch in a crowded category alongside Claude Managed Agents, in public beta since April, and Amazon Bedrock AgentCore, whose managed harness went GA in June (InfoWorld). The failover matrix compares the three; the continuity drill covers what happens when the managed loop dies mid-job. This piece is about what you keep.
Cursor’s Projects, also September 10, moves the same work the same way: “A Project runs on its own computer in the cloud, so closing your laptop doesn’t stop it,” and each Project “maintains a set of files that sync across every cloud and local machine its agents use.” The blog’s review advice is the part an auditor will notice: “Early on, you review each PR closely. As the fixes hold up, you review less” (Cursor changelog; Introducing Projects). Less review is the deal. The evidence has to carry the weight review used to.
Screenshot: Cursor changelog, “Cursor Projects” (Sep 10, 2026), captured Sep 13, 2026.
Why the transcript became the record once agents started acting
When a model only suggested, the log was a nicety. The human ran the command, so shell history and the git log were the record. An agent runs the command itself, and the diff shows only what survived: not what was tried, not what was refused, not who said yes at 2 a.m. and to what scope. The tool-call trail is the only place the actions live.
When that trail is generated on a vendor’s computer and stored in a vendor’s system, its retention follows their policy, its format follows their API, and its completeness follows their idea of a session. “Context compaction” is the harness deliberately shrinking the working context so the model can keep working. Do not infer from that feature how stored events behave; test an exported long session and get the vendor’s retention and event-preservation answers in writing.
The evidence pack: five artifacts an auditor asks for by name
| Artifact | Must contain | What goes wrong without it |
|---|---|---|
| Tool-call trail with arguments | every call in order: tool name, full arguments, result or exit status, timestamp, which agent or subagent made it | a database call with DROP in it and one without look identical in any summary |
| Approvals with who and when | for each gated action: the request, the approver’s identity, the timestamp, the decision, and the scope (once, session, always) | “approved” with no name is a rubber stamp; the approval-queue playbook is about keeping the name |
| Cost per session | tokens in and out by model, sandbox minutes, tool charges, the rate in force, and the dollar figure you computed from them | the monthly invoice cannot be joined to one session, and the anomaly you must explain has no owner |
| Final diff | the PR number, the merge commit SHA, the patch as merged, and the session ids that contributed | the vendor’s artifacts view is a snapshot of a moment, not what shipped |
| Environment snapshot | sandbox image or environment definition, tool and MCP server list, model id, harness version, network policy, secret names (never values) | “it worked on their computer” can be neither reproduced nor contested |
The sixth file is not evidence but makes the other five admissible: a manifest.sha256 with a hash of each artifact and the PR link, written at export time.
Five artifacts and a manifest. The final diff and the approvals come from the git host and your own gate, not from the vendor.
Where each piece of the AI agent audit trail can be exported from
Illustrative. An operator model of what each surface typically yields, not a vendor specification. No column is complete on its own.
The matrix is the argument in one picture: no single column is complete. Four notes on the columns.
The events API is the primary source for the trail. Check whether arguments come back whole or truncated in both the API and the rendered UI. The vendor UI is for humans on the day, never for the archive; if it is the only surface for something, screenshot it with the session id and clock in frame and file it under raw/. The git host holds the final diff that actually merged and the PR-level approvals, which is why the merge commit is the fixed point every other artifact anchors to (GitHub Docs).
The fourth column is the one people forget. If tool execution runs on your machine, which Cursor’s September 2 self-hosted machines and the Agents API’s self-hosted sandboxes both allow, the commands the agent executed can be logged by you, at a boundary you own, regardless of what the vendor retains. AWS’s September 8 write-up of AgentCore with GitHub Actions already treats evidence as plumbing: traces land through OpenTelemetry and get scored before a PR can merge (AWS). The pipe that feeds an evaluator can feed an archive.
An export cadence that beats the retention cutoff
Three triggers, each with a deadline, because “we export sometimes” is how packs go missing.
| Trigger | Exports | Deadline (illustrative) |
|---|---|---|
| Session end, by webhook or a five-minute poll | that session’s events, usage, artifacts, and PR link | within 15 minutes of the session closing |
| Nightly sweep | every session since the watermark, whether or not the end trigger fired | before 06:00 local, so the morning review reads from the archive |
| Retention-window sweep | any session older than half the vendor’s documented retention window with no pack | weekly; if the window is undocumented, set a conservative local deadline and ask the vendor |
#!/usr/bin/env bash
# illustrative: evidence-pull.sh, export every session since the watermark into the local archive.
# Endpoint paths are placeholders; substitute the ones in your vendor's docs. The shape is the point.
set -euo pipefail
ROOT="$HOME/evidence"; WM="$ROOT/.watermark"; SINCE=$(cat "$WM" 2>/dev/null || echo "2026-09-01T00:00:00Z")
auth=(-H "Authorization: Bearer $VENDOR_TOKEN")
for sid in $(curl -sf "${auth[@]}" "$VENDOR_API/sessions?since=$SINCE" | jq -r '.data[].id'); do
d="$ROOT/$(date -u +%Y/%m)/$VENDOR/$sid"; mkdir -p "$d/raw"
curl -sf "${auth[@]}" "$VENDOR_API/sessions/$sid/events" > "$d/events.jsonl"
curl -sf "${auth[@]}" "$VENDOR_API/sessions/$sid/usage" > "$d/usage.json"
jq -c 'select(.type | test("approval"))' "$d/events.jsonl" > "$d/approvals.jsonl"
pr=$(jq -r '.metadata.pr_url // empty' "$d/usage.json"); [ -n "$pr" ] && gh pr diff "$pr" > "$d/final.diff"
(cd "$d" && sha256sum events.jsonl approvals.jsonl usage.json final.diff 2>/dev/null > manifest.sha256)
done
date -u +%FT%TZ > "$WM"
Two things the script deliberately does not do. It does not trust its own success: a separate check compares every PR merged this week against the archive and pages you for any PR whose session ids have no pack. And it does not build env.json itself; a separate job captures the environment snapshot once per environment definition and per image change, and each session’s pack gets a copy keyed by that hash, because the snapshot changes rarely and the sessions change constantly.
Naming and retention that survive a vendor change
The path is evidence/<yyyy>/<mm>/<vendor>/<session-id>/ and the six file names inside never change, whatever the vendor calls things. Raw exports in the vendor’s own shape go under raw/, so a format change on their side is a parser change on yours, not a hole in the archive. A vendor change is then a new directory name, and the search you run across the archive does not care.
| Tier | Keeps | For | Where |
|---|---|---|---|
| Hot | full packs, indexed for search | 90 days | local disk or the team’s object store |
| Warm | full packs | 1 year | versioned object storage |
| Cold | packs for anything merged to a protected branch | life of the code plus one year | write-once storage with a retention lock (AWS) |
Redact before you write, not after. Tool arguments carry secrets, because agents paste tokens into commands the way people do; strip values and keep names at the moment the pack is assembled, with the same discipline the local-first vault applies to transcripts on disk. A pack with a live credential in it is a liability with a hash on it.
Replay thinking when you do not own the disk
The replay playbook assumed the transcripts were on your machine and the question was finding them. Here the disk is the vendor’s, so replay starts from the pack instead:
- Rebuild the timeline from
events.jsonl, in sequence order, not clock order. - Anchor it to the git host: the merge commit SHA and PR review events are the fixed points, and vendor timestamps hang off them.
- Overlay
approvals.jsonl, so every consequential call sits next to the name that allowed it. - Join
usage.jsonby session id, so the cost of the incident is a number rather than a shrug.
Then run the drill that proves the pack is real. Once a month, pick one session at random and have someone who was not involved reconstruct what happened from the pack alone, with the vendor UI closed. If they cannot, the pack is incomplete, and you found out on a Tuesday instead of in a deposition. Backups are tested by restoring them; evidence is tested by replaying it.
What breaks in a vendor-hosted AI agent audit trail, and the signal that tells you
| Failure | The signal | First move |
|---|---|---|
| Retention beat the export | a PR references a session id with no pack | shorten the retention-window sweep; assume a smaller window |
| Truncated arguments | argument lengths in events.jsonl cluster at one maximum |
pull from the API, not the UI; ask the vendor for the full-argument path |
| Approvals with no identity | the approver field is empty or reads “user” | route approvals through your own gate so the name is yours to record |
| Cost with no join | usage totals exist but carry no session id | tag sessions with your own correlation id at creation |
| The diff is not final | the archived SHA differs from the PR’s head at merge | re-export on merge, not only on session end |
| Environment drift | the snapshot says latest |
pin image tags; snapshot on every change |
| Compaction gaps | sequence numbers skip in the events stream | get the vendor’s answer on compaction in writing; log at your sandbox boundary |
| A secret in the pack | the secret scanner fires on events.jsonl |
redact at assembly; rotate the credential |
Evidence is operating-layer work, not a smarter prompt
Chatbots suggest; agents act, and the acting now happens on a computer you rent by the session. Nothing in the model, the harness, or the coordinator makes the record more durable, because durability is not their job. It is an operating-layer job: the agentic-ops stack calls it layer one, tracing and observability, and a fleet command center that cannot answer “show me the trail for that PR” is a status page. The hybrid-fleet runbook puts the same archive at the center of a laptop-plus-VM setup; this piece is what fills it when the disk is not yours.
The export job is boring, and it should be. The interesting part is the deposition you never have to sit through.
FAQ: AI agent audit trails on managed harnesses
What should an AI agent audit trail contain?
Five artifacts per session: the tool-call trail with full arguments and timestamps, approvals with the approver’s identity and scope, cost per session with the rate in force, the final diff anchored to the merge commit, and an environment snapshot of image, tools, model, and harness version. Hash them together in a manifest.
How long should I keep AI agent session logs?
An illustrative starting policy keeps full packs searchable for 90 days and protected-branch packs for the life of that code plus a year in write-once storage. Adjust the schedule to legal and operational requirements. Export cadence comes first: a log you never copied has no retention period at all.
Sources
- OpenAI: “Introducing the Agents API” (Sep 10, 2026)
- OpenAI: Agents API docs overview
- InfoWorld: “OpenAI launches managed Agents API” (Sep 11, 2026)
- Cursor changelog: “Cursor Projects” (Sep 10, 2026) and “Self-hosted machines” (Sep 2, 2026)
- Cursor: “Introducing Projects” (Sep 10, 2026)
- AWS: “Automated agent evaluation with Amazon Bedrock AgentCore and GitHub Actions” (Sep 8, 2026)
- GitHub Docs: pull requests, required reviews, branch protection
- AWS: object storage retention locks
- OpenAI Developers (@OpenAIDevs), Agents API launch post on X (Sep 10, 2026)
