Skip to content

feat(grading): port the evaluator audit tool to the second plan - #130

Merged
kamui merged 5 commits into
mainfrom
t3code/issue-30-audit-tool-v2
Oct 12, 2026
Merged

kamui merged 5 commits into
mainfrom
t3code/issue-30-audit-tool-v2

Conversation

@kamui

@kamui kamui commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Why

The second evaluator audit is declared (#128), and evaluator_audit.py still built the first plan's strata from the previous verdict format, so draw refused the new plan. This ports the tool, so that the sample can be drawn once the last-push cohort is graded.

Stacked on #128.

Scope

  • bench/tools/evaluator_audit.py: commands check, draw, claims, second, compare, conclude for the thirteen declared strata and three unit kinds.
    • check runs the three whole-cohort checks (saved credit equals the derivation, a claim with a canonical claim holds its saved label and known problem, no stale grade or missing row), and draw refuses on any failure.
    • draw records each stratum as sampled, whole or empty; a stratum audited whole has no tolerance.
    • claims writes the first grader's claim list (item, kind, claim id, quote) for a sampled batch, and nothing else of the first verdict.
    • compare matches by review, item, claim id and exact quote, as multisets; a missing, added, repeated, renamed or re-quoted answer or review refuses the comparison. It saves nothing about identifies_cause or cause_only.
    • Every operation after the draw rebuilds the sample from the pinned grades and refuses a sample that is not the seeded draw of its populations.
    • conclude verifies every pin, rebuilds the comparison from the sample and the second assessments, and holds only sampled strata to max_errors.
  • bench/tools/grade.py, bench/tools/grading_validation.py: a fixed claim list may carry claim ids (ids, parallel to quotes), and the validator holds the answer to them. Lists without ids behave as before.
  • bench/tools/calibration.py: STRATA comes from the tool's UNITS.
  • docs/evaluator-audit.md, docs/current-grading.md: what the tool does today, and three readings of the plan stated in the doc.

Tradeoffs

  • Claim units include claims of reviews that are not admitted. The declared text has no "admitted" for claims; the user was asked on 2026-10-12 and kept the literal reading over admitted-only.
  • A known problem is a family with approved eligibility. One awaiting approval is in no stratum and must be saved unresolved. All 67 are approved today.
  • A control unit is a review of a task whose saved control status is audited-clean. The provisional state a pending candidate causes does not remove it, so the population does not depend on what the first grader raised.
  • A review saved unassessed (its remedy inventory is incomplete) still holds graded claims and credit, so it stays a unit and draw does not wait for it.
  • When ids are present, grade.py prepare adds one sentence to the grader's prompt: "Where an item lists ids, give its claims those ids, in that order." It is prompt text outside the pinned template.
  • Not built, because the two verdicts do not hold it: the split of trial tasks from the others, the second grader's concerns about the claim list, and queue-level usage.

Blast Radius

The audit tool, and the claim-list path of grade.py prepare and its validator. grade.py and grading_validation.py are runner files, so a grading key prepared before this change fails dispatch with "runner changed after preparation"; no grading is prepared yet. Nothing is graded, so the tool has not run on real batches: on the real records check exits 1 with "189 selected batch(es) have no grade".

Verification

  • python3 -m unittest discover -s bench/tools -p "test_evaluator_audit.py": 43 pass. test_calibration.py 21, test_grade.py 66, test_claim_grading.py 28 pass.
  • python3 bench/tools/calibration.py check and current_grading.py check: pass.
  • bun run test:bench: 934 tests, one failure, test_codex_grading.test_catalog_preserves_native_model_instructions, which also fails on main on this host and passes in CI.
  • Reviewed twice by Codex GPT-6.1 Sol (high): seven findings on the first version and three on the fixes, all addressed with a test each. The second pass found no regression in populations, draw order, what reaches the second grader, or the exclusion of the second fact.
  • Known gap: sample.json pins the task facts its populations rest on (known problems, impact labels, control status), because a ruling can change them after the draw without changing a grade. An edit that changes those facts and the populations together is not caught until compare pins the sample. Committing sample.json right after the draw closes it; the claim strata do not have the gap, since they come from the pinned grades alone.

Part of #30

@kamui
kamui marked this pull request as ready for review October 12, 2026 06:14
Base automatically changed from t3code/issue-30-audit-v2 to main October 12, 2026 06:36
kamui added 5 commits October 12, 2026 02:39
The second evaluator audit matches a second grader's answers to the first
grader's claims by review, item, claim id and exact quote. The claim list
that grade.py prepare --inventory fixes held each item's kind and quotes
only, so a second grader chose its own ids.

An inventory item may now list ids beside its quotes. The validator holds
the claims of that item to those ids in order, and the prompt says so when
a list carries them. A list without ids behaves as before.
evaluator_audit.py built the first plan's nine strata from verdict
contract v1 and refused the plan audits.json now declares. It reads grades
saved under contract v2 and builds the thirteen declared strata.

- check runs the three whole-cohort checks and names each failing unit:
  saved credit against the credit the claims give, linked claims against
  their saved label and known problem, stale grades and missing rows.
  draw runs them first and refuses on a failure.
- draw orders by the seeded hash with ties by unit id, records a stratum
  no larger than its size as audited whole and an empty one as empty, and
  lists a unit drawn in two strata once with both.
- claims writes a sampled batch's claim list for grade.py prepare
  --inventory: item, kind, claim id and quote. second refuses a workspace
  prepared without it.
- compare matches by review, item, claim id and exact quote and refuses a
  missing, added, renamed or re-quoted answer. Only a different credit,
  claim outcome or control result is a disagreement. Counts without a
  tolerance are saved under reported; nothing is computed from the second
  fact.
- conclude holds each sampled stratum to its tolerance. A stratum audited
  whole records its confirmed errors and never fails on their count.

The first plan's strata maps and its overlapping-quotation matcher are
removed. The first round's saved records are not read.
An independent review of the port found seven defects. Each is fixed with
a test that fails without the fix.

- conclude trusted comparison.json. It now refuses when the sample or a
  second assessment changed since the comparison, and when comparison.json
  is not what the sample and the latest second assessments give. Every
  operation after the draw refuses a sample that is not the seeded draw of
  its populations at the declared sizes. A second assessment whose verdicts
  or receipt changed is refused.
- claims overwrote its output file. It writes once, to a new file outside
  the round's directory.
- compare dropped added answers. Claims are matched as multisets and the
  two sets of reviews must be equal, so an added or repeated answer or
  review refuses the comparison.
- The third check skipped reviews that are not admitted, whose claims are
  units. Every graded review needs a row for each known problem.
- The second check let a linked claim lose its saved known problem. The
  graded claim must hold an entry for it under every saved label.
- The says-what counts covered only the problems a grader mentioned. They
  cover every claim and known problem of its task, with the raised pairs
  beside them.
- A family awaiting approval was derived as missed while the grade saves
  it unresolved. It is a unit of no stratum and its saved credit must be
  unresolved.

docs/evaluator-audit.md records three settled readings: a claim unit can
come from a review that is not admitted, a known problem is a family with
approved eligibility, and the control is the saved status.
…t builds them

calibration.py and evaluator_audit.py each listed the thirteen stratum
names. calibration.STRATA is now the tool's own table, so a stratum cannot
be required without being built.
… each second assessment

A second review found three ways past the audit's checks.

- A population edited in sample.json was accepted, because the draw was
  rebuilt from the populations the sample itself saved. Cutting a sampled
  stratum to its drawn units made it audited whole, with no tolerance.
  Every operation after the draw now builds the units again from the
  pinned grades, the selected attempts and the task facts the sample pins,
  and refuses a sample whose strata, drawn units, counts or batches differ.
  The sample pins each task's known problems with their impact labels and
  its control status, because a ruling may change one of them before the
  conclusion without changing a grade.
- A second assessment with no claim carried no pin of its receipt or raw
  verdicts, and assessment.json was unpinned until the comparison. The
  receipt is written last and records the hashes of the verdicts and the
  assessment. compare and conclude check both, and the comparison pins all
  three files of each assessment.
- claims compared its resolved output path with an unresolved round
  directory, so a round reached through a symlink took the file.
@kamui
kamui force-pushed the t3code/issue-30-audit-tool-v2 branch from fc269f9 to 5286dca Compare October 12, 2026 06:41

@kamui kamui left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved (advisory) — no findings.

Reviewed 5286dca. All nine changed files, the full diff, grading input fingerprints, grade projection, provenance checks, record locking and affected validators reviewed. Required independent verification completed. No finding or open question remains. The sample task facts still rely on committing sample.json immediately after drawing, as the PR discloses; no real audit has run because the cohort is ungraded.

Review details

Intent: Port the evaluator audit to verdict contract v2 and the thirteen declared strata, with a fixed claim list for the independent second pass.

Issue fit: The PR delivers the audit-tool portion of #30. Actual regrading, paid second assessments, audit reconciliation and dataset publication remain outside this change. Requirements were taken from the PR text and the declared audit plan.

Reviewed: 5286dca against merge-base 9feb2e1.

Checks:

  • Accepted caller evidence from the clean reviewed head: evaluator-audit tests 49, calibration tests 21, grading tests 66 with sandbox escalation, and claim-grading tests 28 passed. Changed-test assertions and fixtures were inspected.
  • Accepted exact-head calibration, current-grading and import checks, and diff whitespace validation. Prior sandbox startup failures were environment failures and were superseded by the successful escalated grading run.
  • Current CI snapshot: Web and evidence and Client compatibility passed; Grading regressions pending. The prior broad-suite catalog failure is historical and also occurs on main on this host.

@kamui
kamui merged commit e58a7c2 into main Oct 12, 2026
4 checks passed
@kamui
kamui deleted the t3code/issue-30-audit-tool-v2 branch October 12, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant