AI agent tooling · C++23
Khonsu
Undo for AI agents. Record any agent once. Replay it bit-exactly with the model switched off. Fork a new future from any call. Works with every framework, and ships on PyPI and npm.

- 24 / 24
- replays identical to the recorded run, with the model server switched off
- 1.3 ns
- to fork 64 MiB of state, vs 8.5 ms for a deep copy
- 76%
- of tokens served from the recording after editing the last prompt
- 34 ms
- for a later workspace snapshot of a 20,000-file repo
The problem
Agents are hard to debug because they never do the same thing twice. In a study on a real coding agent, the same task and prompt produced different code in 16 of 16 live re-runs, and tests flipped between pass and fail on 5 of 8 tasks.
Existing tools cover pieces. Tracing products show runs but can’t re-execute them, HTTP cassettes break on any prompt change, and framework checkpointers are tied to one framework and ignore the workspace.
Khonsu records at the HTTP boundary, so any agent that calls an OpenAI-compatible or Anthropic API works without code changes.
From a run to a recording you can travel through
- 01
Record
A local proxy captures each exchange. Every response is fdatasync’d before the agent can observe it.
- 02
Snapshot
The workspace is captured before every call as a Merkle tree, and only new objects are appended.
- 03
Match
Requests match on XXH3 of canonical JSON plus an occurrence count, so parallel calls replay in any order.
- 04
Replay or fork
Calls are served from the recording. A fork restores the files and goes live from call N.
- 05
Share
Merkle anti-entropy sync exchanges only what differs, and notes merge as CRDTs with no coordinator.
Results
- Differed from the recording
- 16 / 16
- Identical, model off
- 24 / 24
Real-agent study
| Measure | Result |
|---|---|
| Live re-runs that differed from the recording | 16 / 16 |
| Tasks where tests flipped between pass and fail | 5 / 8 |
| Replays identical with the model stopped | 24 / 24 |
| Tokens reused after editing the last prompt | 76% |
A function-calling coding agent on qwen2.5:3b via Ollama, 8 tasks.
Against the alternatives
| Comparison | Khonsu | Other |
|---|---|---|
| vcrpy: replay p50 | 1.12 ms | 3.77 ms |
| vcrpy: recording size | 186 KiB | 452 KiB |
| vcrpy: API key on disk | No | Yes |
| vcrpy: calls kept after kill -9 at call 30 | 30 | 0 |
| LangGraph: outcomes from 10 mid-run resumes | 1 | 10 |
| LangGraph: storage at 40 turns | 171 KiB | 2.1 MiB |
The engine
| Operation | Time |
|---|---|
| fork() of 64 MiB, persistent Merkle tree | 1.3 ns |
| Same fork, copy-on-write page table | 134 µs |
| Same fork, deep copy | 8.5 ms |
| First write to a page after a fork | ~2 µs |
| Log append | 15.9 M frames/s |
| Workspace snapshot of 20,000 files, first / later | 146 ms / 34 ms |
Reference run on Node 24, wasm32, on a laptop.
Key decisions
Durable before observable
If the agent saw a response, it’s in the recording. That includes the streaming terminal event, which is held back until it’s on disk.
Canonical JSON keeps its lexemes
Numbers keep their original form, so 0.10 is never rewritten as 0.1. Matching is order-independent.
One kernel, two targets
The same C++23 kernel powers the CLI and the website in WebAssembly, so a .khn file is parsed and verified identically in a terminal and a browser.
Secrets never reach disk
Authorization and API-key headers are stored only as <redacted>, and .env files and credentials are never captured in snapshots.
Tamper evidence
Every frame has a CRC32C and the end frame commits to a hash chain. One flipped bit fails verify, and a CRC-valid rewrite still breaks the chain.
What broke
A durability window in stream endings
A kill -9 test exposed how the OpenAI SDK ends streams. The terminal event is now held until it’s durable.
A replay bug in Khonsu itself
The study found that rerun tools returned fresh output, and pytest’s “passed in 0.03s” made 11 of 24 replays miss. The fix is pinned by a regression test.
A shutdown race
ThreadSanitizer caught a race in listener shutdown. Every suite runs under ASan, UBSan and TSan on every push.
What these numbers don’t prove
- Engine timings are from one reference laptop, and the benchmarks page re-runs them on the visitor’s device.
- The study used one local model on 8 tasks, so it demonstrates the behaviour without estimating it across all agents.
- The CLI runs on Linux, or Windows via WSL. macOS is on the roadmap.