harness-evaluator
Harness evaluator: compare agentic coding harnesses (Claude Code, Codex, Pi, OpenCode, OMP) on token efficiency, task effectiveness, and time efficiency.
See DESIGN.md for the full design specification and the docs site for comprehensive documentation.
Quick start
No clone required — harness-evaluator bundles its task library and publishes to PyPI as harness-evaluator:
uvx harness-evaluator init # scaffold harness-evaluator.yaml
docker pull ghcr.io/yorch/harness-evaluator-runner:latest # pull the runner image
export ANTHROPIC_API_KEY=sk-ant-...
uvx harness-evaluator gateway --port 8877 # separate terminal
uvx harness-evaluator run harness-evaluator.yaml
Install uv first if you don't have it: curl -LsSf https://astral.sh/uv/install.sh | sh
You can also install with pip install harness-evaluator or uv tool install harness-evaluator.
From source
# 1. Install dependencies
uv sync --extra dev
# 2. Pull the pre-built Docker image (or build locally with: docker build -t harness-evaluator-runner:latest .)
docker pull ghcr.io/yorch/harness-evaluator-runner:latest
# 3. Set API keys
export ANTHROPIC_API_KEY=sk-ant-...
export OPENAI_API_KEY=sk-...
# 4. Start the gateway proxy (in a separate terminal)
harness-evaluator gateway --port 8877
# 5. Run a minimal evaluation (1 harness, 1 model, 1 task, 1 repeat)
harness-evaluator run runs/sample-minimal.yaml
# Or dry-run to see the matrix without executing
harness-evaluator run runs/sample-minimal.yaml --dry-run
# Curated 20-task mix (5 harnesses × 2 models × 20 tasks × 3 repeats = 600 cells)
harness-evaluator run runs/task-mix.yaml --dry-run
Docker image
The runner executes harnesses inside an isolated Docker container. A pre-built image is available on GHCR (recommended), or you can build locally:
# Pull the pre-built image (recommended)
docker pull ghcr.io/yorch/harness-evaluator-runner:latest
# Or build locally
docker build -t harness-evaluator-runner:latest .
M1: Gateway Proxy (completed)
The gateway proxy is a custom HTTP/SSE server that sits between a harness and the provider API, capturing every call's token usage, cost, and latency.
See docs/gateway-proxy.md for a detailed explanation with architecture diagram, token parsing, storage schema, and configuration reference.
Running the proxy
harness-evaluator gateway --port 8877
Configure harnesses to route through the proxy:
export ANTHROPIC_BASE_URL=http://127.0.0.1:8877
export OPENAI_BASE_URL=http://127.0.0.1:8877
Running the canary
After sending a request through the proxy, verify token capture accuracy:
harness-evaluator canary --tolerance 1.0
What the proxy captures
- Token usage: input, output, cache-read, cache-write, reasoning tokens
- Cost: calculated from a pricing table per model
- Latency: wall-clock time per API call
- Full request/response: headers and bodies stored in SQLite
- Streaming support: real-time SSE parsing for both Anthropic and OpenAI
Observability tiers
- full: open harness, all metadata captured
- partial: closed harness, provider traffic captured via proxy
- minimal: closed harness, only total spend via billing API
Reconciliation
Token usage from proxy, billing API, and harness self-report are reconciled with per-harness tolerance bands. Discrepancies are flagged as a transparency metric.
M2: Core Pipeline (completed)
The core pipeline handles eval matrix building, execution, and reporting.
Running an eval
# Dry run (print the matrix without executing)
harness-evaluator run runs/sample-run.yaml --dry-run
# Execute the eval
harness-evaluator run runs/sample-run.yaml
# Generate reports
harness-evaluator report broad-first-pass --output ./reports
# View results in console
harness-evaluator results broad-first-pass
Run configuration
Eval runs are configured via YAML files (see runs/sample-run.yaml):
harnesses: list of harness specs (name, adapter, observability tier)models: list of model specs (name, provider, API key env var)tasks: list of task IDs or*for all tasks in the libraryrepeats: number of repeats per cell (default 5)budget_usd: maximum total spend (optional)parallel_runs: number of parallel container runs (default 1)
Task definitions
Tasks are defined as YAML files in a task library directory (see tasks/):
track:swe(hidden tests) oropen_ended(LLM judge)task_prompt: the prompt given to the harnesstest_command: command to run teststest_patch: hidden test patch applied before evaluationtimeout_seconds: per-task timeout
Features
- Matrix building: harness × model × task × repeat
- Budget caps: stops when $ budget exhausted
- Cell-level resumability: skips completed cells on re-run
- Retry logic: transient failures retried with exponential backoff
- Exit classes: PASS, FAIL, RETRYABLE_KILL, NON_RETRYABLE_KILL
- Partial credit: fraction of tests passing
- Error classification: success, partial, overfit, timeout, refusal, wrong_approach, crash, no_change
- Reports: HTML, JSON, CSV with within-model leaderboards
M3: Harness Adapters (completed)
Adapters wrap each coding harness with a uniform interface for the runner.
Supported harnesses
| Harness | Adapter | Observability | Notes |
|---|---|---|---|
| OpenCode | opencode |
full | Open-source, system prompt visible |
| Claude Code | claude-code |
partial | Closed, proxy captures traffic |
| Codex | codex |
partial | Closed, proxy captures traffic |
| Pi | pi |
minimal | May bypass proxy |
| OMP | omp |
minimal | May bypass proxy |
Listing adapters
harness-evaluator adapters
Observability tiers
- full: Open/cooperating harness. System prompts, tool definitions, context strategy, and turn-level metadata are available.
- partial: Closed harness but provider traffic is captured through the gateway proxy. Token usage and cost are accurately attributed.
- minimal: Only total spend or billing data is available. Traffic may bypass the proxy. Cost accounting relies on billing reconciliation.
Adapter design
Each adapter implements:
prepare(): Check/install the harnessrun(task_prompt, timeout): Execute the harness non-interactivelycleanup(): Clean up after the runget_env(): Set gateway proxy env vars and API keys
The adapter registry (harness_evaluator.adapters.registry) loads adapters by name and
the Docker runner uses it to dispatch to the correct adapter based on the
run config's harness.adapter field.
M4: Open-Ended Track (completed)
The open-ended track evaluates tasks without a single correct answer using a frozen LLM judge, structured rubric, and structural checks.
Components
- Frozen Judge (
FrozenJudge): Versioned LLM judge with an immutable prompt. Versionv1.0is the initial frozen prompt. Changing the prompt requires bumping the version, which invalidates prior calibration data. - Rubric (
Rubric): Weighted criteria with 0-5 scoring scale. Default rubric includes correctness (3x), completeness (2x), code_quality (1.5x), test_quality (1.5x), documentation (1x). - Structural Checks (
StructuralChecker): Verifies file existence, Python syntax, and test command execution. Structural failures cap the composite success at 0.5. - Calibration (
CalibrationSet): Anchor submissions with known expected scores for drift detection. Mean absolute error > 0.15 flags drift.
Running calibration
export ANTHROPIC_API_KEY=sk-ant-...
harness-evaluator calibrate --model claude-sonnet-4-20250514
Evaluation flow
- Get git diff of changes
- Run structural checks (file existence, syntax, tests)
- Run LLM judge against rubric
- Composite score: judge score, capped at 0.5 if structural checks fail
- Pass threshold: 0.7
M5: Dashboard (completed)
Interactive FastAPI web dashboard for exploring eval results.
Starting the dashboard
harness-evaluator dashboard --port 8080
Then open http://127.0.0.1:8080 in your browser.
Features
- Run overview: List all runs with summary stats (cells, passed, failed, cost)
- Run detail: Per-run view with leaderboards and filtered results table
- Filtering: Filter by model, harness, task track, and minimum success rate
- Leaderboards: Within-model harness comparison sorted by success rate
- REST API: JSON endpoints for programmatic access:
GET /api/runs— list all runsGET /api/run/{name}— get filtered resultsGET /api/run/{name}/leaderboard— get leaderboard data
M6: Statistics (completed)
Statistical analysis of evaluation results, including mixed-effects modeling, variance decomposition, bootstrap confidence intervals, and consistency analysis.
Running stats
harness-evaluator stats my-run --db harness_evaluator_results.db
Components
- Mixed-Effects Model:
success ~ C(harness) + C(model) + (1|task)Treats harness and model as fixed effects, task as a random effect. Reports coefficients, standard errors, p-values, and confidence intervals. - Variance Decomposition: Partitions variance into harness, model, task, and residual components. Reports percentage of total variance explained.
- Bootstrap CIs: Non-parametric bootstrap confidence intervals (default 1000 resamples, 95% CI) for success rate by harness.
- Consistency Analysis: Per harness × model combination, reports mean, std, coefficient of variation, min/max success, and bootstrap CI.
- Warnings: Automatically warns when sample size is too small (<30) or when the mixed-effects model fails to converge.
Architecture
- Gateway: custom HTTP/SSE proxy that intercepts provider calls and captures token usage, cost, and latency with full request/response logging.
- Orchestrator: builds the eval matrix (harness × model × task × repeats), manages budget caps, and handles cell-level resumability.
- Runner: Docker-based isolation, one container per eval cell.
- Adapters: per-harness integration (Python core + TS shims where needed).
- Evaluator: SWE-bench-style (hidden tests) and open-ended (LLM judge) tracks.
- Reporting: CLI reports + static HTML + interactive web dashboard.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file harness_evaluator-0.3.0.tar.gz.
File metadata
- Download URL: harness_evaluator-0.3.0.tar.gz
- Upload date:
- Size: 102.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec32dcf60c4634982477705aa6a6d8660810f48890f2fb9663fb81f9561f2ff6
|
|
| MD5 |
45979251e3659ef06fba199eb5c1affe
|
|
| BLAKE2b-256 |
92f108f6b7bc685ed15a9e50dd9842d5386958ed462e07388cc4df8b11f58e27
|
Provenance
The following attestation bundles were made for harness_evaluator-0.3.0.tar.gz:
Publisher:
publish.yml on yorch/harness-evaluator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
harness_evaluator-0.3.0.tar.gz -
Subject digest:
ec32dcf60c4634982477705aa6a6d8660810f48890f2fb9663fb81f9561f2ff6 - Sigstore transparency entry: 2657293129
- Sigstore integration time:
-
Permalink:
yorch/harness-evaluator@6d1cd098f607753e2008021097165781d4d1a5ab -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/yorch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6d1cd098f607753e2008021097165781d4d1a5ab -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file harness_evaluator-0.3.0-py3-none-any.whl.
File metadata
- Download URL: harness_evaluator-0.3.0-py3-none-any.whl
- Upload date:
- Size: 149.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9127bc154b8b7dde50d996dd59938ffb8c6564c18d58064018e4240407ba5139
|
|
| MD5 |
45784c028a929c987b2a47be1c98ae45
|
|
| BLAKE2b-256 |
28ed5e21695a815ed40d682791a2c0a1015a92320fbae0acc13f2bd60b4b3c83
|
Provenance
The following attestation bundles were made for harness_evaluator-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on yorch/harness-evaluator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
harness_evaluator-0.3.0-py3-none-any.whl -
Subject digest:
9127bc154b8b7dde50d996dd59938ffb8c6564c18d58064018e4240407ba5139 - Sigstore transparency entry: 2657293154
- Sigstore integration time:
-
Permalink:
yorch/harness-evaluator@6d1cd098f607753e2008021097165781d4d1a5ab -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/yorch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6d1cd098f607753e2008021097165781d4d1a5ab -
Trigger Event:
workflow_dispatch
-
Statement type: