The evidentiary record for AI agents

Stop hoping your agents behave. Prove it.

The black box for AI agents. Replay the exact decision, prove why it happened, and stop it happening twice.

runback.cassette/v1 · signed · verify it yourself — no account →

Open formatverify without Runback — no account
45 sealedcheckpoints in the public log — chain intact right now
0 bytesPII leaves your process on first-party SDKs — where redaction runs
Self-hostCommunity or Enterprise — data never leaves your perimeter
Why a trace is not enough

Observation shows the symptom. Re-execution finds the cause.

Observability assumes determinism: same code, same trace, twice. Agents don't — every decision turns on context assembled at runtime: retrieved documents, tool outputs, the exact messages[]. A log shows the outcome; only a re-executable run shows the reasoning. Keep Langfuse, LangSmith and Datadog — Runback is the layer above them.

Swipe to see all columns →

LangSmith · Langfuse
Runback
Read the trace after the fact
Re-run from the exact captured context
CI release gate — block regressions before deploy
partial
Signed, tamper-evident audit export
Self-host, data never leaves your perimeter
partial
Regulatory controls (EU AI Act · CPS 230 · NIST)
partial
a log · read onlyyou can read it
a runback record · executablediverges hereyou can run it again

Verified September 2026 — reviewed quarterly, and every ✓ above runs green in public CI ↗.

Full comparison — every tool, every capability →
When it goes wrong

An agent just did something wrong. Now what?

Without Runback
02:47
Agent fails in production
wrong tool called — logs say nothing useful
03:12
Engineer paged and woken up
25 minutes of alert noise before escalation
03:14
Starts reading logs
2,400 lines across 6 services — no context, no thread
04:20
Still in the logs
which call? which step? which message did the model see?
05:31
Maybe reproduced locally
different model version — not sure it's the same bug
06:35
Fix shipped — crossed fingers
MTTR: 3h 48m · confidence: unknown
With Runback
02:47
Agent fails → run captured
automatic, zero config
02:47
Runback opens on the failed step
error-first navigation — no hunting
02:49
Root cause identified
Context tab shows the exact messages[] the model saw
02:51
Fix replayed — confirms it holds
re-ran from step 3 with the patch, same environment
02:51
Incident → golden test in 1 click
permanently in the regression suite
02:51
MTTR: 4 minutes 23 seconds
fix verified · fix confirmed · audit record sealed
illustrative — based on common production patterns
same captured context
then · gpt-4oissue_refund $250policy breach
now · re-runescalate_to_humanwithin policy
one decision, re-run — the fork is the root cause
The product

One failing run, start to sealed record.

Forty-three seconds, no narration: open the failed run, replay it against another model to see where the decision forks, write the rule that blocks it, verify the sealed chain.

The Runback runs list: 40 captured agent runs, 8 of them failed, each opening on the step it broke on.
Recorded on the shared public demo — the real product, on sample data. No audio.
Audit & Governance

Every decision, sealed the moment it happens.

A decision record for every run: hash-chained, sealed the moment it happens, verifiable without us and producible on demand to any auditor. The portable format is the Runback cassette.

  • EU AI Act Art. 12 mandatory logging
  • Scoped, revocable read-only access for auditors — no login, no export handed over blind
  • Ed25519-signed hash chain — verifiable offline, no shared secret
  • Verify without Runback — open verifier, no account
Runback's audit ledger re-deriving its hash chain: forty of forty entries checked, with the six checks it runs listed beneath.
Don't take our word for it

You don't have to trust us. That's the point.

Below is a real audit export from the incident walked through on How it works.Verify it here — no account. The check runs on our server and keeps nothing; each hash checks against the one before it, and the signature establishes who produced it. Want it off our infrastructure entirely? Download the same record and run npx @runback/verify sample-cassette.json.

