.bench/

Generated output. Created by axon bench prepare and the runner; never edit anything inside it.

.bench/
├── runs/          # one directory per run: events, manifest, result, artifacts
├── workspace/     # materialized worlds, retained per the config's policy
├── bench.d.ts     # typed globals — observe() and bench.axis() autocomplete
├── schema.json    # the measurement schema, extracted from your Schema type
└── tsconfig.json  # so your editor sees the generated globals

bench.d.ts

Written from bench.config.ts and your Schema type. It is what makes the authoring surface typed:

observe("resolved", true)        // checked against Schema
observe("resolvd", true)         // compile error
bench.axis("model")              // narrows to your declared variations

Regenerated by axon bench prepare. Commit it — a benchmark someone clones should type-check before they run anything.

schema.json

The measurement schema as a value: ids, kinds, descriptions, objectives.

A TypeScript type vanishes at compile time, and two things need the schema at runtime. Coverage can only report expected four measurements, observed three if it knows the fourth exists. And results enter a shared aggregate only when their schemas match, which requires something hashable. The extraction happens once, at prepare, and the manifest carries the result.

runs/

One directory per run, holding the raw event log, the manifest, the derived result, and any attached artifacts.

The log is the source of truth. A result is a projection over it, which is why axon bench result <run-id> can rebuild one months later without re-running anything — same log, same projection, same numbers.

workspace/

The materialized worlds runs execute in, kept according to workspace.retain.

By default only failed trials' worlds survive. When something goes wrong, the world it went wrong in is usually more informative than any measurement about it: the half-applied patch, the file that should not have been touched, the dependency that got installed.

Committing

Commit the declarations. Ignore the runs — they are machine-specific, occasionally large, and reproducible from the log anyway.

.bench/runs/
.bench/workspace/

axon bench init writes that .gitignore for you.