hetu

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2026 License: Apache-2.0

README

hetu

Record, replay, and fork any AI agent run. hetu is rr for agent runs: it turns an agent execution into a permanent, reproducible, forkable artifact — a run journal — then re-runs it offline, deterministically, with zero tokens.

By Avartan Labs. Apache-2.0.

hetu replaying a recorded agent run offline


Why

An agent run is one of the least reproducible things in software. It reaches out to a model, runs tools against a moving filesystem, and never happens the same way twice — so when it goes wrong, you can't re-run it, can't see where the bad information entered, and can't test a fix without paying for a whole new run and hoping it diverges the same way.

hetu treats a run as what it is: a process tree exchanging bytes with the world. It captures every source of non-determinism the agent touches — model calls, tool traffic, workspace changes — into an append-only, content-addressed journal, with zero changes to the agent's code. From that journal it can:

  • replay the run offline, serving the recorded inputs back at the boundary — no network, no API key, no tokens — and report the exact step of any divergence;
  • fork the run: rewind to step N, change exactly one thing (a tool result, a model response, a file), and continue live from there — a controlled counterfactual, not a restart.

The journal is the product. It's designed to be the WARC/HAR of agent runs: an open, versioned interchange format (HRF — see docs/format.md) that a smarter reader can re-interpret next year.

Lineage: rr, WARC, git, the write-ahead log, and VCR cassettes.

Try it now — offline, no API key

Every release ships a bundled, redacted fixture run so you can see replay work with zero setup. Install the binary (or go install, below), then:

$ hetu --data-dir ./fixtures runs list
RUN                                          STARTED               STATUS     STEPS  LLM  TOKENS(in/out)
20260719T091713Z-01KXWTMNBRTZSFV9A9P4PVJBWM  2026-07-19 09:17:13Z  completed  11     3    1560/140

$ hetu --data-dir ./fixtures replay 20260719T091713Z-01KXWTMNBRTZSFV9A9P4PVJBWM
run 20260719T091713Z-01KXWTMNBRTZSFV9A9P4PVJBWM
  agent   claude-code unknown
  status  completed
  stats   3 llm calls, 2 tool calls, 1560/140 tokens (in/out)

[2] llm_call  claude-sonnet-5
    → user: The calculator tests are failing. Please fix the bug.
    ← assistant: Let me run the tests to see what is failing.
    ← tool_use bash {"command":"python -m pytest -q"}
[3] tool_use  bash
[5] llm_call  claude-sonnet-5
    ← assistant: add() subtracts instead of adding. Fixing calc.py.
    ← tool_use str_replace {"path":"calc.py"}
[8] llm_call  claude-sonnet-5
    ← assistant: Fixed the bug in add(); the tests pass now.

That replay touched no network and no credentials — the model responses came from the recording. The fixture is generated against an in-repo fake server (no key, ever) and a planted test secret is redacted on capture; verify it yourself:

$ hetu --data-dir ./fixtures redact-check 20260719T091713Z-01KXWTMNBRTZSFV9A9P4PVJBWM
clean: no secrets found

The exact run id is printed by runs list — copy it from there. See fixtures/ for how the fixture is made and what it does and doesn't contain.

Record your own run

hetu launches the agent as a child process with its API base URL pointed at a local proxy (no TLS interception, no CA — plain HTTP to localhost). Everything the agent sends flows through, recorded as raw bytes; credentials pass upstream but are never written to disk.

# Claude Code (the first supported agent)
$ hetu record -- claude -p "make the tests pass"

# any OpenAI-compatible agent (network-only capture)
$ hetu record --agent openai -- python my_agent.py

$ hetu runs list
$ hetu show <run>            # render the trajectory
$ hetu replay <run> --verify # re-run offline in a fresh worktree, report reproduction

--verify restores the recorded workspace into a fresh worktree (never your live directory), relaunches the real agent against a replay proxy that serves recorded responses offline, and prints a repro reportN/M exchanges reproduced, and on divergence the exact seq plus a diff of the request that differed. A match miss never falls through to a live API; it stops and shows you why.

Fork a run

# rewind to step 7, correct a poisoned tool result, continue live
$ hetu fork <run> --at 7 --edit
$ hetu diff <parent> <child>          # step-aligned trajectory + workspace diff
$ hetu diff <parent> <child> --outcome=fixed --hypothesis "add() was subtracting"

A fork copies the parent's history up to the fork point (parents are immutable), applies your one edit, restores the workspace, and continues live from there into an isolated child run. Because continuing spends real tokens, a fork stops before going live unless you pass --live or confirm at the prompt — it never surprise-bills you. Confirming an outcome records a verification event (hypothesis → patch → result), the label at the heart of hetu's verification flywheel.

Install

Install script (Linux / macOS). Downloads the release binary for your platform, verifies its SHA-256 against the release checksums, and installs to ~/.local/bin (no sudo):

curl -fsSL https://raw.githubusercontent.com/avartan-labs/hetu/v0.1.0/scripts/install.sh | sh

Pin a version or change the location:

curl -fsSL https://raw.githubusercontent.com/avartan-labs/hetu/v0.1.0/scripts/install.sh \
  | HETU_VERSION=v0.1.0 HETU_INSTALL_DIR=/usr/local/bin sh