A sealed audit record — 6 events, hash-chained and signed. Show the raw JSON
{
  "$schema": "runback.audit/v2",
  "manifest": {
    "run_id": "run_a3f1b90c",
    "generated_at": "2026-06-14T02:47:13.950Z",
    "event_count": 6,
    "algorithm": "sha256-chain",
    "content_digest": "2e91e3f5fc451d2c9841d9e3b6c68d78a9b2fca00fdff98989512704180a9189",
    "replay": {
      "cassette_digest": "4376f4529252da46ea7da2f5a0afb59f5cb3511b13459ef8f67cf848f7a02cf8",
      "entry_count": 4,
      "algorithm": "oracle-chain/sha256",
      "note": "The run's oracle stream — every model response and tool output, hash-chained. Re-execute the agent against `events` with @runback/replay and the cassette digest must reproduce. This is proof the recording IS the deterministic input stream of the run — an audit you can re-run, not just read."
    },
    "signed": true,
    "signature": {
      "alg": "Ed25519",
      "value": "d6ab935b3ec9d96883ccb689d5589a50c985fa7109f1e321724a2623d417d7bce7f01a8707a5e11848d7a97c759370deee37297d8f6f3392d29f0d9b53e2e70d",
      "pubkey": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEArDPmR+Gvu1HawnSvM6xjZao7BVPPQ80Qq3sa1hAYvDU=\n-----END PUBLIC KEY-----\n"
    },
    "verify": "Recompute the event chain h_i = SHA-256(h_{i-1} + canonical(event_i)) over `events` → must equal content_digest. Recompute the oracle-stream digest from `events` → must equal replay.cassette_digest. The signature covers `${content_digest}:${cassette_digest}`. Ed25519: verify with the public key embedded in manifest.signature.pubkey (no server key needed — fully offline-verifiable). HMAC-SHA256 (legacy): requires AUDIT_SIGNING_KEY. POST this record to /api/audit/verify.",
    "spec_url": "https://runback.dev/spec",
    "verifier_url": "https://runback.dev/verify"
  },
  "run": {
    "run_id": "run_a3f1b90c",
    "name": "loan-approval-agent",
    "status": "error",
    "input": "Applicant #4471 requests a $12,000 personal loan.",
    "output": null,
    "error": {
      "name": "PolicyBlock",
      "message": "issue_approval blocked — manual-review-required"
    },
    "metadata": {
      "demo": true
    },
    "step_count": 2,
    "total_tokens": 1030,
    "started_at": "2026-06-14T02:47:11.000Z",
    "ended_at": "2026-06-14T02:47:13.950Z",
    "actor_type": null,
    "actor_id": null
  },
  "events": [
    {
      "schema_version": 1,
      "run_id": "run_a3f1b90c",
      "span_id": "r",
      "parent_span_id": null,
      "seq": 0,
      "ts_start": "2026-06-14T02:47:11.000Z",
      "ts_end": null,
      "type": "run",
      "phase": "start",
      "name": "loan-approval-agent",
      "input": "Applicant #4471 requests a $12,000 personal loan.",
      "output": null,
      "status": "running",
      "error": null,
      "metadata": {
        "demo": true
      },
      "_hash": "07bda052e5ce563160c1730ddefb62bace30cbeb871190097ee081d2a8570094"
    },
    {
      "schema_version": 1,
      "run_id": "run_a3f1b90c",
      "span_id": "l1",
      "parent_span_id": "r",
      "seq": 1,
      "ts_start": "2026-06-14T02:47:11.000Z",
      "ts_end": "2026-06-14T02:47:12.400Z",
      "type": "llm",
      "model": {
        "provider": "openai",
        "model_id": "gpt-4o"
      },
      "request": {
        "system": "You are a careful lending agent. Follow policy.",
        "messages": [
          {
            "role": "user",
            "content": "Applicant #4471 requests a $12,000 personal loan."
          }
        ],
        "tools": [
          {
            "name": "check_credit_file",
            "description": "Pull the applicant's credit file.",
            "parameters": {
              "type": "object",
              "properties": {
                "applicant_id": {
                  "type": "number"
                }
              }
            }
          }
        ],
        "params": {
          "temperature": 0
        }
      },
      "response": {
        "text": "Checking the credit file before deciding.",
        "reasoning": null,
        "finish_reason": "tool-call",
        "tool_calls": [
          {
            "tool_call_id": "t1",
            "tool_name": "check_credit_file",
            "input": {
              "applicant_id": 4471
            }
          }
        ]
      },
      "usage": {
        "input_tokens": 428,
        "output_tokens": 184,
        "total_tokens": 612
      },
      "latency_ms": 1400,
      "error": null,
      "_hash": "8f985ca54090e255926fb55830ecf4ab4dc4f9f32b598e04f50e34aaf09745fb"
    },
    {
      "schema_version": 1,
      "run_id": "run_a3f1b90c",
      "span_id": "t1",
      "parent_span_id": "l1",
      "seq": 2,
      "ts_start": "2026-06-14T02:47:12.400Z",
      "ts_end": "2026-06-14T02:47:12.618Z",
      "type": "tool",
      "tool_name": "check_credit_file",
      "tool_call_id": "t1",
      "input": {
        "applicant_id": 4471
      },
      "output": {
        "score": 684,
        "band": "near-prime",
        "disputes_open": 1
      },
      "latency_ms": 218,
      "error": null,
      "_hash": "0fad198fd6469eb12aaa162d8acb5a0d9002f5eaa88806f4a4b6a79383b999bf"
    },
    {
      "schema_version": 1,
      "run_id": "run_a3f1b90c",
      "span_id": "l2",
      "parent_span_id": "r",
      "seq": 3,
      "ts_start": "2026-06-14T02:47:12.618Z",
      "ts_end": "2026-06-14T02:47:13.900Z",
      "type": "llm",
      "model": {
        "provider": "openai",
        "model_id": "gpt-4o"
      },
      "request": {
        "system": "You are a careful lending agent. Follow policy.",
        "messages": [
          {
            "role": "user",
            "content": "Applicant #4471 requests a $12,000 personal loan."
          },
          {
            "role": "tool",
            "content": "{\"score\":684,\"band\":\"near-prime\",\"disputes_open\":1}"
          }
        ],
        "tools": [
          {
            "name": "issue_approval",
            "description": "Approve the loan.",
            "parameters": {
              "type": "object",
              "properties": {
                "amount": {
                  "type": "number"
                }
              }
            }
          }
        ],
        "params": {
          "temperature": 0
        }
      },
      "response": {
        "text": "Credit is sufficient — approving.",
        "reasoning": null,
        "finish_reason": "tool-call",
        "tool_calls": [
          {
            "tool_call_id": "t2",
            "tool_name": "issue_approval",
            "input": {
              "applicant_id": 4471,
              "amount": 12000
            }
          }
        ]
      },
      "usage": {
        "input_tokens": 286,
        "output_tokens": 132,
        "total_tokens": 418
      },
      "latency_ms": 1282,
      "error": null,
      "_hash": "76dbdec70aef43d145f8668c6401248be453f78655bba38957c33a36bf83cfe8"
    },
    {
      "schema_version": 1,
      "run_id": "run_a3f1b90c",
      "span_id": "t2",
      "parent_span_id": "l2",
      "seq": 4,
      "ts_start": "2026-06-14T02:47:13.900Z",
      "ts_end": "2026-06-14T02:47:13.950Z",
      "type": "tool",
      "tool_name": "issue_approval",
      "tool_call_id": "t2",
      "input": {
        "applicant_id": 4471,
        "amount": 12000
      },
      "output": null,
      "latency_ms": 50,
      "error": {
        "name": "PolicyBlock",
        "message": "Blocked: an open dispute requires manual review before approval."
      },
      "policy_block": {
        "rule": "manual-review-required",
        "detail": "when credit_file.disputes_open gt 0 → must call escalate_to_human"
      },
      "policy_evaluated": {
        "passed": false
      },
      "_hash": "bad224a034ed84cd8a216847e2f37084e5b7428f32b0868737faffcc007408a7"
    },
    {
      "schema_version": 1,
      "run_id": "run_a3f1b90c",
      "span_id": "re",
      "parent_span_id": null,
      "seq": 5,
      "ts_start": "2026-06-14T02:47:13.950Z",
      "ts_end": "2026-06-14T02:47:13.950Z",
      "type": "run",
      "phase": "end",
      "name": "loan-approval-agent",
      "input": null,
      "output": null,
      "status": "error",
      "error": {
        "name": "PolicyBlock",
        "message": "issue_approval blocked — manual-review-required"
      },
      "metadata": {},
      "_hash": "2e91e3f5fc451d2c9841d9e3b6c68d78a9b2fca00fdff98989512704180a9189"
    }
  ]
}
Plugs into what you already run

Wrap what's already running. Nothing to migrate.

Runback wraps the model calls your agents already make. Add it to one agent today; it's live from the next request. Setup is a developer task of about fifteen minutes; everything after it — replay, policies, audit export — is used from the dashboard.

Your agents
RUNBACK
ReplayEngineering
GateCI / CD
ProofGovernance
import { withDebugger } from "@runback/sdk";

const dbg = withDebugger(model, { runName: "support-agent", redact: "standard" });
const res = await generateText({ model: dbg.model, tools: dbg.tools(myTools), prompt: task });
await dbg.finish({ output: res.text, status: "success" });
SDKDeepest capture — context, tool calls, token-level detail
ProxyNo SDK in your agent — point its base URL at the gateway
OTelAlready sending traces? Runback consumes them natively
Full data flow →

Built for teams where a wrong decision matters.

When risk, audit or a regulator asks what your agent did six months ago, what do you hand them? A screenshot, a trace nobody can re-run, an export nobody can check — or a signed record they can replay and verify themselves.

Runback's regulatory mapping: EU AI Act, ISO/IEC 42001, NIST AI RMF, APRA CPS 230, GDPR, ISO 27001 and APRA CPS 234, each with compliant, partial and gap counts and a downloadable evidence package.
Early-stage AI team

An agent breaks in production and nobody can say why. Replay the decision, fix it — that incident becomes a permanent test in one click.

