Eval
July 14, 2026 · View on GitHub
This directory reproduces, with measurements, the experiment behind
RTK's README savings table. RTK models a
30-minute agent session and estimates per-operation token savings
("Estimates based on medium-sized TypeScript/Rust projects"). Here the same
class of operations is captured live and counted: every number in the
ClawCodex README's /eco section comes from replaying real command outputs
through the production compression pipeline.
Layout
eval/eco/
├── capture_corpus.py # runs real commands, stores full outputs (stdlib-only)
├── measure.py # replays corpus through src/eco, counts tokens
├── corpus/ # gitignored — machine-specific captured outputs
└── results/ # committed — results.md, results.json, examples/
Method
-
Capture (
capture_corpus.py). 27 operations an agent actually runs:- Test runners:
pytest/pytest -v(failing + green),go test [-v] ./...(failing),npx jest(failing + green), plus a green slice of this repo's own suite. Failing runs come from small sample projects written into--workdirwith genuine bugs (off-by-one, in-place mutation, wrong error message) so the tracebacks,--- FAILblocks, and assertion diffs are real tool output — RTK's own "never synthetic" fixture rule. - Package managers:
npm install jest,pip install flaskinto a fresh venv (--no-cache-dirso the Collecting/Downloading ceremony is real). - Git:
clone --no-local --progressof this repo, dirty + cleangit status,commit,push --progressto a local bare remote. - Repo-scale reads:
git log(full + oneline),git diff v1.0.0..v1.1.0,ls -R src,find,cata 900-line file, twogrep -rnsweeps (one under, one over the 400-line head-cap threshold). - Logs:
log show --last 90s --style syslog(macOS unified log; ~35k lines, varies by run). - Small outputs:
docker ps,wc -l, cleangit status— passthrough rows that must come back byte-identical.
- Test runners:
-
Measure (
measure.py). Each item is replayed through the production path, byte-for-byte what the Bash tool does when/ecois on:baseline = _assemble_bash_body(truncate_output(stdout), truncate_output(stderr)) outcome = compress_bash_output(command, exit_code, full_text, baseline, tee_dir)baselineis exactly the model-bound text without eco (including the pre-existing 30k-char truncation), and both renderings get the mapper'sreturnCodeInterpretationsuffix, so the counted text is the wire content. The eco text includes the recovery-hint line, so its token cost is charged honestly — for the committed run, the bench tee path tokenizes no shorter than a typical production~/.clawcodex/...hint, so its published savings are, if anything, slightly understated. Tokens are tiktokencl100k_basecounts (RTK reports chars/4 estimates; we compute those too, intoresults.json, but headline numbers are real tokenizer counts). The never-worse invariant is asserted over the whole corpus, and tee-filename entropy (time_ns, pid) is pinned so reruns on an unchanged corpus are byte-identical. -
Project —
results.mdalso recomputes RTK's 30-minute-session table with our measured ratios: rows whose assumed per-call size sits below eco's thresholds (a ~200-tokenls, a ~2,000-tokencat) map to 0% because eco passes them through;git add/commit/pushapplies the measured push ratio to the push share (3 of 8 calls) only. That projection is deliberately conservative — the corpus table is the measured result.
Reproduce
python3 eval/eco/capture_corpus.py --workdir /tmp/eco-bench
.venv/bin/python eval/eco/measure.py # needs tiktoken (repo venv has it)
capture_corpus.py needs git, and captures what it can find: go, npm,
docker (daemon up), and macOS log rows are skipped when unavailable.
--python points at a python that can import pytest (defaults to the repo
venv). Outputs are machine-specific — sizes and therefore percentages will
vary a few points from the committed results/ run; the invariants (never
worse, failures survive) hold everywhere.
Caveats, honestly
- The corpus is fat-tail weighted by design: it includes the big outputs (repo-scale listings, a failing suite, a system log) that dominate real context spend, alongside 8 passthrough rows. The per-operation table is the primary result; the -80% corpus total describes this mix, not every session.
- The
git clone/git pushrows are captured with--progress(as agents often run them for visibility); a plain non-TTY push emits far less ceremony. Those two rows contribute ~13k baseline tokens — dropping both still leaves the corpus total around -77%. cargo testisn't captured (no local Rust toolchain); the RTK-model projection maps itscargo test / npm testrow to the measured jest ratio.- Percentages for the same operation differ run to run (system-log volume, npm registry noise, repo growth) — regenerate before quoting new numbers.