Skip to main content

commitarena

CI License: MIT Release Stars

Your git history is the benchmark. Replay real bug fixes against any model, in a sandbox with no network.

Español · Example report

commitarena demo in a terminal

commitarena mines commits from your repository where a bug fix came with a test, checks in Docker that the test fails without the fix and passes with it, and then asks each model to make that test pass. Every model gets the same small agent loop with one bash tool, and every command it runs executes in a container started with --network none. The report splits the pass rate into fixes committed before and after each model's training cutoff, so you can see whether a model solves the bug or remembers the patch.

Why

There are good tools close to this. What I wanted and did not find in one place:

What it does Difference
sjarmak/codeprobe (10 stars) Mines merged PRs, runs agent CLIs, ranks with cost and an HTML report. Its README says each agent runs "inside a --network=bridge container (the agent needs the model API)". In commitarena the model is called from the host and the code the model writes never has a network.
PozziTiv4ik/Repo-Trials (0 stars) FAIL_TO_PASS tasks from your git history. commitarena adds the same harness for every model, local ones included, and the before/after-cutoff split.
harbor-framework/harbor (6,755 stars) A general framework for agent evaluations. commitarena is one command for one question: which model fixes the bugs of this repo.

Star counts from the GitHub API on 2026-11-03.

Three things commitarena does on purpose:

  1. No network for model-written code. The agent loop runs on your machine and only sends chat requests. Each bash call goes through docker exec into a container with --network none, --cap-drop ALL, no-new-privileges, 2 CPU, 2 GB, a PID limit and a per-command timeout.
  2. One harness for every model. Same system prompt, same single tool, same step and time limits, whether it is a hosted model or a 4B model on Ollama. No vendor agent, no extra tools.
  3. Solve or remember. Public repos are in training data. The report shows pass rate on fixes dated before each model's cutoff next to fixes dated after it. Cutoffs are configurable; by default the model's release date is used, which is a safe upper bound.

Quickstart

The demo needs no API keys and no Docker. It prints a recorded run and writes the HTML report.

uvx --from git+https://github.com/diegoperezg7/commitarena@v0.1.1 commitarena demo

Or from a clone:

git clone https://github.com/diegoperezg7/commitarena && cd commitarena && uv run commitarena demo

uvx commitarena is coming to PyPI.

Example output

$ commitarena demo
Recorded result (not a live run): 2026-11-03, commitarena 0.1.0, models mistral/codestral-latest,
mistral/ministral-8b-latest, mistral/mistral-large-4, on Darwin arm64 (Apple M4, 16 GB RAM).
Repo: https://github.com/andialbrecht/sqlparse (BSD-3-Clause)
Leaderboard
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━┓
┃ model                       ┃  pass ┃ rate ┃ before cutoff ┃ after cutoff ┃ cost $ ┃    tokens ┃ avg s ┃ avg steps ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━┩
│ mistral/mistral-large-4     │ 11/11 │ 100% │           8/8 │          3/3 │ 0.5401 │   672,848 │   118 │      11.1 │
│ mistral/ministral-8b-latest │  1/11 │   9% │           0/5 │          1/6 │ 0.2445 │ 1,630,017 │    68 │      28.3 │
│ mistral/codestral-latest    │  0/11 │   0% │           0/4 │          0/7 │ 0.6507 │ 2,038,536 │    75 │      27.8 │
└─────────────────────────────┴───────┴──────┴───────────────┴──────────────┴────────┴───────────┴───────┴───────────┘

report

How to read it: with the same prompt, tool, limits and sandbox, Mistral Large 4 fixed all 11 bugs, including the 3 committed after its release (October 2026), so it was solving, not recalling. Ministral 8B fixed one, and that one is dated after its own cutoff. Codestral fixed none. Three tasks after a cutoff is a small sample: treat the split as a signal, not a verdict.

Why Codestral scores 0/11. It is the model, not the scoring: it repeated an earlier command verbatim in 170 of its 304 tool calls, kept doing so after 163 "you already ran this exact command" notices from the harness, ran out of its 30 steps in 9 of 11 attempts, left the code untouched in 6, and never edited a test file. This is the start of the PRIMARY KEY task, whose human fix is one regex line in sqlparse/keywords.py (full trajectories are in docs/demo-run/trajectories):

12 grep -n 'PRIMARY' sqlparse/keywords.py
13 sed -n '440,450p' sqlparse/keywords.py
14 sed -n '440,450p' sqlparse/keywords.py      <- repeat notice
15 grep -n 'KEY' sqlparse/keywords.py
...
23 grep -n 'PRIMARY' sqlparse/keywords.py      <- repeat notice
24 sed -n '440,450p' sqlparse/keywords.py      <- repeat notice
25 grep -n 'KEY' sqlparse/keywords.py          <- repeat notice

Use it on your repo

You need Docker running, plus Ollama or an API key.

# 1. Mine tasks: commits that change source and tests, validated in Docker
commitarena mine https://github.com/you/yourrepo --max-tasks 10

# 2. Run models (a local one and a hosted one)
export MISTRAL_API_KEY=...
commitarena run --tasks tasks/you-yourrepo/tasks.json \
  --models ollama/qwen3:4b-16k,mistral/codestral-latest --max-cost 1

# 3. The report is written to runs/<timestamp>/report.html; re-render it with other cutoffs
commitarena report runs/<timestamp> --cutoff mistral/codestral-latest=2025-07-31 --open

How it works

flowchart LR
  subgraph host[Your machine]
    G[git history] --> M[mine: commits touching src + tests]
    M --> V{Docker, no network:<br/>new tests fail before,<br/>pass after?}
    V -->|yes| T[tasks.json<br/>failing tests + test diff<br/>no commit message]
    T --> L[agent loop<br/>one bash tool]
    L <-->|chat API| P[(model provider<br/>or Ollama)]
  end
  L -->|docker exec| S[sandbox<br/>--network none<br/>2 CPU, 2 GB]
  S --> R[copy out the workspace]
  R --> X[keep non-test changes only,<br/>restore original tests]
  X --> Y[fresh no-network container:<br/>full test suite]
  Y --> Z[report.html<br/>leaderboard, matrix,<br/>cutoff split, diffs]
  • Mining. Non-merge commits that change at least one test file and at least one .py source file (small fixes only by default). For each one the test suite runs twice in a no-network container: the parent commit plus the new test files, and the fix commit. A task is kept when some tests go from failing to passing (FAIL_TO_PASS) and nothing that passed before breaks (PASS_TO_PASS). The test image is built once per repo with your install command, which is the only step with network.
  • The prompt lists the failing tests, the test diff and the current failure output. The commit message, the issue and the human fix are never shown. The workspace gets a fresh one-commit git history so the real history cannot leak the fix.
  • Scoring. After the attempt the workspace is copied out. Only changes to non-test files are applied onto a pristine copy, so edits to tests or conftest.py are discarded, and the full suite runs in a fresh container. Pass means every FAIL_TO_PASS test passes and no PASS_TO_PASS test fails.
  • Metrics. Pass, cost (provider-reported for OpenRouter, otherwise tokens times list price; local models cost 0), input and output tokens, wall time and steps (model calls).

Configuration

Flag Default
run --models Comma-separated provider/model. Providers: openrouter, openai, mistral, ollama.
run --max-cost 1.0 USD. Checked before every model call; the run stops with partial results.
run --max-steps / --max-time 30 / 1200 Model calls and seconds per attempt.
run --cutoff MODEL=DATE release date Training cutoff used for the before/after split (repeatable).
run --price MODEL=IN,OUT built-in USD per million tokens for models without a known price.
run --context-file F Inject an AGENTS.md / CLAUDE.md: --context-mode both|repo|prompt.
run --strip-context-files off Remove the repo's own AGENTS.md / CLAUDE.md before the attempt.
run --cpus / --memory / --command-timeout 2 / 2g / 120 Sandbox limits.
mine --since / --until / --scan / --max-tasks Which commits to consider.
mine --python / --setup 3.12 / pip install -e . How the test image is built.

Environment variables: OPENROUTER_API_KEY, OPENAI_API_KEY, MISTRAL_API_KEY, OLLAMA_HOST, COMMITARENA_CACHE (clones, default ~/.cache/commitarena). See .env.example. There is no telemetry.

Ollama context window. Ollama's OpenAI-compatible endpoint ignores num_ctx, and its default window can be 4096 tokens, which silently drops the task text and gives worse results. commitarena warns about it. Use a variant with num_ctx 16384 (the one used in development is qwen3:4b-16k); the agent loop elides older tool outputs to stay inside 16K.

printf 'FROM qwen3:4b\nPARAMETER num_ctx 16384\n' > Modelfile && ollama create qwen3:4b-16k -f Modelfile
commitarena run --tasks tasks.json --models ollama/qwen3:4b-16k

Local models go through exactly the same code path (qwen3:4b-16k was run during development), but it is not in the recorded demo. On this machine it spent every 4096-token reply reasoning and never called the tool, and its thinking could not be turned off through the OpenAI endpoint (think: false, reasoning_effort: "none" and /no_think were all tried). Raising the reply limit for one model would break the same-harness rule, so it was left out rather than shown with a misleading 0.

Python API

from commitarena import load_tasks, run_task, Budget, ContextFile

task = load_tasks("tasks.json")[0]
res = run_task(task, "ollama/qwen3:4b-16k", budget=Budget(max_cost=1.0),
               context=ContextFile(open("AGENTS.md").read(), in_repo=True, in_prompt=True))
print(res.passed, res.cost_usd, res.tokens_in, res.steps, res.wall_time_s)

Demo data

The recorded demo uses 11 tasks mined from sqlparse (BSD-3-Clause, Copyright (c) 2016, Andi Albrecht). The bundled files contain the failing tests, the test diffs and the upstream fixes as diffs, each linked to its commit. The upstream license is bundled verbatim in src/commitarena/demo/LICENSE-sqlparse.

Roadmap

  • Other languages and test runners
  • Claude Code and Codex as contestants
  • GitHub issue text as an optional prompt
  • pass@k and repeated attempts
  • Parallel runs
  • Export to Harbor

License

MIT. See LICENSE.

Metadata

Release files for commitarena 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for commitarena 0.1.1
File Size Uploaded Provenance Actions
commitarena-0.1.1.tar.gz 166.4 kB With provenance Details for commitarena-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for commitarena 0.1.1
File Interpreter ABI Platform Actions
commitarena-0.1.1-py3-none-any.whl Python 3 none any Details for commitarena-0.1.1-py3-none-any.whl

Total release size: 329.0 kB

Release files / commitarena-0.1.1.tar.gz

Download URL commitarena-0.1.1.tar.gz
Size 166.4 kB
Tags Source
SHA-256 checksum
How to use checksums
0f3cc1d4597c14cd612144b84d40d166b047d2afed335e2e36a32c000f96bd3b
BLAKE2b-256 checksum
How to use checksums
b934b04dbadd30e7d1e761cb60f4eca4374ee09b606859759cca42e7f3ef5f17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Release files / commitarena-0.1.1-py3-none-any.whl

Download URL commitarena-0.1.1-py3-none-any.whl
Size 162.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fdc976f64a451b19aa5639207786ecb6820857c46a4b52f521ce29081f23fb9a
BLAKE2b-256 checksum
How to use checksums
0276b4d80462e48f496e2f8ba346c0514c234628364df9a491e39d6de106142a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Security for commitarena 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for commitarena-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page