joule-bench/README.md
David Charlot 712252b2a7 Add --rollouts N: the metered test-time-compute frontier (best-of-N)
Run N independent rollouts per (solver, task, pass) and report the best-of-k
frontier: for each k=1..N, the fraction of tasks resolved within the first k
rollouts paired with the cumulative dollars + cloud/local energy those k rollouts
spent. This is the resolution × energy × $ curve of test-time compute — the
trade no other harness meters. The recent literature shows best-of-N + rollout
selection lifts frontier agents ~7pp on SWE-bench Verified; this measures what
that lift costs in joules and dollars. TaskRun gains a rollout index;
test_time_frontier() aggregates best-of-k; render shows the curve.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-25 04:28:13 -04:00

3.3 KiB
Raw Permalink Blame History

joule-bench

A coding-agent benchmark that scores resolution rate and energy/cost together, producing a 2D Pareto frontier. Resolution is graded by an executable test oracle — the task's tests fail before the solver runs and must pass after — so the headline number is task success, not text similarity.

This is the harness behind the claim that Joule Code is SOTA "in the age of agents": not by out-accuracy-ing frontier models on raw resolution, but by resolving competitively at far lower joules and dollars, with the energy attested per op.

What it does

For each (task, solver):

  1. Seed a temp workdir with the task's pristine buggy tree (before/).
  2. Confirm the bug reproduces (baseline tests fail) — else the datapoint is flagged invalid.
  3. Bracket energy across the solver run.
  4. Restore pristine test files (anti-gaming: a solver cannot pass by editing the test).
  5. Grade: resolved iff the tests now pass.

Then aggregate per solver into frontier points: resolution %, joules per resolved task (total energy ÷ resolved, matching the EoC joules_per_correct metric), total joules, median wall time.

Solvers

  • reference — applies the task's known-good fix (reference/). The ceiling.
  • noop — touches nothing. The floor (proves the oracle rejects unfixed code).
  • claude — drives the claude CLI headlessly.
  • gemini — drives the gemini CLI headlessly.

The agent-joule cascade solver (driving the headless joule-coded worker over its control socket) and a SWE-bench Verified suite are the next increments.

Usage

cargo run -- run --suite smoke --solvers reference,noop --out results.json
cargo run -- report --results results.json

# Test-time compute: best-of-N rollouts per task → the metered resolution × energy × $
# frontier (more rollouts resolve more, at a measured cost — the trade nobody else meters).
cargo run -- run --suite mix --solvers claude --rollouts 3 --out ttc.json

Energy

Energy is captured through an EnergyMeter trait, selected with --energy:

  • measured — jouleclaw host counter (Apple IOReport ModelBased without sudo, Linux RAPL / NVML HwShunt), the same path agent-joule meters with. Idle whole-SoC power is calibrated once and subtracted (idle × wall) to isolate the solver's marginal energy.
  • estimator — wall-clock × active-watts, always labeled Estimator (a coefficient, never a measurement). Override with JOULE_BENCH_ACTIVE_WATTS.
  • auto (default) — measured if a host counter reads, else estimator.

Measurement floor (honesty). A whole-SoC counter cannot resolve work shorter than its minimum window (~10 ms for IOReport). Any run below that window is flagged ~ and reported as energy-unreliable: the resolution result stays valid, but the energy figure is noise-dominated and not comparable. Trivial solvers (reference, noop) finish in microseconds and are always flagged — real energy signal comes from multi-second agent runs (the claude/cascade solvers), where the solver's work dominates the window.

Tasks

A task is a directory under tasks/<suite>/<name>/:

task.toml      # name, prompt, test_cmd, test_files (restored before grading)
before/        # pristine buggy tree (source + tests), seeded into the workdir
reference/     # known-good fix, applied by the `reference` solver