TrazaDB · Foresight for AI agents · open source, one binary
It learns from every run your agents have ever made — and sees failure coming.
Traza records every step of every agent run, then reads the runs together: which paths end well, which fail, and
exactly where they part. A run heading down a path that has failed before is flagged while it is still running,
and stopped before its next step if you say so. No model judges anything. It is counting, with the intervals to
show how sure it is.
runs that took this path succeeded 69 of 90 times (76.7%, 95% CI 66.9–84.2%); the agent's overall success rate is 54%
76.7% on 90 runs · 95% CI 66.9–84.2%
Predictive fuse, odds 0.7:continue
If it calls issue_refund next:stopforesight: runs that took this path and then called tool:issue_refund succeeded 15 of 30 times (≤66.8%)
Best next step from here: llm:gpt-4o
live-novel-0: novel
llm:gpt-4o→tool:delete_database
no earlier run of this agent took tool:delete_database at this point; the 180 runs that got here went on with tool:search_orders, tool:search_orders×3-5, tool:lookup_customer
Best next step from here: tool:search_orders
Demo corpus
Real output of traza-server 0.28.0 over the engine’s seeded behaviour corpus (226 runs, 1,342 spans), recorded 2026-10-18 by
scripts/demo-numbers.mjs. Synthetic runs with known outcomes, not customer data.
01 Foresight
Every run your agent made is evidence about the one running now.
The Fate Map is a tree of every path an agent’s completed runs took, each branch with its success rate, a 95%
Wilson interval, its cost and example runs. A branch that does measurably worse than its siblings is a
fatal fork, flagged only when a Fisher exact test agrees. A running run is walked down the same
tree, so it gets a verdict while there is still time to act on it.
On the demo corpus, the map predicts how runs end better than the agent’s average does: at depth 3 it
removes 31% of the base rate’s error, measured on runs it was not built
from. Read that number before trusting a verdict; an agent whose fate does not depend on its path scores near
zero, and the map says so.
A predictive fuse acts on the interval’s upper bound, never the estimate, so three unlucky runs stop nothing.
02 Steer
See it coming on your phone. Nudge it before its next step.
Mission Control lists every run working right now, across every project: what each is about to do, what it has
spent, its guard verdict, and how runs like it have ended. When one heads for a fatal fork, Traza Cloud pushes
it to your phone — the console installs as an app, no store involved — or to Slack.
From the notification: approve it to continue, kill it, or send a
nudge. Advice is words for the agent; a block vetoes its next step. Either reaches the agent
once, at the pre-call check it already makes, so nothing has to interrupt a step in flight.
The check after a block nudge, on live-doomed-0
{"verdict": "stop",
"reasons": ["Do not call search_orders again."],
"nudges": [{"kind": "block", "message": "Do not call search_orders again."}]}
runs that took this path succeeded 5 of 50 times (10.0%, 95% CI 4.3–21.4%); the agent's overall success rate is 54%
ApproveKillNudge…
Nudge live-doomed-0
adviceblock
The order does not exist. Stop searching and escalate to a human.
Send nudge
Its next pre-call check · next: search_orders
verdict continue
nudges: [advice] delivered
Illustration of the console on a phone. The run, its foresight, the nudge and the check’s answer are engine output
from the demo corpus.
03 Replay & Fork
Run it again for free. Then change one thing and let it go on.
Point the OpenAI or Anthropic SDK at a recording and run your agent for real, every model answer served from
the tape. Fork it at any step — a different tool result, a different answer — and the agent carries on live down
a branch the recording never took.
Real output: these exact commands, run against traza-server 0.28.0 on 2026-10-18. On
Traza Cloud, $TRAZA is https://api.trazadb.com and the key is a project API key.
A fork, on the demo Claude Code session
Step 5 ran Bash and failed. The fork answers it with
test result: ok. 3 passed; 0 failed instead: steps 0–4 come from the tape
(3 model calls, zero sent to a provider), and after step
5 the agent is live.
A diff across the fatal fork
refund_happy-1 (success) against search_loop-0 (failure): the first
divergence is step 2 — run b has step 2 (tool:search_orders) where run a has no matching step.
What exactly did the model see? Why did the cache miss?
Every request an agent sent, read back as the context window it was: chunk by chunk, each traced to the step
that put it there. The autopsy pairs each call with the one before it in the same conversation, names the first
thing that changed, and prices the tokens the cache could have served.
Step 12 of session 11111111… · claude-sonnet-4-5-20250929
11 chunks, ~197 estimated tokens of conversation; the provider reported 1,512 context tokens, 1,500 of them read from its cache.
userassistanttool calltool result
#0userAdd a total to the cart summaryfrom step 0 · llm:claude-sonnet-4-5-20250929, 12 steps ago
#6tool resultThe file /tmp/demo-shop/src/cart.rs has been updated.from step 3 · tool:Edit, 9 steps ago
#8tool resulterror[E0609]: no field `price` on type `&Item`from step 5 · tool:Bash, 7 steps ago
#10tool resultAdded `price: u64` to Item.from step 7 · tool:Agent, 5 steps ago
Composition: tool call 66% · tool result 21% · assistant 8% · user 4%.
Cache: stable, the prefix is unchanged since step 6 (9 chunks, ~158 tokens) and within the 5 min 0 s TTL.
9 model calls of one session, autopsied with a 60-second cache lifetime (ttl_seconds=60)
step 0—new_context
step 2← 0stable
step 4← 2stable
step 6← 4stable
step 9—new_context
step 11← 9stable
step 12← 6ttl_expired~158 tok · $0.00043
step 13← 12ttl_expired~197 tok · $0.00053
step 14← 13stable
ttl_seconds=60
2 breaks · ~355 tokens re-processed · $0.00096
default TTL (300 s)
0 breaks · 7 stable · 2 new contexts
Advice, from the engine’s lookup table: Calls are further apart than the cache lifetime. Use a longer-lived cache if the provider offers one, or pass ttl_seconds= if it is already in use.
Dollars at the rates in scripts/demo-pricing.json. The provider’s own cache report contradicts the recorded prompts on 1 call; the autopsy counts that rather than explaining it away.
Demo corpus
Real output of traza-server 0.28.0 over the engine’s synthetic Claude Code and Codex transcripts (4 sessions), imported with traza-server import, recorded 2026-10-18 by
scripts/demo-numbers.mjs. Synthetic runs with known outcomes, not customer data.
Show someone what happened, in a form they can check without you.
The engine keeps a hash chain over everything it commits. An evidence pack bundles the chain, its verification,
retention, activity and erasures under one digest the Python standard library can recompute. Traza Cloud’s
notary anchors every cell’s ledger each hour it moves; on Team, it also turns any run into a
proof link: a read-only certificate page with the run’s tape summary, the ledger head, and a
signature you can verify with openssl.
The same check runs in the terminal above, against a real engine.
06 Zero-setup for Claude Code and Codex
Every coding session you have ever run, as runs. One command.
Claude Code and the Codex CLI already write down everything they do. traza-server import turns
those transcripts into runs — every model response a step, every tool call a step, every sub-agent an agent
span — with no SDK, no exporter and no proxy. --watch follows the sessions you are running now.
Then everything above works on them: the Fate Map of your own sessions, the X-Ray of any call, detectors for
test tampering and edit thrash, and blame: which session, step, prompt and model wrote this
line of your code. On Traza Cloud, every developer’s sessions meet in one view: spend by developer, repository
and model, and detector findings. An autopsy of the costliest sessions prices what cache breaks lost.
traza-server --data-dir ./data &# a server (or use one you have)
traza-server import claude-code # every Claude Code session here
traza-server import codex # every Codex session here
traza-server import claude-code --watch&# and keep following live ones
traza-server blame src/cart.rs:42 # who wrote line 42?
Sessions
4
Model calls
22
Tool calls
11
Sub-agents
2
GET /v1/blame?path=src/cart.rs&line=… (the line: self.items.iter().map(|item| item.price).sum())
{"run": "11111111-1111-4111-8111-111111111111",
"tool": "Edit",
"step_index": 3,
"model": "claude-sonnet-4-5-20250929",
"prompt": "Add a total to the cart summary"}
Detector unverified_finish fired on two of four sessions:
finished without testing the last edit. TQL test[error] ..> edit found the session that edited code after a failing
test, at steps 5 and 10.
Demo corpus
Real output of traza-server 0.28.0 over the engine’s synthetic Claude Code and Codex transcripts (4 sessions), imported with traza-server import, recorded 2026-10-18 by
scripts/demo-numbers.mjs. Synthetic runs with known outcomes, not customer data.
Also in the engine
Questions you can ask of every run, in one process.
Run fuses
Limits on cost, tokens, steps, repeats, failure streaks, handoff ping-pong and success odds. The pre-call check refuses a step before it runs; a kill switch stops any run.
The change radar ranks the moments an agent’s prompt, model, version or behaviour changed — including a provider
changing under you with no deploy of yours — with what moved, its p-value and a verdict.
22 read tools for your coding agent, from
foresee_run, list_live_runs, xray_step, blame_line, find_behavior, what_changed to diagnose_session. Stored text stays inside blocks marked untrusted.
The engine’s documentation lists its limits next to its features. Here are the ones people ask about first.
A fatal fork is correlation, not cause
It says runs that went that way ended worse. The step may be a symptom — the agent searched again because the
order did not exist — and the fork tells you where to look, with a success and a failure from the same point to diff.
Two runs that called the same tools in the same order are the same path, whatever their arguments. Without a
declared outcome, a run’s outcome is the status of the span that ended last. Declare outcomes where you can.
A nudge is delivered once, at the agent’s next pre-call check. An agent that never checks never hears it, and a
step already running is never interrupted. The kill switch is what stops a run for good.
Spans arrive when operations end, so a verdict on an acknowledgement can only stop the step after the batch.
Only the pre-call check refuses a step before it runs, and only if the agent asks.
A replay serves recorded model answers. Your tools still execute live, side effects included, unless your
harness takes their results from the recording. A fork’s live half is your agent’s own traffic.
Anyone who can write the ledger file can recompute every head. What makes a rewrite detectable is an anchor
held somewhere else, which is the notary’s job.
Every project is a tenant on a cell: traza-server 0.28.0 on a private network, the
Apache-2.0 release, unmodified, shared by many projects and isolated by the engine's own tenancy. Foresight,
steering, replay and forks, the X-Ray, the importers, retention, erasure with receipts and the ledger are all in
the open binary.
What the cloud sells is what needs someone to host it: your phone and your Slack in the loop, one view across
every project and every developer, a third party’s signature on your runs, and cells that someone else runs,
upgrades and backs up.
The gateway: API keys with scopes, per-project rate limits, operator routes closed
traza-server 0.28.0
A cell on a private network, shared by projects. Yours is one engine tenant, reached only with a credential bound to it
The same binary: ./traza-server --data-dir ./data
Measured, not claimed
Numbers from the engine’s own benchmark records.
Every figure below is copied from a file the benchmark harness writes, with the conditions it was taken
under. They describe the engine on one machine, not a Traza Cloud service level.
Trace lookup by id
p95 1.280 ms1,000,000 spans, 100,000 traces · record
Attribute-filtered search
p95 5.443 msSame corpus, every response checked against the expected span ids · record
Sustained HTTP ingest
65,749 spans/sWrite-ahead-log durability, 1,000 spans per request, client JSON encoding inside the timed loop · record
Bytes stored per byte sent, service traces
0.23x311.9 MiB ingested, 70.5 MiB on disk · record
Bytes stored per byte sent, LLM calls
0.16x438.7 MiB ingested, 70.5 MiB on disk · record
Stored for a repeated 320 KiB context
2.5 MiB3144.4 MiB ingested; identical payloads are stored once · record
Measured by the engine’s bundled harnesses on macos/aarch64, 10 available hardware threads, under ambient desktop load, not an idle host, against synthetic corpora. A run that
misses its acceptance gate writes no record. Workload-specific measurements, not capacity guarantees, and not a
Traza Cloud service level.
The 320 KiB case is the best case for content addressing, shown because agents resend long contexts; ordinary spans
look like the first two storage rows.
Pricing
Priced by spans. Never by seat.
Foresight, Steer, X-Ray, Replay and Guard are on every plan. No export or egress fees, and export stays on even
when you are capped or unpaid. At the cap, ingest pauses; reads keep working and nothing is deleted early.
Free
$0forever
Everything the engine does, hosted. For side projects and first agents.