Rightshold™ Sign up

Answers · AI evidence

How do I pre-register an eval's pass/fail threshold and analysis plan before I look at the scores?

Last updated

TL;DR: Write the metric, the pass/fail threshold, inclusion and exclusion rules, the multiple-comparison plan and the stop rule down before you look at the scores, then hash that plan and store the hash with the later run record. Nosek, Ebersole, DeHaven and Mellor (2018) call this preregistration: define the research questions and analysis plan before observing the outcomes, so predictions stay distinct from postdictions. The Center for Open Science puts it plainly: the same data cannot be used to generate and test a hypothesis. In LLM evals, peeking and then picking a friendlier threshold, dropping hard items, or promoting a secondary metric that "also looks good" is hypothesizing after the results are known. You may update a threshold by publishing a new versioned plan, not by editing the old one in place. record_ai_run stores the plan hash in params (kept as params_sha256) alongside the later output hash; verify_ai_run checks the receipt.

What should I check, step by step?

1. Before scoring — or before unblinding scores you already collected — write a plan: the primary metric and how it is computed, the pass/fail threshold (and whether the claim is superiority, non-inferiority or equivalence), secondary metrics, inclusion and exclusion rules, pairing, the sample size or stop rule, and how you will handle multiple comparisons.

  1. If this is a comparison, include the equivalence or superiority margin and α in the same plan. "We'll see if it improved" is not a gate. How to decide whether an eval score change is negligible with a pre-set equivalence margin covers the TOST side.
  2. Pin the instrument in the plan: the eval-set content hash and the judge id (judge model snapshot, rubric, prompt, scale, settings and parser). A threshold without a named set and judge can be moved by swapping either.
  3. Hash the canonical plan file (SHA-256). Keep the file where it cannot be quietly overwritten: a version-control tag, or a registry such as OSF Registries or an AsPredicted PDF, which is time-stamped and has a unique URL for verification.
  4. Run the eval against that plan. Do not change the threshold, drop items after seeing them, switch the primary metric, or keep adding items until the number crosses the line.
  5. When you record the run, put plan_sha256 (and the eval-set and judge hashes) in params and the results-file hash as output_sha256. record_ai_run keeps params as params_sha256 over sorted-key canonical JSON.
  6. Report confirmatory results against the plan, and label any extra cuts as exploratory. Planned and unplanned work are both useful; they are not the same claim.
  7. If the threshold has to change (a new risk tolerance, a bug in the metric, a new set version), write a new plan with a new hash. Keep the old plan and say what changed. Do not edit the original file in place.

Why does looking at eval scores before setting the pass/fail threshold move the goalposts?

Nosek, Ebersole, DeHaven and Mellor (2018) write that progress depends on generating hypotheses from existing observations and testing them with new ones, and that mistaking the generation of postdictions for the testing of predictions reduces the credibility of findings. Ordinary biases such as hindsight — seeing an outcome as more predictable after it has occurred — make this easy to do by accident. Their remedy is to define the questions and the analysis plan before observing the outcomes.

What should I write in an eval analysis plan before I look at the scores?

Primary metric and its exact definition: the denominator, how items are aggregated, and any pairwise swap for an LLM judge.

How do I update an eval pass/fail threshold without silently editing the original plan?

The Center for Open Science notes that when you write up preregistered research you should transparently disclose any changes from the plan. A new risk tolerance, a bug in the scorer or a new eval-set version is a reason to write a new plan, not a reason to rewrite the old file.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Record a signed receipt for this eval run against a plan I hashed before looking at the scores: the plan hash, the pass/fail threshold, hashes of the frozen eval set and judge, and the results-file hash.”

One-click setup

{
  "tool": "record_ai_run",
  "arguments": {
    "model": "<model or system under test, dated snapshot>",
    "provider": "<provider or eval-harness>",
    "prompt_sha256": "<sha256 of the frozen eval set file>",
    "output_sha256": "<sha256 of the per-item scores and results table>",
    "params": {
      "run": "preregistered-eval",
      "plan_sha256": "<sha256 of the pre-registered analysis plan>",
      "plan_version": "v1",
      "judge_id": "<sha256 of rubric + judge prompt + scale + settings>",
      "eval_set_sha256": "<sha256>",
      "metric": "holdout_accuracy",
      "threshold": 0.92,
      "claim": "pass_if_primary_ge_threshold",
      "alpha": 0.05,
      "n_items": 400,
      "primary_score": 0.934,
      "passed": true,
      "exploratory_notes": "none"
    },
    "ran_at": "2026-11-08T07:05:00Z"
  }
}

Rightshold does not write your analysis plan, score your eval or decide whether a run passed. It signs and timestamps the hashes and fields you send so a later reader can see which plan a result was claimed against. A receipt does not prove the plan was written before the scores unless the plan file's own dated record (or registry timestamp) shows that. Not legal advice.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'