Home
Home/resources/how to give long running ai agents a…
Ed25519 signaturesSHA-256 hashes8 SDKs
Status
Sign inStart free
Home
AI GovernanceAI AgentsTracesAI Attestation

How to Give a Long-Running AI Agent a Verifiable Trace

An agent that runs for hours leaves a long trail of model calls, tool invocations, and side effects. Application logs record that trail; they cannot prove it was not edited afterward. Here is how to give every agent run a signed, sealed, independently verifiable trace with Invoance: create, attest, anchor, seal.

Adeola OkunolaFounder, Invoance15 July 2026·9 min read
On this page
  1. Long-running agents create an evidence problem
  2. What a trace is (and is not)
  3. Step 1: open a trace per agent run
  4. Step 2: attest every model call
  5. Attestation types map to agent moments
  6. Step 3: anchor tool calls and side effects as events
  7. Step 4: seal the run
  8. What you can hand an auditor
  9. Practical notes for agent builders

Long-running agents create an evidence problem

An agent that runs for hours or days makes dozens of model calls, invokes tools, writes to databases, and sometimes waits for a human to approve something. When a customer, an auditor, or a regulator later asks what the agent actually did, the answer usually lives in application logs: plain rows that anyone with database access can edit or delete after the fact.

That is the gap. Ordinary logs record what happened, but they cannot prove the record itself was not cleaned up afterward. And for AI systems the bar is rising: Article 12 of the EU AI Act expects automatically generated logs across a high-risk system's lifetime, ISO/IEC 42001 auditors ask how AI decisions are recorded, and enterprise procurement questionnaires now include a blunt version of the same question: how do you log what your AI did, and how would we know if those logs were altered?

Invoance answers with three primitives that compose: AI attestations (a signed record of each model interaction), events (a signed record of everything around the model), and traces (a container that groups one run's records and seals them into a single verifiable proof). This guide wires all three into a long-running agent loop.

What a trace is (and is not)

A trace is a named, ordered grouping of anchored records under a single identifier. Every event, document, and AI attestation you attach keeps its own SHA-256 content hash and Ed25519 signature; the trace id is the thread that connects them. When the run ends, you seal the trace: Invoance computes a composite hash over every item's hash in chronological order, signs a seal record with your tenant's key, and closes the trace to new items.

A trace is not a workflow engine. It does not enforce steps, sequencing, or approvals, and it does not care how long the run takes. An open trace keeps accepting records for minutes or months, which is exactly the shape of a long-running agent.

The sealed result is signed, append-only, and independently verifiable. Anyone can recompute the composite hash from the item hashes and check every signature against your published public key, with no Invoance account required.

Step 1: open a trace per agent run

Create one trace per run, at the moment the run starts. Put the run id in the label (open traces must have unique labels within your account, so a stable run id prevents collisions) and put searchable context in metadata. Then anchor a run-started event right away: it gives auditors the authoritative starting timestamp, and a trace needs at least one event before it can be sealed.

One trace per run (Node; the Python SDK mirrors this surface)
import { randomUUID } from "node:crypto";
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

// One id per agent run. It names the trace and rides along on every event.
const runId = randomUUID();

const trace = await client.traces.create({
  label: "support-agent-run-" + runId,
  metadata: { agent: "support-refunds", environment: "production" },
});
console.log(trace.trace_id, trace.status); // the trace id, "open"

await client.events.ingest({
  eventType: "agent.run.started",
  payload: { run_id: runId, goal: "resolve ticket 4821" },
  traceId: trace.trace_id,
});

Step 2: attest every model call

Each time the agent calls a model, ingest an attestation of type output. Invoance hashes the input and the output with SHA-256, canonicalizes the full record, and signs it with your tenant's Ed25519 key. Use subject to tie the attestation to the run and step, and pass the trace id so it lands inside the run's trace.

Inside the agent loop, after each model response
const att = await client.attestations.ingest({
  type: "output",
  input: promptSentToModel,
  output: modelResponse,
  modelProvider: "anthropic",
  modelName: "claude-sonnet-4-5",
  modelVersion: "2025-09-29",
  subject: {
    sessionId: runId,
    step: String(stepNumber),
  },
  traceId: trace.trace_id,
  idempotencyKey: runId + "-model-" + stepNumber,
});

console.log(att.input_hash, att.output_hash, att.status);

Attestation types map to agent moments

Attestations come in three types, and the other two cover the moments that make agents hard to audit. Use decision when the model chose a course of action: which tool to call, whether to escalate, whether a threshold was met. Use approval for human-in-the-loop sign-offs, with the approver's id in subject. The type is part of the signed payload, so "the model decided" and "a human approved" become distinct, provable claims rather than log lines that read the same.

The ingest call returns the input hash, output hash, and payload hash immediately; the signed record is durably queued and written asynchronously, so the call adds no meaningful latency to your loop. Duplicate submissions with the same content return the original attestation id instead of creating a second record.

Step 3: anchor tool calls and side effects as events

Model calls are half the story. An auditor's question is usually about effects: what did the agent actually change? Anchor an event for every tool invocation and consequential side effect, with the same trace id. Keep action names stable and lower-snake (agent.tool.called, refund.issued, ticket.closed) so filtering stays useful months later.

If the agent produced an artifact (a generated report, an exported file), anchor the file itself with Document Anchor and the same trace id. The document's hash becomes part of the sealed proof, so the artifact the customer received is provably the artifact the run produced.

One event per tool call
await client.events.ingest({
  eventType: "agent.tool.called",
  payload: {
    run_id: runId,
    tool: "stripe.refund",
    amount_cents: 4200,
    result: "success",
  },
  traceId: trace.trace_id,
});

Step 4: seal the run

When the run finishes, on success or failure, anchor a final run-finished event and seal the trace. Sealing is asynchronous: the API returns 202 and a worker computes the composite hash, a SHA-256 over every item's hash in chronological order across events, documents, and attestations, in the order they actually happened. The worker then writes a trace.sealed event signed with your tenant key and marks the trace sealed. Poll the trace until its status reads sealed; the proof endpoint returns 409 until then.

A sealed trace rejects new items. Anything ingested with that trace id afterward fails with a 409 instead of quietly rewriting history, which is precisely the property you want from a record of an autonomous system.

End of run
// Continues Step 1: client, trace and runId are the values created there.
await client.events.ingest({
  eventType: "agent.run.finished",
  payload: { run_id: runId, outcome: "resolved" },
  traceId: trace.trace_id,
});

const seal = await client.traces.seal(trace.trace_id);
console.log(seal.status, seal.message); // "sealing", "Seal initiated. Poll GET /v1/traces/{trace_id} for status."

// The seal runs in the background. Poll until the status leaves "sealing";
// the proof endpoint answers 409 trace_not_sealed until then.
let detail = await client.traces.get(trace.trace_id);
while (detail.status === "sealing") {
  await new Promise((resolve) => setTimeout(resolve, 1000));
  detail = await client.traces.get(trace.trace_id);
}
if (detail.status !== "sealed") {
  throw new Error("seal did not complete, trace is " + detail.status);
}

const proof = await client.traces.proof(trace.trace_id);
console.log(detail.status, proof.composite_hash); // "sealed", the composite hash

What you can hand an auditor

A sealed trace gives you three artifacts. The proof bundle (GET /v1/traces/{trace_id}/proof) is a self-contained JSON document carrying every item's content, hash, signature, and public key, plus the composite hash and the signed seal record: everything needed to verify the run offline. The PDF proof is the same material as a branded document with a QR code pointing at the verification page, which is the version legal teams tend to file. And if you enable public verification for the trace (it is off by default), anyone can open the proof page at invoance.com/proof/trace/ followed by the trace id and check it in the browser; AI attestation payloads stay hash-only there unless you separately choose to expose them.

Be precise about what this proves. Verification is detection, not prevention. It establishes that every record in the trace is exactly what was signed at ingestion, that nothing in the sealed sequence was edited, and that nothing in the middle was removed. That is the claim an auditor can test with math instead of taking on trust.

Practical notes for agent builders

Anchoring belongs beside your loop, not inside it. Fire attestations after you have already acted on the model response, or push them onto a queue; the proof does not depend on blocking the agent, and the wall-clock cost of the calls is small either way. Derive idempotency keys from the run id and step number, as in the samples above, so a crashed-and-retried step lands exactly once.

Keep one trace per run rather than one per customer or one per day. The label carries the run id, metadata carries the rest, and traces are not a scarce resource: the free tier includes 250 traces, 50 AI attestations, and 1,000 ledger events per month, which is enough to trace a real run end to end before paying anything, and Builder raises the trace ceiling to 60,000 per month.

  • Traces product overview How sealing and composite proofs work, end to end.
  • AI attestations quick start Endpoints, limits, and the public proof flow for attestations.
  • Start free 250 traces and 50 attestations a month on the free tier.
On this page
  1. Long-running agents create an evidence problem
  2. What a trace is (and is not)
  3. Step 1: open a trace per agent run
  4. Step 2: attest every model call
  5. Attestation types map to agent moments
  6. Step 3: anchor tool calls and side effects as events
  7. Step 4: seal the run
  8. What you can hand an auditor
  9. Practical notes for agent builders
Adeola Okunola

Adeola Okunola

Founder, Invoance
About the author

I'm Adeola, founder of Invoance.

I build proof infrastructure for audit logs, AI attestations, and business records that need to stand up to security, compliance, and legal scrutiny.

Most systems document what happened. Invoance helps prove it.

All articles by Adeola
Related product

AI Attestation

A signed record of what a model was asked, what it answered, and which model it was.

Open AI Attestation
Keep readingAll articles
AI Governance9 min read

How to Prove Your AI Did What It Said: A Developer's Guide to Verifiable AI Outputs

Your AI's output is gone the moment it returns. Logs aren't proof. This guide shows how to attach a cryptographic receipt to every model call, in three lines of code, with a public URL anyone can verify, no Invoance account required.

Adeola Okunola·6 May 2026Read
AI Governance10 min read

AI Attestation: What It Is, Why It Matters, and How to Implement It

AI systems make decisions that affect loans, diagnoses, hiring, and contracts. When those decisions are challenged, organizations need proof of what the model produced, when, and with what inputs. AI attestation provides that proof.

Adeola Okunola·9 March 2026Read
Compliance9 min read

ISO 42001 Compliance: What Engineering Teams Need to Know

ISO 42001 is the first international standard for AI management systems. For engineering teams, it means specific technical requirements around auditability, traceability, and governance. Here is what you actually need to build.

Adeola Okunola·2 March 2026Read

Try it on the free plan.

Create a signed record and verify it yourself.

Start freeRead the docs

Proof infrastructure. Records are hashed, signed with your organization's Ed25519 key, and stored append-only, so anyone can check them later.

Products

  • Audit Logs
  • Event Ledger
  • AI Attestation
  • Document Anchoring
  • Traces

Developers

  • Documentation
  • API reference
  • SDKs
  • How it works
  • How traces seal
  • System status

Verify

  • Audit Log
  • Event
  • AI Attestation
  • Document
  • Trace

Company

  • Company overview
  • What is Invoance
  • Pricing
  • Security
  • Compliance teams
  • Finance teams
  • Partners
  • Brand assets
  • Resources
  • Help center
  • Contact
© 2025 – 2026 Invoance, Inc. All rights reserved.© 2026 Invoance, Inc. All rights reserved.
PrivacyLegal noticeLegal FAQ