Prefer not to pipe to a shell? Download the archive and checksums.txt for your platform from the releases page, verify with sha256sum -c, and move the hetu binary onto your PATH. See scripts/install.sh — it does exactly that.

From source (Go 1.22+):

go install github.com/avartan-labs/hetu/cmd/hetu@latest

What it captures, honestly

hetu models non-determinism as five channelsnetwork, filesystem, clock, randomness, ipc — and every run declares a determinism contract per channel: serve-recorded, reexecute-verify, live, or unrecorded.

v1 records network fully (every model exchange, byte-for-byte) and filesystem via per-run shadow-git snapshots (for agents with hook support, like Claude Code). The other channels are carried in the schema but not yet captured — and an unrecorded channel is an honest hole that lowers a run's declared fidelity, never a silent lie. A network-only agent (e.g. the openai recipe) records the network channel and leaves filesystem an honest hole.

Two limitations worth stating plainly:

  • Replay re-executes tools. In --verify, the replayed prefix re-runs the agent's tools in the restored workspace, so mid-run untracked state reflects re-execution. Shadow-git restore covers tracked-file state, which dominates for coding agents.
  • Scrub rules are empirical. Matching a replayed request to a recording requires canonicalizing away volatile spans (timestamps, cwd, ids). The ruleset starts good and improves one discovered field at a time; reproduction rate is tracked in CI.

Every run also carries a consent_tier (private by default) and provenance metadata — schema from day one, never an afterthought. There is no telemetry.

How it's built

hetu is a single static binary — no daemon, no database, no container, no network dependency to record. All provider and framework knowledge lives in versioned lenses applied at read time, never at write time; the journal stores raw bytes. Adding a second provider (the M5 openai-chat lens + openai agent) required zero changes to the storage format or replay engine — a claim mechanically enforced in CI.

  • docs/format.md — the HRF on-disk format, implementable from the doc alone.
  • docs/architecture.md — the system model, interception ladder, and design.
  • docs/dogfood.md — recording and forking a real run end-to-end.
  • demo/ — the full record → replay → fork → diff story (needs your own API key to run live).

License

Apache-2.0 — the recorder, format, lenses, and local replay/diff/fork are open source, permanently. See LICENSE.

Directories

Path Synopsis
cmd
hetu command
Command hetu records, replays, and forks agent runs.
Command hetu records, replays, and forks agent runs.
internal
canon
Package canon canonicalizes recorded and live requests to a stable form and matches a live request stream against a recording (CLAUDE.md §7).
Package canon canonicalizes recorded and live requests to a stable form and matches a live request stream against a recording (CLAUDE.md §7).
cas
Package cas implements a chunked, content-addressed store (CAS).
Package cas implements a chunked, content-addressed store (CAS).
cli
Package cli holds the cobra command tree (M1+); nothing depends on it.
Package cli holds the cobra command tree (M1+); nothing depends on it.
control
Package control is the recorder's single-writer command channel (M2).
Package control is the recorder's single-writer command channel (M2).
diffview
Package diffview renders human-readable diffs for divergence and repro reports (CLAUDE.md §7, §8).
Package diffview renders human-readable diffs for divergence and repro reports (CLAUDE.md §7, §8).
eventlog
Package eventlog implements the hetu run format (HRF v0.1): the manifest, the append-only event log, the event envelope, and the crash-recovering reader.
Package eventlog implements the hetu run format (HRF v0.1): the manifest, the append-only event log, the event envelope, and the crash-recovering reader.
fakeapi
Package fakeapi is a test-only fake Anthropic Messages server used by integration tests.
Package fakeapi is a test-only fake Anthropic Messages server used by integration tests.
fork
Package fork implements lineage, patch tables, and the live flip (M4).
Package fork implements lineage, patch tables, and the live flip (M4).
lens
Package lens is the registry over versioned journal interpreters; provider lenses land later (M1+).
Package lens is the registry over versioned journal interpreters; provider lenses land later (M1+).
lens/anthropicmessages
Package anthropicmessages is the protocol lens for the Anthropic Messages API.
Package anthropicmessages is the protocol lens for the Anthropic Messages API.
lens/claudecode
Package claudecode is the Claude Code launch-recipe lens.
Package claudecode is the Claude Code launch-recipe lens.
lens/openai
Package openai is the launch-recipe lens for a generic OpenAI-API agent.
Package openai is the launch-recipe lens for a generic OpenAI-API agent.
lens/openaichat
Package openaichat is the protocol lens for the OpenAI Chat Completions API (POST /v1/chat/completions).
Package openaichat is the protocol lens for the OpenAI Chat Completions API (POST /v1/chat/completions).
proxy
Package proxy is the rung-1 interceptor: record/replay/fork modes, protocol-agnostic (M1+).
Package proxy is the rung-1 interceptor: record/replay/fork modes, protocol-agnostic (M1+).
redact
Package redact scrubs known secret patterns from stored payloads (M1).
Package redact scrubs known secret patterns from stored payloads (M1).
replay
Package replay re-executes a recorded run with recorded inputs served back at the boundary (CLAUDE.md §8).
Package replay re-executes a recorded run with recorded inputs served back at the boundary (CLAUDE.md §8).
snapshot
Package snapshot manages shadow-git workspace snapshots, a derived layer (M2).
Package snapshot manages shadow-git workspace snapshots, a derived layer (M2).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL