PASR-Bench
A small, pre-registered protocol for measuring a code-context retriever, and the
harness that runs it. Packaged separately from pasr-mcp (pip install ./eval, distribution name pasr-bench). Results for PASR itself:
RESULTS.md and ../docs/competitors-benchmark.md.
What it measures
Real-agent run — four arms per task, each producing the same ArmResult:
- native_search — deterministic grep + read-files (stand-in for an agent's own tools)
- broad — the whole repo, source-first, truncated to a cap
- pasr —
select_contextat a fixed budget - pasr_fallback —
pasr, then one budget widening if confidence is low
A model answers each task from only that arm's context (UNKNOWN if absent); a
second model judges the answer against the task's expected identifiers;
critical_source_hit is still required. Metrics: task success, model input tokens
(incl. a flat per-tool-call overhead), round trips, critical-source miss rate, fallback
rate. Then a paired non-inferiority test of pasr / pasr_fallback vs the
baseline_arm at the plan's margin_task_success (point estimate + 10k-resample
bootstrap CI).
Bake-off — an offline, no-API retrieval comparison at a shared budget: grep,
repomap (aider-style signatures), embed_lex (a no-setup semantic floor), pasr,
pasr_hash, pasr_map. Scored on critical-file hit ∧ keyword coverage, split by task
kind.
No GPU. Arms run on CPU; the only model use is one answer + one judge call per
(task, arm) — ~400 Anthropic calls for the 50-task plan. Full Sonnet ≈ $12–15; a cheap
--model with a strong --judge-model ≈ $4–6.
Install & run
pip install ./eval # the pasr-bench distribution (deps: pasr-mcp)
pip install "./eval[llm,plots]" # + anthropic (real agent) + matplotlib (report.png)
pasr-bench plans # the packaged plan(s)
pasr-bench run --agent keyword # offline smoke: full matrix + report + validation
pasr-bench bakeoff --budget 6000 # offline retrieval bake-off
export ANTHROPIC_API_KEY=sk-ant-...
pasr-bench run --agent claude --max-tasks 4 # cheap trial (~$0.4)
pasr-bench run --agent claude \
--model claude-haiku-4-5 --judge-model claude-sonnet-5 \
--checkout-dir .eval-checkouts # budget-safe full run (~$4–6)
Each finished (task, arm) row is appended to matrix.jsonl and flushed, so a crash
keeps every completed row; --resume <run_dir> reloads the partial matrix and finishes
into the same delivery. --checkout-dir DIR reuses clones. PASR_EVAL_BROAD_CAP=30000
shrinks the broad arm. A run writes <out>/<plan>_<utc>/ with matrix.jsonl,
report.{json,md,png}, validation.json, resolved_commits.json.
python eval/run_eval.py … and python eval/bakeoff.py … still work as thin shims for
the two sub-commands.
Bring your own retriever
The protocol is retriever-agnostic. To measure a different context tool against the same 50 tasks and the same baselines:
- Add an arm in
pasr_eval/arms.py: extendARMSand add a branch in_build(...)that returns(context, sources, tool_calls, round_trips, fallback)for your retriever. Everything downstream — grading, metrics, non-inferiority, the validator — is arm-agnostic. - For a bake-off arm, add a function in
pasr_eval/bakeoff.pyand list it in that file'sARMS. - Keep the plan (
pasr_eval/plans/pilot.json) fixed so numbers stay comparable, or register a new plan and cite it.
The validator (validate_matrix) rejects synthetic rows, query→answer leaks, and an
unmatched task×arm matrix, so a submitted result is checkable.
Files
| Path | What |
|---|---|
pasr_eval/spec.py |
RepoSpec / TaskSpec / EvalPlan, load_plan; the leak + kind guards |
pasr_eval/arms.py |
the four real-agent arms → ArmResult |
pasr_eval/bakeoff.py |
the six offline bake-off arms |
pasr_eval/agents.py |
AgentRunner protocol, KeywordAgent (offline proxy) |
pasr_eval/llm_agent.py |
LlmAgent — answer + judge via the Anthropic API ([llm] extra) |
pasr_eval/metrics.py |
grade, aggregate, paired bootstrap CI, non-inferiority, full_report |
pasr_eval/runner.py |
resolve_repos, run_plan (skip= / on_row=), write_matrix |
pasr_eval/validate.py |
validate_matrix — no synthetic rows, no leaks, matched matrix |
pasr_eval/run.py |
end-to-end orchestrator: clone → streamed matrix → report → validate |
pasr_eval/plans/pilot.json |
the registered plan — 10 pinned repos, 50 tasks |
RESULTS.md |
pre-registration + n=15 pilot + keyword-50 + the n=50 real-agent headline |
Metadata
Release files for pasr-bench 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pasr_bench-0.2.1.tar.gz | 27.2 kB | Without provenance | Details for pasr_bench-0.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pasr_bench-0.2.1-py3-none-any.whl | Python 3 | none | any | Details for pasr_bench-0.2.1-py3-none-any.whl |
Total release size: 58.6 kB
Release files / pasr_bench-0.2.1.tar.gz
| Download URL | pasr_bench-0.2.1.tar.gz |
|---|---|
| Size | 27.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2ffc347e91df7c9488ef3e86883fae53fd8cbc790dfe000e15d4272ad3e20072
|
|
BLAKE2b-256 checksum How to use checksums |
a96dac39c1aa27d9256a6e6e573d19c36460e987308bf7df588401b6bfff7ea3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / pasr_bench-0.2.1-py3-none-any.whl
| Download URL | pasr_bench-0.2.1-py3-none-any.whl |
|---|---|
| Size | 31.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
050780db36e830e650070e9febed9bbd82b18be5dbe7058800ed4f9fe69eae2f
|
|
BLAKE2b-256 checksum How to use checksums |
8f07c460adca15c6e1244db5f708d713fddb9e63b99f95432290b0f989fac646
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Security for pasr-bench 0.2.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.