Evidence-first agentic verifier for rubric-based evaluation.
Installation • Quick start • How it works • Configuration • Reference
What is Sauron?
Sauron evaluates agent runs against rubric criteria using the execution trace, final environment state, and produced artifacts. It returns a verdict and an evidence receipt for each criterion.
Sauron adaptively gathers information through bounded, read-only queries. An investigator proposes claims, a separate verifier checks them against their sources, and a finalizer assesses whether the verified claims support a verdict. This allows Sauron to investigate long runs without loading the full trace and state into context.
Criteria that remain unresolved receive not_awarded with evidence_missing=true and
an explanation.
Rubric criteria
│
▼
Cluster planner
│
▼
Parallel investigation sessions ─── one per cluster
│
├── Query trace, state, and artifacts
├── Propose claims → retrieve sources → verify
└── Finalize each criterion using verified claims
│
▼
Task-wide consistency check
│
▼
Per-criterion verdicts and evidence receipts
+
Run summary
Installation
Requires Python 3.11 or newer.
pip install sauron-verifier
From source, with uv (the supported development workflow):
git clone https://github.com/rsanayei/Sauron.git && cd Sauron
uv sync # creates .venv with the package and dev tools
uv run sauron --help
Sauron talks to any OpenAI-compatible chat-completions endpoint (a LiteLLM proxy, or a
provider that speaks that protocol). Put the endpoint in .env (copy .env.example):
LITELLM_BASE_URL=https://your-endpoint/v1
LITELLM_API_KEY=...
SAURON_MODEL=provider/your-model # the investigator; or pass --model on each run
Model names are whatever that endpoint serves. The optional --vision surface
additionally needs pdftoppm (poppler) and, for PPTX/XLSX rendering, soffice
(LibreOffice) on the PATH.
Quick start
# ten toy tasks with known expected verdicts; validates the whole loop end to end
sauron smoke --model provider/your-model --out results --name smoke
# a corpus slice through the built-in adapter (a task JSONL + per-task run.zip archives)
sauron run --model provider/your-model --data-root /path/to/corpus \
--task-ids <task_id>,<task_id> --out results --name first_run
# a corpus through your own adapter (see docs/adapters.md)
sauron run --model provider/your-model --adapter path/to/my_adapter.py \
--out results --name mine
# metrics for a finished run, against the gold labels its adapter attached
sauron score results/first_run
(From a source checkout, prefix each command with uv run.) Runs are resume-safe: a
task whose criterion records are already on disk is not re-judged. Add --fresh to
refuse resuming into an existing run directory, or --dry-run to resolve the
configuration and the slice without any model call.
Configuration
A run is the shipped defaults plus explicit overrides. Every knob is listed by
sauron defaults; the fully resolved configuration is written to
<out>/<name>/config.json. You choose the investigator model; every other default is
the configuration of the reference evaluations:
| knob | default | what it does |
|---|---|---|
model |
none, you choose | the investigator: the model that runs each investigation session (--model, or SAURON_MODEL in .env) |
planner_model |
a light model | a cheaper model for the cluster planner, task gist and autoplan probe |
checker_model |
the investigator model | faithfulness and coverage checks; --checker-model selects another route |
budget_scale |
1.0 | multiplier on every session cap; 1.0 is the standard budget the reference runs used |
cache_discount |
0.1 | the token budget counts provider cache-hit input at this weight (billed cost and recorded usage are unaffected) |
coverage_check_min_criteria |
8 | awards on quantified criteria (all, every, none, ...) in sessions of at least N criteria must pass an evidence-coverage check; 0 = off |
consistency_check |
on | task-wide re-check of verdict pairs that read one source fact with opposite polarity |
parallel_checks |
4 | concurrent faithfulness checks for atoms proposed in one turn (latency only) |
gist |
on | one orientation pass per task, shared by its sessions |
autoplan |
probe |
cluster cap, workers and singleton batching measured on the corpus; pin any of them with --max-cluster-size / --cluster-workers / --singleton-batch |
concurrency |
fast |
shared scheduler preset (max 64 sessions in flight, max 16 tasks in parallel) |
mcp_config |
off | live-environment MCP servers as a read-only tool family (--mcp-config servers.json) |
vision |
off | rendered-page inspection of PDF/PPTX/XLSX/image artifacts and image-grounded atoms (--vision) |
See docs/configuration.md for every knob and the reasoning behind each default.
What ships here
sauron.judges.SauronClusterJudge: the verifier. Plans criteria into evidence clusters, runs one session per cluster, and finalizes each criterion under deterministic rules plus a conditional coverage check.sauron.judges.SauronJudge: a single-criterion verifier, usable standalone.sauron.env: bounded read-only views over a trace, a state snapshot or workspace directory, and produced artifacts (text, PDF, PPTX, DOCX, XLSX), plus a scratch sandbox forrun_python. Optional surfaces, off by default: live-environment MCP servers and rendered-page vision.sauron.verifier.evidence_store: the evidence verifier (locator schema, source resolution, deterministic checks for mechanical claims, LLM faithfulness check).sauron.adapters: thetrajectoriesadapter (a task JSONL plus per-task workspace archives), asyntheticsuite, and a loader for external adapters.
Development
uv sync --group dev
uv run ruff check . # lint
uv run pytest # offline contract tests; no network, no model calls
See CONTRIBUTING.md for the ground rules.
Documentation
docs/architecture.md: the verification loop, its invariants, and where each part lives in the codedocs/configuration.md: every knob, its default, and where the default comes fromdocs/adapters.md: theTaskBundlecontract and how to write an adapter (examples/minimal_adapter.pyis a complete one)docs/output.md: the files a run writes and how to read them
Reference
If you use Sauron in your research, please cite:
@misc{sanayei2026evidencefirst,
title = {Evidence-First Agentic Verification},
author = {Sanayei, Reza and
Dumitru, Razvan-Gabriel and
Hou, Sunjie and
Rezaei, MohammadHossein and
Riaz, Haris and
Vacareanu, Robert and
Yang, Minglai and
Liu, Ying and
Surdeanu, Mihai and
Zhang, Daniel Yue},
year = {2026},
eprint = {2610.17724},
archivePrefix = {arXiv},
url = {https://arxiv.org/abs/2610.17724}
}
Metadata
Release files for sauron-verifier 1.0.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 | |
|---|---|---|---|
| sauron_verifier-1.0.1.tar.gz | 175.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sauron_verifier-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 318.7 kB
Release files / sauron_verifier-1.0.1.tar.gz
| Download URL | sauron_verifier-1.0.1.tar.gz |
|---|---|
| Size | 175.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
796b678ed3c5fb4e78c7743bbc91be3ada5abb83bbbe4a944ab128f651238b87
|
|
BLAKE2b-256 checksum How to use checksums |
6418030a9789fd6c9a886da198226d15e327d183851e9fd57c8ffcb1c8d748a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / sauron_verifier-1.0.1-py3-none-any.whl
| Download URL | sauron_verifier-1.0.1-py3-none-any.whl |
|---|---|
| Size | 143.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f19aa5b1532638ce39b5adc234f2c6cd2a3a29bbf640eb521fd80181e1d9a014
|
|
BLAKE2b-256 checksum How to use checksums |
087d659b0139ab3819bda699f03b7083092903fe206564f78352d389d50be055
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|