Get started free →
Banks & financial institutions

An agent approves something a regulator later asks about. Every decision is sealed the moment it happens — one record covers APRA CPS 230, EU AI Act Art. 12, and NIST AI RMF. Self-hosted in your VPC.

Enterprise & compliance →
Law firms & professional services

Opposing counsel — or your own client — asks exactly what the AI said and why. Every session is captured, sealed, and replayable for court; high-risk outputs are flagged before they reach the lawyer.

Governance for legal →
Safety-critical deployments

The decision that can't be wrong is the one you can't watch every time. A policy gate runs before the call — the block is sealed into the record.

How it works →
What Runback does

Not four tools. One loop, off one recording.

Take the recording away and the other three are guesswork.

01

Observe

Every model call — context, tools, tokens — captured at the boundary. PII redacted in-process before anything leaves your app.

Capture →
02

Replay

Re-run from the exact captured context — tools, retrieval, messages[] held fixed. A different output means behaviour changed. Root cause in minutes, not a war room.

Walk the demo →
03

Gate

Simulate a policy against 90 days of decisions. Enforce it live — block the violating action before it runs.

Policy gates →
04

Audit

SHA-256 hash-chained, Ed25519-signed record. Tamper-evident. The artifact your compliance team actually asks for.

Enterprise →

Every incident becomes a regression test — why this compounds →

Who builds this

Early, and not pretending otherwise.

No customer logos here — yet

We're early. Rather than dress that up with stock-photo testimonials, we'd rather you judge this on the worked incident and the record you just verified above.

Walk the incident →
The tests are public, not a claim

Every layer of the replay engine is proven in public CI. We don't get to say "it works" without also showing you the run that proves it.

See the CI runs ↗

Ship the next agent knowing you can defend the last one.

Start free on managed cloud, clone the source and self-host, or book a call — we'll walk it through live in your environment.

Managed plans from A$49/mo full pricing →