How it works

Observe, Replay, Gate, Audit — the mechanism that turns a black-box agent into one you can prove.

See it applied to regulated production
How it works

From a black box you can't debug to one you can re-run.

Runback keeps a signed record of everything an agent does — so you can reproduce any run, find what broke, and test a fix before release.

Costs you~3 linesany agentyour model call runs untouchedsee the code →
01
Observe
Capture every decision the model sees — context, tools, tokens, PII redacted.
02
Replay
Re-run from the exact captured context. A different output means behaviour changed.
03
Gate
Simulate a policy against history. Enforce it live, block before it runs.
04
Audit
Export a tamper-evident, hash-chained record. Every decision provable.
→ Compounds: every incident auto-mines into a regression test.
What changes

When you can reproduce any decision, three things change.

01
Model upgrades become a diff, not a bet. Replay production decisions against the new model and compare the output before it ships.
02
Prompt iteration stops regressing. Every resolved incident becomes a test that blocks that specific failure from recurring.
03
Regulated deployment becomes day-one. The signed record builds from the first run — not retrofitted six months later.
01 · Observe

See exactly what the model saw.

Every step records the precise context the model was handed — system prompt, conversation, tools — captured at the model boundary, with PII redacted in-process. A failed run opens on the step that broke. Click any step:

research-email-agent · run failedclick any step ↓
Tool call · send_email — failed here
tool
send_email
status
error
input
{ "to": "alex[at]acme.co", "body": "Next.js 16 summary…" }
Invalid recipient — the model wrote the address in plain text ("[at]") instead of a valid email. The run failed here.
02 · Replay

Reproduce any decision — then find what changed it.

Re-execution holds tools, retrieval, and context fixed and runs the model fresh — a different output is signal, not a recording glitch. When something breaks, bisect the timeline to the exact change in log₂ tries.

Original · gpt-4opass

Flagged the $85k application for human review — correctly applied the $50k limit.

route_to_review({ reason: "exceeds_auto_limit" })
Replay · gpt-4o-0513regression

Approved the same $85k application — ignored the $50k limit entirely.

issue_approval({ amount: 85000 })

12 revisions, one regression. Bisect finds it in 4 probes, not 12:

prompt v1
prompt v2
prompt v3
prompt v4
prompt v5
prompt v6
prompt v7
prompt v8
gpt-4o
gpt-4o-0513
gpt-4.1
claude-sonnet-4-6
Ready — 12 candidates, one regression, unknown which.

On a real run, each probe compares the model's decision — which tool, with what arguments — not tool or environment behavior. A regression caused by a changed tool response, not the model's choice, won't be found by this search.

One scenario, two outcomes

Hours of log archaeology, or minutes on the failing step.

The same production failure, resolved with a log pipeline and with Runback. Not a customer story — the mechanism below is exactly what a real incident uses.

Without Runback
3h 48m
Grep through 2,400 log lines.
Guess. Patch. Hope it doesn't recur.
2:47 AM — alert fires
3:00 AM — first engineer online
4:15 AM — found a suspicious log line
5:20 AM — maybe found the prompt issue?
6:35 AM — fix deployed, fingers crossed
same incident
With Runback
4m 23s
Open the run. Root cause is highlighted.
Patch, replay to confirm, seal the record.
2:47 AM — alert fires with run link
2:49 AM — run open, failure step highlighted
2:51 AM — root cause found in messages[]
2:52 AM — fix applied, replay confirms
2:52 AM — sealed. Done.
03 · Gate

Turn a fix into a guardrail — then enforce it live.

Save the step as an eval that must keep passing. Simulate a candidate policy against real history to see what it would have blocked, then enforce it in-process — blocked before it runs. A breach becomes a red row, never an incident.

  • refund within $100 limitpass
  • disputed charge → must escalatefail
  • out-of-scope → declinepass
  • stays in policy tonepass
3 / 4 passed — 1 regression caught before deploy
Runback's policies table: four active policies — refund-flow guardrails, a QA test policy, a loan amount ceiling and PII data minimisation — each with its version, rule count and last-updated date.
04 · Audit

The cassette that sealed itself as it ran.

Per run

Export a complete, tamper-evident record of any run — every event in a SHA-256 hash chain, signed. Change one byte and verification fails. The artifact an auditor actually asks for.

$schemarunback.audit/v2
run_idsupport-refund-agent
events6 · chained
content_digest3e68cdbbf372df98…
signatureEd25519 ✓ signed
Recompute the chain to verify — POST to /api/audit/verify.
0nownowa1b2c3d4e5f6
current digesta1b2c3d4e5f6a1b2c3d4e5f6
SHA256(prev_hash + canonical({kind, key, output}))
Org-wide

Runs also seal into an org-wide ledger — one signed root proves any run is in the log, without handing over the rest.

Each leaf below is one sealed run. Click one to see the minimal set of hashes that proves it belongs to the signed root — without exposing anything about the other three.

merkle_root
5e1a8c3f6b9d
node_01
3b6d9e0f1c4a
node_23
a2c5f8b1e4d7
Then it compounds

Every incident becomes a permanent test.

A run that breaches policy or errors auto-enrolls as a golden test — deduped, so each distinct failure is one test that grows your suite by itself.

A daily job goes further: it takes each real failure and asks a model to probe the same weak spot from a different angle. Every proposal lands as pending — never auto-approved — until a human reviews it.

Walk the loan-approval-agent incident — all 5 steps, the policy block, the cassette →

Why not something else

Four gaps, and what closes each one.

  1. 01

    You can't reproduce what your agent decided.

    Logs record the outcome. Re-execution shows the reasoning — the exact context, retrieval, and messages[] the model saw. Root cause in 4m 23s, not 3h 48m.

    Demo scenario — walk the exact step · walk it →
    Without Runback · 2,400 lines
    [02:47:03] INFO agent.run started
    [02:47:04] INFO tool_call check_credit
    [02:47:05] ERROR issue_approval failed
    … 2,397 more lines, no context
    With Runback · exact step
    ▸ agent decides ← failure here
    model: gpt-4o · 418 tok
    system: loans up to $50k only
    root cause: in this block ↑
  2. 02

    You think you can build this. The parts that matter you can't.

    The capture layer takes a sprint. The golden corpus, fleet benchmarks and policy history take years — and can't be imported, back-filled or bought.

    Auto-mined adversarial corpus — the actual mechanism · read how it works →
    Your org · month 1
    124 runs captured
    Your org · month 6
    847 golden tests
    Your org · month 12
    2,400+ auto-mined
    Competitor today
    starts from 0

    Illustrative — not usage data. The mechanism (auto-mined from real prod failures, can't be imported or bought) is real; these specific numbers aren't a customer's.

  3. 03

    An auditor will ask. A regulator will follow.

    EU AI Act Art. 12, APRA CPS 230, NIST AI RMF — one record, built from the first run rather than retrofitted when the auditor asks.

    EU AI Act, Article 12 — read the law · the law ↗
    EU AI Act · Art. 12mandatory logging for high-risk AI
    APRA CPS 230operational incident recording
    NIST AI RMFmeasure, manage, govern functions

    one Runback cassette · satisfies all three

  4. 04

    The team that starts capturing today has an advantage in 18 months that can't be bought.

    Behavioral history only builds forward. Every month you delay is data you can never recover.

    Fleet benchmarks, model diff, policy library · what's in Pro →
    4m 23sMTTR with Runback
    vs
    3h 48mwithout captured context

    Illustrative — based on common production patterns, not a measured customer average. loan-approval-agent · 2:47 AM · every month you delay is behavioral data you can never recover

Where the data lives

Your agent runs in your app. So how does Runback see it?

Your model calls happen inside your own application. Hook it up once; everything else runs on the trace it produces.

1 · Your agent

Instrument once

A ~3-line SDK wrap or your existing OpenTelemetry traces. A post-hook — your real model call runs untouched.

const dbg = withDebugger(model)
const res = await generateText({
  model: dbg.model,
})
await dbg.finish({
  status: "success",
})
SDKProxyOpenTelemetry
2 · In your process

Redact before egress

Secrets, keys, emails, card numbers and SSNs are scrubbed before a trace is sent anywhere.

3 · Your store

Land in a store you own

Postgres you control — self-hosted or our managed cloud. Delete a run and it's gone.

4 · On the trace

Replay · Evals · Audit

Every feature reads the same captured trace. No extra wiring, no second integration.

Replay and evals re-execute a step, so they use a model key configured server-side. Observe, time-travel, and audit need no model key at all.

import { withDebugger } from "@runback/sdk";
import { generateText, stepCountIs } from "ai";

const dbg = withDebugger(model, { runName: "support-agent", redact: "standard" });
const res = await generateText({
  model: dbg.model,
  tools: dbg.tools(myTools),
  stopWhen: stepCountIs(8),
  prompt: task,
});
await dbg.finish({ output: res.text, status: "success" });

Every run now shows up ready to observe, replay, gate, and audit. See all integrations →

The fastest way to get it is to open a run.

Walk a real failing run step by step — no signup.