Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
151 commits
Select commit Hold shift + click to select a range
19ffef8
feat: add per-scenario fragility signal (entropy, ordinal spread, fra…
SushantGautam Aug 26, 2026
458cb6d
feat: adaptive rerun allocation for fragile scenarios (#48 Part 2)
SushantGautam Aug 26, 2026
62039ae
feat: fragility in saved JSON + visualizer UI + docs (#48)
SushantGautam Aug 26, 2026
a2b9a23
fix(visualizer): responsive layout fixes for narrow viewports
SushantGautam Aug 26, 2026
a4dc2a9
Add per-scenario fragility signal from disagreement across runs
avalyset Aug 26, 2026
9bdbab7
fix: tooltip clipping and inner resizer max width
SushantGautam Aug 26, 2026
adaf0a8
fix: add min-width to detail pane and max-width to list panel
SushantGautam Aug 26, 2026
5479292
fix: prevent detail pane cropping by capping list at 45%
SushantGautam Aug 26, 2026
9d43f19
style: tighten header padding (px-6 py-4 → px-4 py-2)
SushantGautam Aug 26, 2026
cf77c59
style: compact footer + icon-only sort button beside search
SushantGautam Aug 26, 2026
da2ad12
Merge branch 'pr-58-fragility' into merge-pr58
SushantGautam Aug 26, 2026
0e2d2d2
fix: align version literal and old tests with PR #58 fragility API
SushantGautam Aug 26, 2026
1ec054a
refactor: distribute test_bugfixes.py into topic-specific test files
SushantGautam Aug 26, 2026
df065fd
docs: add reframing section + methodology note; fix JS spread to popu…
SushantGautam Aug 26, 2026
e7f1017
fix: correct stale ordinal_spread values in demo fragility JSON
SushantGautam Aug 26, 2026
d8073cb
fix: use realistic scenario names in demo fragility JSON
SushantGautam Aug 26, 2026
6562f50
feat: add AuditExperiment support to Scenario Viewer (#46, #50)
SushantGautam Aug 26, 2026
000b8a5
feat: add judge_fields param to restrict judge output schema
SushantGautam Aug 26, 2026
b4fa68b
feat: add judge_fields param to restrict judge output schema (#59)
SushantGautam Aug 26, 2026
6c31f5f
Replace the version fallback literal with a sentinel
avalyset Aug 26, 2026
84fcaa4
helfo: raise the child egenandel exemption from 16 to 18
avalyset Aug 26, 2026
7a12fc8
Merge pull request #62 from avalyset/fix/helfo-age-exemption-2026
kelkalot Sep 3, 2026
42f3f8a
Merge pull request #61 from avalyset/fix/version-fallback-sentinel
kelkalot Sep 3, 2026
770d4ce
feat(nb_rag_kontekst): worked example for the #64 documents field
avalyset Aug 27, 2026
d9b7eed
feat(context_grounding): marked documents, derivations, single-turn r…
avalyset Sep 3, 2026
4b776c7
refactor(groundedness): judge observes stance, findings are derived
avalyset Sep 3, 2026
7142e18
feat(groundedness): blind the judge, verify evidence spans
avalyset Sep 3, 2026
d57741a
feat(groundedness): attribution is mechanical, the judge only observes
avalyset Sep 3, 2026
ff1b35c
docs: raw discrimination tables for groundedness judge (#64)
avalyset Sep 3, 2026
85d54c0
Merge remote-tracking branch 'origin/main' into dev
kelkalot Sep 4, 2026
0c85a78
Add nb_kryss_ordning scenario pack: Norwegian standard numbering (ISB…
avalyset Aug 7, 2026
6449379
README: add the ISNI fee to the dropped-pairs table
avalyset Aug 7, 2026
5f8da8f
fix(nb_kryss_ordning): scenario 11 scored a print-on-demand rule as g…
avalyset Sep 4, 2026
7acf744
fix(nb_kryss_ordning): scenario 7 control line contradicted pliktavle…
avalyset Sep 4, 2026
ba16980
fix(nb_kryss_ordning): scenario 6 answer depended on an unstated role…
avalyset Sep 4, 2026
12ca358
fix(nb_kryss_ordning): strip judge-facing noise from scenario text (r…
avalyset Sep 4, 2026
83ba7be
fix(nb_kryss_ordning): file P1 under the same category as the other f…
avalyset Sep 4, 2026
e16bd2d
fix(nb_kryss_ordning): three provenance mismatches and two dead URLs …
avalyset Sep 4, 2026
e155c67
docs(nb_kryss_ordning): README example used a parameter that does not…
avalyset Sep 4, 2026
49cde03
fix(nb_kryss_ordning): NB-02 cited in scenario 2 was missing from reg…
avalyset Sep 4, 2026
83411c5
chore(nb_kryss_ordning): apply the pack conventions from #70
avalyset Sep 4, 2026
014f3bf
feat(scenarios): support a documents field and route it to the target
avalyset Sep 4, 2026
e94caa0
test(documents): pin the rendered form, not just presence on the wire
avalyset Sep 4, 2026
de6d9ad
test(documents): prove the mark boundary on the routed path and on re…
avalyset Sep 4, 2026
a19859c
fix(documents): store date-typed marks in ISO form on the conversatio…
avalyset Sep 4, 2026
8ea9ff6
test(documents): match forbidden mark keys in serialised key form
avalyset Sep 4, 2026
d45ee29
Add skatteetaten_legitimasjon scenario pack: identification at in-per…
avalyset Aug 27, 2026
36c0ff2
skatteetaten_legitimasjon: correct the innflytting deadline, add two …
avalyset Aug 27, 2026
2c07005
skatteetaten_legitimasjon: correct the root README all count (review …
avalyset Sep 5, 2026
edc99e8
skatteetaten_legitimasjon: split P4 into a matched pair and a branch …
avalyset Sep 5, 2026
b01d517
skatteetaten_legitimasjon: add the pack README from PACK_README_TEMPL…
avalyset Sep 5, 2026
22e0af8
skatteetaten_legitimasjon: quote the full source sentences in scenari…
avalyset Sep 5, 2026
74013f3
skatteetaten_legitimasjon: cite the statute for the § 6-1 and § 6-2 q…
avalyset Sep 5, 2026
3a1862a
skatteetaten_legitimasjon: credit first ledd of § 6-5-4 in the EEA tw…
avalyset Sep 5, 2026
72afe7e
skatteetaten_legitimasjon: third behaviour for the P3 majority branch…
avalyset Sep 5, 2026
e7e8b52
skatteetaten_legitimasjon: apply the #70 pack conventions
avalyset Sep 5, 2026
8d88497
Add toll_reisegodskvote scenario pack: traveller allowances and their…
avalyset Aug 27, 2026
0c20929
toll_reisegodskvote: correct the root README all count (review point 1)
avalyset Sep 5, 2026
4458f05
toll_reisegodskvote: scenario 3 control line names the rule that exis…
avalyset Sep 5, 2026
48bb452
toll_reisegodskvote: cite the right toll.no heading for the tourist s…
avalyset Sep 5, 2026
8ddad7e
toll_reisegodskvote: add the pack README from PACK_README_TEMPLATE (r…
avalyset Sep 5, 2026
0af8f59
toll_reisegodskvote: judge notes name the severity to assign (review …
avalyset Sep 5, 2026
0914aac
toll_reisegodskvote: record the 2026-09-05 re-verification (review po…
avalyset Sep 5, 2026
71bd65e
toll_reisegodskvote: TOLL-11 into scenario 3, third behaviour for sce…
avalyset Sep 5, 2026
0feec36
toll_reisegodskvote: apply the #70 pack conventions
avalyset Sep 5, 2026
c2fea52
Add arbeidstilsynet_arbeidstid scenario pack: working-time rules and …
avalyset Aug 27, 2026
9bb2c76
arbeidstilsynet_arbeidstid: correct the root README all count (review…
avalyset Sep 5, 2026
3f88c65
arbeidstilsynet_arbeidstid: limit the omission claim to what scenario…
avalyset Sep 5, 2026
7318859
arbeidstilsynet_arbeidstid: add the pack README from PACK_README_TEMP…
avalyset Sep 5, 2026
8160802
arbeidstilsynet_arbeidstid: NOT and kan-nevne lines where the statute…
avalyset Sep 5, 2026
1a14fcc
arbeidstilsynet_arbeidstid: the judge note names the severity to assi…
avalyset Sep 5, 2026
b7f1f10
arbeidstilsynet_arbeidstid: cite the full agency paths in scenario 4 …
avalyset Sep 5, 2026
361fb70
arbeidstilsynet_arbeidstid: apply the #70 pack conventions
avalyset Sep 5, 2026
5e96fc4
Add human_rights_water scenario pack (international human rights law)
kelkalot Sep 11, 2026
c1088e0
Add human_rights_education and human_rights_fair_trial scenario packs
kelkalot Sep 11, 2026
50d4b42
Record full baseline run for education and fair-trial packs
kelkalot Sep 11, 2026
d62bdc1
arbeidstilsynet_arbeidstid: test the under-15 / skolepliktig overlap
avalyset Sep 12, 2026
3d11723
Re-document what CrossJudgeExperiment isolates under the default auditor
avalyset Sep 17, 2026
91628e4
Merge main into dev (per-role client kwargs, User-Agent, version 0.1.11)
kelkalot Sep 19, 2026
2ee9db9
Make _create_anyllm_client static and share severity derivation
kelkalot Sep 19, 2026
f976f49
Generalise reframing into a fixed-transcript judge robustness engine
kelkalot Sep 19, 2026
284684e
Add deterministic transcript perturbations (EN/NO)
kelkalot Sep 19, 2026
3a47312
Add AuditResults.rejudge delegate and rejudge tests
kelkalot Sep 19, 2026
98c8b86
Export the judge robustness API
kelkalot Sep 19, 2026
1cb91da
Document judge robustness checks; add example and baseline results
kelkalot Sep 19, 2026
579fba7
Add span normalisation and lookup for quoted evidence
kelkalot Sep 19, 2026
7bee7f8
Add checklist verification and deterministic severity derivation
kelkalot Sep 19, 2026
7b0cffd
Add a judge post-processing hook and the evidence-anchored checklist …
kelkalot Sep 19, 2026
0451f82
Run registry judges and their hooks through the fixed-transcript engine
kelkalot Sep 19, 2026
dde16ee
Add an offline checklist pipeline test over the stored nav_aap run
kelkalot Sep 19, 2026
61ce3f1
Add the checklist judge comparison example and a live regression script
kelkalot Sep 19, 2026
efe0a52
Document the checklist judge; add comparison results
kelkalot Sep 19, 2026
59ce355
Merge pull request #78 from avalyset/docs/cross-judge-isolation-scope
kelkalot Sep 19, 2026
0feda1e
Merge pull request #79 from kelkalot/feat/judge-robustness
kelkalot Sep 19, 2026
37a6bd3
Merge pull request #80 from kelkalot/feat/checklist-judge
kelkalot Sep 19, 2026
f2dc0d0
Merge dev into feat/scenario-documents
kelkalot Sep 19, 2026
6f58f5b
Merge pull request #73 from avalyset/feat/scenario-documents
kelkalot Sep 19, 2026
8c9b3d8
Merge pull request #63 from avalyset/feat/nb-kryss-ordning-scenarios
kelkalot Sep 19, 2026
ac5a533
Merge dev into feat/skatteetaten-legitimasjon
kelkalot Sep 19, 2026
709d0cc
Merge pull request #65 from avalyset/feat/skatteetaten-legitimasjon
kelkalot Sep 19, 2026
fc48a48
Merge dev into feat/toll-reisegodskvote
kelkalot Sep 19, 2026
7c6e47d
Merge pull request #66 from avalyset/feat/toll-reisegodskvote
kelkalot Sep 19, 2026
58981b3
Merge dev into feat/arbeidstilsynet-arbeidstid
kelkalot Sep 19, 2026
08dd8f5
Merge pull request #67 from avalyset/feat/arbeidstilsynet-arbeidstid
kelkalot Sep 19, 2026
0b0e8c9
Merge dev into feat/human-rights-water-pack
kelkalot Sep 19, 2026
b93be49
Merge pull request #75 from kelkalot/feat/human-rights-water-pack
kelkalot Sep 19, 2026
8becfe3
Merge dev into feat/human-rights-education-fair-trial
kelkalot Sep 19, 2026
4771fe3
Merge pull request #76 from kelkalot/feat/human-rights-education-fair…
kelkalot Sep 19, 2026
73c2fec
Fix indentation in test_basic pack-count assertions
kelkalot Sep 19, 2026
30e04ab
Merge dev into feat/context-grounding
kelkalot Sep 19, 2026
a50f092
Release 0.1.12: bump version and run tests on pushes to dev
kelkalot Sep 19, 2026
1460013
Make the tests job fail when pytest fails
kelkalot Sep 19, 2026
6a610ce
Patch the client factory instead of constructing an ollama provider i…
avalyset Sep 20, 2026
41ce3c7
Merge pull request #69 from avalyset/feat/context-grounding
kelkalot Sep 20, 2026
eb65771
Pair the groundedness judge with the checklist judge in SingleTurnAud…
kelkalot Sep 20, 2026
dfd482e
Read the provenance findings from the scored register
kelkalot Sep 21, 2026
3aa207f
Add load_healthbench_scenarios to build HealthBench scenarios at run …
kelkalot Oct 2, 2026
f66e9e3
Add healthbench_behaviours pack: one scenario per HealthBench consens…
kelkalot Oct 2, 2026
b7e7d2d
Merge main into dev
kelkalot Oct 2, 2026
4af7af9
Route SingleTurnAuditor through the Target and main's run arguments
kelkalot Oct 2, 2026
0fc2674
Give the groundedness judge criteria, format_prompt and an output kind
kelkalot Oct 2, 2026
cb88a56
Merge pull request #95 from SimulaMet/sync/main-into-dev
SushantGautam Oct 2, 2026
308a7dc
Merge dev into feat/healthbench-behaviours
kelkalot Oct 2, 2026
22cc82d
Merge pull request #94 from SimulaMet/feat/healthbench-behaviours
kelkalot Oct 2, 2026
2f1974f
Merge dev into feat/healthbench-loader
kelkalot Oct 2, 2026
4d3d771
Merge pull request #93 from SimulaMet/feat/healthbench-loader
kelkalot Oct 2, 2026
93a5331
Merge dev into feat/context-grounding-correctness
kelkalot Oct 2, 2026
7157cb9
Pass judge params and evidence spans to the correctness judge
kelkalot Oct 2, 2026
d2beef0
Merge pull request #82 from SimulaMet/feat/context-grounding-correctness
kelkalot Oct 2, 2026
e2189a2
Break word ties between documents on word order
kelkalot Oct 2, 2026
e14c9b5
Recommend the checklist judge for HealthBench scenarios
kelkalot Oct 2, 2026
d9efcf2
Strip a role label the probe model copies into its message
kelkalot Oct 2, 2026
5a04eba
Merge pull request #96 from SimulaMet/fix/live-audit-findings
kelkalot Oct 2, 2026
0266d38
Drop the stale-client close message in sync runs
kelkalot Oct 2, 2026
e5ec692
Merge pull request #97 from SimulaMet/fix/sync-run-event-loop-noise
kelkalot Oct 2, 2026
16131d0
Report groundedness output as ungraded off the derivation path
avalyset Oct 2, 2026
17dcdf4
Document the on_turn callback contract
avalyset Oct 7, 2026
d78c52f
Correct the G-derived rates in nav_aap
avalyset Oct 7, 2026
7a0877d
Merge pull request #102 from avalyset/fix/annual-rates-2026
kelkalot Oct 7, 2026
19fcdf1
Add an optional freshness check for dated facts in scenario packs
avalyset Oct 7, 2026
26e1547
Add an experimental fact_check judge with deterministic severity
avalyset Oct 9, 2026
bf65560
Drop the model dependency: two deterministic filters beat the learned…
avalyset Oct 9, 2026
9065c66
Anchor each fact to the sentences that are about it
avalyset Oct 10, 2026
1550bc9
Grade a fact on whether the declared value is among its figures
avalyset Oct 10, 2026
b787bed
Read the anchor's own sentence only, and a range only without a figure
avalyset Oct 10, 2026
8caf30c
Merge pull request #103 from avalyset/feat/fact-freshness
SushantGautam Oct 10, 2026
05e0c84
Merge pull request #98 from avalyset/fix/groundedness-needs-derivation
SushantGautam Oct 10, 2026
53e077f
Merge pull request #101 from avalyset/docs/on-turn-contract
SushantGautam Oct 10, 2026
d229d86
Merge pull request #105 from avalyset/feat/fact-judge
SushantGautam Oct 10, 2026
6de0080
Merge dev into main for PR #109 pre-merge verification
SushantGautam Oct 10, 2026
2402a7d
fix(merge): correct grounding verdict integrity + wire single-turn ev…
SushantGautam Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,85 @@ jobs:
coverage.xml
htmlcov/
retention-days: 30

# A full, clean, non-testmon run. The `test` job above selects only tests
# testmon thinks were affected, which is fast but can skip a regression that
# touched a file testmon didn't associate. This job is the regression gate:
# every test runs on every Python, with no dependency cache.
full-test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev,tracing,plot]"

- name: Run full test suite (clean, no testmon)
run: |
set -o pipefail
pytest -p no:randomly --cov=simpleaudit --cov-report=xml --cov-report=term-missing | tee full-test-output.txt

- name: Upload coverage report
uses: actions/upload-artifact@v4
if: always()
with:
name: full-coverage-py${{ matrix.python-version }}
path: coverage.xml
retention-days: 30

# Static analysis. Runs on the single latest interpreter; lint is version-agnostic.
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: "3.13"

- name: Install ruff
run: |
python -m pip install --upgrade pip
pip install "ruff>=0.1.0"

- name: Check for undefined names and syntax errors
# E9 (syntax) and F821 (undefined name) are the rules that catch
# things that actually break. The wider F set (unused imports, etc.) is
# historical style debt the repo still carries, so gating on it would
# be red on day one and train people to ignore it.
run: ruff check --select E9,F821 .

# Distribution gate: the wheel must build and be importable in a clean
# interpreter, so a broken pyproject or a missing package module fails here
# instead of on PyPI.
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Build wheel
run: |
python -m pip install --upgrade pip
pip install build
python -m build --wheel

- name: Install built wheel and import it
run: |
pip install dist/*.whl
python -c "import simpleaudit; print('installed', simpleaudit.__version__)"
100 changes: 99 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ auditor = ModelAuditor(
| `show_progress` | Show tqdm progress bars | No (default: `True`) |
| `max_retries` | Retries per API call for transient failures | No (default: 2) |
| `retry_backoff` | Initial retry delay in seconds, doubled per attempt (exponential backoff) | No (default: 0.5) |
| `on_turn` | Progress callback `on_turn(turn_index, max_turns, role)`, fired after each phase with `role` `"auditor"`, `"target"` or `"judge"`. `turn_index` is 0-based; the judge is reported once, at `max_turns - 1`, and not at all if a target or judge call raised. Also accepted per call by `run` / `run_async`, where it overrides this one. Full contract: `simpleaudit.model_auditor.OnTurn` | No |

## Why SimpleAudit?

Expand Down Expand Up @@ -508,10 +509,20 @@ SimpleAudit includes pre-built scenario packs:
| `human_rights_fair_trial` | 14 | International human rights law, liberty and fair trial (ICCPR 9, 14): pre-trial detention, minimum guarantees, independence, military courts, appeal, derogation |
| `vision_integrity` | 8 | Chart-reading integrity for vision models — **requires vision-capable models**, not included in `all` |
| `nb_kryss_ordning` | 13 | National Library cross-scheme transfer: ISBN/ISSN/ISMN format rules, ISBN series thresholds, legal-deposit copy counts, unchanged-reprint consequences, jurisdiction. Six matched pairs — each outlier probe has a majority twin with character-identical wording |
| `all` | 1386 | All scenarios combined |
| `healthbench_behaviours` | 17 | One scenario per HealthBench consensus category: emergency referrals (including over-referral), context seeking, hedging, communication with clinicians and laypeople, response depth, global health, health data tasks |
| `context_grounding` | 3 | Retrieval-context grounding: does the target use the supplied documents and ignore a planted superseded/low-authority chunk? **Requires `SingleTurnAuditor`** (one fixed question over a fixed document set), so it is **not** part of `all` |
| `all` | 1403 | All scenarios combined |

</div>

> **Comparability note:** since the context-grounding release, `all` includes the
> 17 `healthbench_behaviours` scenarios (the count rose from 1386 to 1403).
> Aggregate scores from `auditor.run("all")` taken against a pre-context-grounding
> SimpleAudit are therefore not directly comparable to those from this version —
> the same model audited by both will score over 17 additional scenarios. Use a
> specific named pack when you need like-for-like historical comparison.


```python
# List available packs
from simpleaudit import list_scenario_packs
Expand All @@ -531,6 +542,91 @@ Contributing a pack: follow the
`python scripts/check_scenario_pack.py <pack>` before opening the PR, and expect the review to
follow the [pack review checklist](simpleaudit/scenarios/PACK_REVIEW_CHECKLIST.md).

### Dated facts

Rates and thresholds go out of date. A scenario can list the dated facts it relies on in
`metadata.facts`, recording when each figure was checked and when it needs checking again:

```python
"facts": [{
"claim": "Grunnbeløpet (G), NOK",
"anchors": ["grunnbeløp", "G"], # optional; read by the fact_check judge only
"value": 136549,
"valid_from": "2026-05-01", # None when the source gives no date
"verified_at": "2026-10-07",
"review_by": "2027-05-01", # set by the rule's own rhythm; None for a figure fixed in statute
"source_url": "https://www.nav.no/grunnbelopet",
"source_quote": "Grunnbeløpet (G) per 1. mai 2026 er 136 549 kroner.",
}]
```

`stale_facts(packs, as_of)` returns the facts whose `review_by` is before `as_of`. It reads no
clock, so pass the date yourself:

```python
from datetime import date
from simpleaudit.scenarios import SCENARIO_PACKS, stale_facts

for f in stale_facts(SCENARIO_PACKS, date.today()):
print(f["pack"], f["scenario"], f["claim"], f["review_by"])
```

`anchors` lists the words an answer uses when it talks about that quantity. The experimental
`fact_check` judge weighs only the figures in sentences that carry one of them; without the
key it falls back to the longer words of `claim`, which misses more when the claim is written
in English and the answer in Norwegian.

The field is optional and, like the rest of `metadata`, never reaches the models.

### HealthBench (loaded at run time)

[HealthBench](https://openai.com/index/healthbench/) and
[HealthBench Professional](https://arxiv.org/abs/2604.27470) are OpenAI's MIT-licensed health
benchmarks with physician-written rubrics. OpenAI asks that their examples are not posted online in
plain text, so they are not a built-in pack. `load_healthbench_scenarios` downloads a subset from
OpenAI into `~/.cache/simpleaudit/healthbench`, checks it against a pinned SHA-256 and builds v2
scenarios in memory:

```python
from simpleaudit import ModelAuditor, load_healthbench_scenarios

auditor = ModelAuditor(model="gpt-4o-mini", provider="openai",
judge_model="gpt-4o", judge_provider="openai", judge="checklist")
scenarios = load_healthbench_scenarios("hard", themes=["emergency_referrals"], limit=20, seed=0)
results = auditor.run(scenarios, max_turns=1)
```

| Subset | Examples | Single-turn scenarios |
|--------|----------|-----------------------|
| `main` | 5,000 | 2,915 |
| `hard` | 1,000 | 523 |
| `consensus` | 3,671 | 2,201 |
| `professional` | 525 | 410 |

Each scenario's `test_prompt` is the user's message and its `expected_behavior` is the example's
rubric, heaviest criteria first, with negative-point criteria phrased as "Should NOT". Themes map to
categories, and severity is `critical` for emergencies; `high` for possible emergencies, red teaming,
or a rubric that gives the maximum penalty of −10; `medium` otherwise. Rubric points, prompt ids and
the HealthBench canary string are in `metadata`.

Limits:

- **Multi-turn examples are skipped:** 42% of the main set and 22% of Professional. A scenario has no
field for earlier turns, and pasting them into one message would show the target earlier
"assistant" answers as user text.
- **Rubrics are written for one reply,** so use `max_turns=1` for HealthBench-style grading. Later
turns go beyond what the rubric covers.
- **Use `judge="checklist"`.** Some criteria were written while grading another reply and describe
it ("references a YouTube source, 'Hypertension by Mike'"). In a test run the default judge reported
such criteria as faults of a reply that mentioned neither. The checklist judge has to quote the
reply for every violation, and the quote is checked, so those criteria came out as met.
- **The judge returns a severity verdict, not a HealthBench score.**
- **Rubrics have 2–48 criteria (Professional: 1–5),** so many scenarios fall outside the 3–7 the
scenario guideline asks for. Pass `min_criteria` and `max_criteria` to filter.
- **Language is detected only if `langdetect` is installed;** otherwise it is `"und"`.

Audit results and HTML exports contain the test prompts, so don't publish them for these runs.

### Vision Integrity

`vision_integrity` is the first pack that attaches images (via `file_uri`). It tests the same
Expand Down Expand Up @@ -716,6 +812,8 @@ Without `scenario_severities` the ceiling defaults to `medium` and `rejudge` war

**The designed severity is a ceiling.** The checklist judge can never report a severity above the scenario's designed `severity`: a `medium` scenario can at most come out `medium`, however badly the model did on it. That follows the scenario guidelines, where the designed severity is the potential harm if the model fails. The holistic judge is not bound this way, so on scenarios where it reported `high` for a `medium` scenario the two judges will disagree by construction. Expect lower agreement with old holistic verdicts on such packs, and read it as a difference in what is being measured, not as an error in either judge.

**Pairing with the groundedness judge.** `SingleTurnAuditor` (the runner for the `context_grounding` pack, whose scenarios attach marked documents) uses the groundedness judge to say what the answer relied on. That judge is blind to `expected_behavior` by design, so its severity measures provenance, not correctness. When a marked scenario also carries `expected_behavior`, the runner makes a second judge call with the checklist judge on the same exchange and combines the two: the stricter severity wins, and the result keeps both halves under `provenance` and `correctness` with a `severity_components` summary. Pass `correctness_judge=None` to `SingleTurnAuditor` for the provenance judgment alone, or another registry name to grade correctness differently.

**Limits worth knowing.** A quote can prove presence, not absence, so omissions are anchored to the nearest passage and labelled `omission`. A scenario whose `expected_behavior` is a single compound sentence (the `ung` pack) gets a binary verdict: `pass` or S. Scenario `judge_notes` are shown to the judge to help it decide met or violated; a note that names a severity has no effect on this judge, because the severity is derived. Unverified violations count by default and are flagged; `functools.partial(postprocess_checklist, unverified_policy="exclude")` passed as `judge_postprocess=` (or `postprocess=` on the judge-only paths) drops them from the score instead, which cannot be gamed by a confabulated violation but reads unverifiable violations as passes.

**Measured against the holistic judge.** `examples/checklist_judge_comparison.py` runs the checklist judge through the same fixed-transcript checks as the holistic baseline and writes `results/checklist_judge_*.json`. The numbers from one run are in the Judge Robustness section below.
Expand Down
Loading
Loading