Pre-registered, not yet run. Every model-reviewer measurement so far used rules a hand-written checker already decides. EXP 011 asks the opposite: on the 18 rules EXP 007's census found no bce 0.3.1 constraint can decide, and which a code change can still break, does nina 0.34.0's reviewer tell violating changes from clean ones better than the frozen rule-filtered off-the-shelf tools, with both held to a false-reject rate of at most 15%? Written, hashed and published before any item exists and before any paid call. This bundle made no model or API call. The item authors, the blind labeller and the cap are fixed by dated amendments before the first call.

The claim

On code changes that break, or respect, rules that EXP 007's census found not expressible in bce 0.3.1, nina's reviewer separates violating from clean changes better than the best frozen off-the-shelf model-free baseline. Both are measured at a matched false-reject budget.

In the claim, 'the best frozen off-the-shelf model-free baseline' is the best of the frozen rule-filtered off-the-shelf tools: each tool runs only on the rules baselines.json maps it to, and a tool not mapped to a rule accepts every change to it. 'A matched false-reject budget' means both sides: the baseline is selected among candidates with FR <= 15% on GREEN items, and the primary passes only if the reviewer's item-level FR on GREEN items is also <= 15%.

On code changes to a small TypeScript fixture that break or respect one of the 18 eligible rules, is the balanced accuracy of nina 0.34.0's reviewer (item majority of its scheduled runs) at least 0.20 above that of the best of the frozen rule-filtered off-the-shelf tools (tsc, eslint, prettier, a churn heuristic, or their OR, each run only on the rules it is mapped to, selected at a false-reject rate of at most 15%), with the lower bound of a class-stratified bootstrap interval above 0, and with the reviewer's own item-level false-reject rate also at most 15%?

Why ask it

The rules: 18 of 50, by a filter frozen before any item

The 50 primary rules EXP 007's census finally classed not (an attempt-2 record supersedes attempt 1), recomputed by the validator from the census records; not-rules.json carries their text, kind, input kind and context as EXP 007 vendored them. The frozen criteria (criteria.md), applied to the rule text only by a fresh agent that never saw an item (none exists), before any authoring. Each decision carries one reason code and a one-sentence reason quoting the rule. The decisions are published as they were made; this bundle does not re-judge them. Fewer than 10 eligible rules would have published EXP 011 as "too few buildable rules"; 18 are eligible, so the floor holds.

Per plugin: abide 12, hunch 5, jev-axi 1. Excluded, by reason: X-PROCESS 8, X-TRANSCRIPT 8, X-TOOLCALL 6, X-COMMIT 4, X-WITHHELD 1, X-RUST 2, X-META 3. Criteria experiments/reviewer-keep/criteria.md (sha256 a714c0c3648804df25be79edcc561264fd981f3b4b58be42b2d2657ef44ef49b); decisions experiments/reviewer-keep/eligibility.json (sha256 bceba756d9de166a3eacad1dbc19fd65e94462dce6e90e669ecc7d99927f6879).

Each eligible rule's record is copied verbatim (every field) from EXP 007's vendored rule file, which pins the plugin repository at a commit with the sha256 of each source file. The MIT licence files stay where EXP 007 vendored them and are referenced by sha256. recordSha256 is the sha256 of each record's compact JSON.

The 18 eligible rules and the model-free tools mapped to each

Each rule's text, verbatim, is in its vendored record (experiments/reviewer-keep/rules/hunch.json, experiments/reviewer-keep/rules/abide.json, experiments/reviewer-keep/rules/jev-axi.json).

RuleToolsWhy
abide/clearer-code-over-commentnoneNo listed tool reads what a comment explains or whether a rename or extraction would replace it.
abide/derive-one-status-typenonetypescript-eslint recommended has no branching or complexity rule, and no other listed tool reads the shape of control flow.
abide/match-existing-styleprettier eslintFormatting and lint style are what prettier --check and eslint check, against the fixture's own configuration.
abide/mention-dead-code-dont-deletechurnDeleting unrelated dead code touches a file the task does not name.
abide/minimum-codetsc eslint churnSpeculative code often leaves unused locals or parameters, and bloat shows as diff size.
abide/no-drive-by-improvementprettier churnAdjacent edits touch files the task does not name or grow the diff; a hand reformat can differ from the formatter's output.
abide/no-single-use-abstractionchurnA new abstraction grows the diff and may add a file the task does not name.
abide/no-unasked-refactorchurnA refactor touches code outside the task's files or grows the diff.
abide/no-unrequested-configurabilitytsc churnAn added option that nothing sets can leave an unused parameter, and extra options grow the diff.
abide/remove-own-orphanstsc eslintUnused imports, locals and parameters are what noUnusedLocals, noUnusedParameters and no-unused-vars report.
abide/scope-creepchurnLines that do not trace to the request show as files outside the task or as diff size.
abide/single-owner-id-formatsnoneNo listed tool compares how an identifier is formatted across call sites.
hunch/correctness/edge-case-regressionnoneNo listed tool runs the code or its tests, and a dropped boundary case need not change a type.
hunch/docs/contradictory-commentnoneNo listed tool reads a comment against the code it describes.
hunch/tests/weakened-testnoneNo listed tool runs the tests or compares what an assertion rejects.
hunch/typescript/async-orderingnonetypescript-eslint recommended without type information has no floating-promise or ordering rule.
hunch/typescript/lossy-serializationtscA conversion that changes a field's type surfaces as a type error under strict tsc.
jev-axi/PUSH_QUESTIONS/generated_by_handchurnHand-editing generated or vendored output touches files the task does not name.

The 32 excluded rules, each with its reason

The fixture and the items

order-desk: a small order service (create, pay, ship, cancel) with a closed status set, one identifier format with a single owner, integer money, an in-memory async store, an ordered async event bus, JSON serialisation with dates and optional fields, a generated file and its generator, a piece of pre-existing dead code, comments, docs and node:test tests. It is the base every item changes. 29 files, manifest experiments/reviewer-keep/fixture.sha256 (sha256 53b901072a6054051021faecfc7b93df0fefc8a6de2954762bb544b8aefa40cc). The fixture was written by a Claude agent in this bundle, before any item, from the brief only (neutral names, no rule in mind per file). Items, not the fixture, carry the violations; they are written by a non-Claude model.

**Neutral fixture history.** Exactly two commits on one branch: `base` ("fixture") and `change` ("change"). There are no other refs or tags, and no author intent in any message, file name or path. `git log`/`show` therefore leak nothing. A validator asserts this per item.

Not established by this bundle: no tool is installed here and none was run. It is a precondition of the first paid call (see preconditions), not of scoring: the installing amendment must show the base clean under all four baselines before any authoring, labelling, practice or matrix call. The fixture tests passed under node 22 type stripping when it was written.

The labels

The arms

The reviewer. nina 0.34.0 at be546e32ce30acb2a18ec9b55ff4a3b23a7b4890, claude-opus-5-5, Claude Code 2.1.280, effort high, 3 runs per item. The EXP 006 reviewer arm, reused by reference: the same fence (fence 6), diff-seen classifier, spend guard and amendment 01's chained-git rule, at the files and commit pinned here. The only change is the prompt, which is declared NOT prompt-comparable to EXP 005/006; the isolation matrix is re-run under it (budgeted at about $5, paid, after the cap is signed). There is no ignore-list. Its prompt, experiments/reviewer-keep/prompt.md (sha256 c99e86dd4759be498488136be3b1480d29100feb80176251a73bb4eaf2543563):

The change under review is the last commit: run `git show HEAD` (or `git diff HEAD~1`) to see it, including added files. The rule to check is in RULE.md. If TASK.md exists it states the task the change was meant to do. Decide whether the change breaks the rule in RULE.md. Answer ACCEPT or REJECT, then one sentence naming the evidence.

Reused from EXP 006 at commit 5b5c68189a04: run_reviewer6.mjs, stream6.mjs, fence6.mjs, scrub6.mjs, spend6.mjs, guard6.mjs, diff-seen.mjs, fingerprints.mjs, amendment-01.json.

The comparator: the frozen rule-filtered off-the-shelf tools. The comparator is the frozen rule-filtered off-the-shelf tools: frozen and pinned before authoring, configured per rule from the rule text only (baselines.json). A tool rejects an item iff its output on the change carries a diagnostic its output on the base does not. OR-of-tools on an item rejects iff any tool mapped to its rule rejects; a tool not mapped to the rule is silent (ACCEPT). Mapping experiments/reviewer-keep/baselines.json (sha256 380ad025c3bc78539016787d1b3c8545589644cfc3a09c4081439ad767859457).

**Churn heuristic, frozen:** REJECT iff the change touches any file not named in TASK.md, or changes more than 40 lines (added+deleted). Without a TASK.md, only the 40-line rule applies.

References: always-RED (BA 0.5); prevalence-random (expected BA 0.5). Jev: OFF. Decided now, never from data. Jev is a model, not a model-free arm.

The bar

BA difference = BA(reviewer item-majority) − BA(best baseline). The bar is: difference ≥ 0.20 AND the 95% lower bound of a **class-stratified bootstrap** > 0. The bootstrap resamples items within RED and within GREEN, 10,000 resamples, seed 10010.

Matched budget. The primary passes only if ALL three hold: the BA difference >= 0.20, AND the 95% lower bound of the class-stratified bootstrap > 0, AND the reviewer's item-level false-reject rate on GREEN items <= 15% (the same budget the best baseline is selected under). A reviewer above the budget fails the primary whatever its BA.

The best baseline, one definition for the hardness gate and the primary:

**Best baseline, one definition everywhere** (gate AND primary): among {each tool, OR-of-tools}, the one with the highest BA subject to FR ≤ 15% on GREEN items.
Ties → the lower FR, then the fixed tool order [tsc, eslint, prettier, churn, OR].
If none reaches FR ≤ 15%, the hardness gate passes (published explicitly) and the primary compares against always-RED / prevalence-random, reported as such.

The scorer is scripts/reviewer-keep-stats.mjs (sha256 779c20afbc3fe22f4a89c2d717f84f332b9a8e2332d7dc51d68f19b47e247944), frozen with this record.

Secondary, gates and controls

Floors and kills

fewer than 10 eligible rules after the blind filter → "too few buildable rules";
after label-disagreement exclusions, fewer than 30 RED or fewer than 30 GREEN items → "unlabelable at this N";
if the human spot-check disagrees with the agreed label on more than 10% of the spot-checked items → the agreement gate fails.

Before the first paid call

Spend and the clock

Cap: $80 proposed — founder sign-off pending; no call before a dated amendment records the signed cap. Pre-counted ceiling $30. $0: this pre-registration made no model or API call.

ItemEstimate
Author (non-Claude)$8–$15
Blind labeller$3–$6
Practice$4
Isolation matrix (new prompt)$5
Counted runs: 234 runs (72 items and 6 controls, 3 each)$38.61–$43.06
**Pre-counted ceiling trip:** if pre-counted spend reaches $30 before the counted runs, STOP. Do not start the counted runs; disclose; ask the founder.

Decisions the design left open

What this does not establish

Publication: every outcome published.

Provenance

This page is rendered from preregistration.json, the committed record at experiments/reviewer-keep/preregistration.json, whose sha256 is 60632a62f23d3d91118f48abf74c6c31061d0f5c2ea57ec7a5a5b0500aacd67f. The site publishes that file byte for byte, and a repository test re-renders this page from it and fails if they differ. A validator rebuilds every file fact in the record from the files on disk; it pins 10 files by sha256.

No item exists and no paid call has been made. The results, when they exist, will be judged against this record as published, and reported as they come out, whichever way they go.