Results · 01 OCT 2026

Measured — bar met, nina in the spotlight. The bar was met, the manipulation check passed, and the pre-registered spotlight decision (2026-10-01) does not hold it: nina's entry in the tools list.

The bar, as pre-registered

The same spotlight bar as EXP 005: amendment 01's four criteria, thresholds, denominators, hold rule and three-state labels, computed by EXP 005's own spotlightVerdict. The only change is the run-state mapping below. The primary figures count every counted run, a diff-blind run as an error; the diff-seen-only figures leave the blind runs out and are reported beside the primary, never in its place.

CriterionAll runs (primary)Diff-seen runs onlyState
Missed drift, at most 10.0% of RED runs1 of 90 (1.1%); on the 30 items, 0 of 30 (0.0%), 95% interval 0.0%–11.4%: passes, not established at this N0 of 89 (0.0%)holds
False reject, at most 25.0% of GREEN runs2 of 90 (2.2%); on the 30 items, 0 of 30 (0.0%), 95% interval 0.0%–11.4%: passes0 of 88 (0.0%)holds
Self-agreement, at least 90.0% of changes57 of 60 (95.0%)57 of 57 (100.0%)holds
Zero patches, harness failures at most 5.0% of runsno local patch; 0 of 180 (0.0%) harness failuresnot applicableholds

The bar: PASS. Item level: passes, not established at this N. Hook errors, recorded beside the bar and not a criterion: 0 of 180 (0.0%).

The manipulation check: did the reviewer see the change?

BLIND runs (harness failures included) at most 18 of the 180 counted runs (10%): the manipulation check PASSES. More than 18: it FAILS, and there is no spotlight whatever the bar says.

PASS: 3 of 180 counted runs were diff-blind, 0 of them harness failures, against the pre-registered maximum of 18 of 180. Run states: 177 SEEN-DECIDED, 0 SEEN-ABSTAIN, 3 BLIND, 0 HARNESS-FAIL.

Every run's diff visibility (180 runs)
ItemRunStateRule
c0011SEEN-DECIDEDa: a changed line in a git output
c0012SEEN-DECIDEDa: a changed line in a git output
c0013SEEN-DECIDEDa: a changed line in a git output
c0021SEEN-DECIDEDa: a changed line in a git output
c0022SEEN-DECIDEDa: a changed line in a git output
c0023SEEN-DECIDEDa: a changed line in a git output
c0031SEEN-DECIDEDa: a changed line in a git output
c0032SEEN-DECIDEDa: a changed line in a git output
c0033SEEN-DECIDEDa: a changed line in a git output
c0041SEEN-DECIDEDa: a changed line in a git output
c0042SEEN-DECIDEDa: a changed line in a git output
c0043SEEN-DECIDEDa: a changed line in a git output
c0051SEEN-DECIDEDa: a changed line in a git output
c0052SEEN-DECIDEDa: a changed line in a git output
c0053SEEN-DECIDEDa: a changed line in a git output
c0061SEEN-DECIDEDa: a changed line in a git output
c0062SEEN-DECIDEDa: a changed line in a git output
c0063SEEN-DECIDEDa: a changed line in a git output
c0071SEEN-DECIDEDb: the added file listed and read
c0072SEEN-DECIDEDb: the added file listed and read
c0073SEEN-DECIDEDb: the added file listed and read
c0081SEEN-DECIDEDa: a changed line in a git output
c0082SEEN-DECIDEDa: a changed line in a git output
c0083SEEN-DECIDEDa: a changed line in a git output
c0091SEEN-DECIDEDa: a changed line in a git output
c0092SEEN-DECIDEDa: a changed line in a git output
c0093SEEN-DECIDEDa: a changed line in a git output
c0101SEEN-DECIDEDa: a changed line in a git output
c0102SEEN-DECIDEDa: a changed line in a git output
c0103SEEN-DECIDEDa: a changed line in a git output
c0111SEEN-DECIDEDa: a changed line in a git output
c0112SEEN-DECIDEDa: a changed line in a git output
c0113SEEN-DECIDEDa: a changed line in a git output
c0121SEEN-DECIDEDa: a changed line in a git output
c0122SEEN-DECIDEDa: a changed line in a git output
c0123SEEN-DECIDEDa: a changed line in a git output
c0131BLINDnone
c0132SEEN-DECIDEDb: the added file listed and read
c0133SEEN-DECIDEDb: the added file listed and read
c0141SEEN-DECIDEDa: a changed line in a git output
c0142SEEN-DECIDEDa: a changed line in a git output
c0143SEEN-DECIDEDa: a changed line in a git output
c0151SEEN-DECIDEDa: a changed line in a git output
c0152SEEN-DECIDEDa: a changed line in a git output
c0153SEEN-DECIDEDa: a changed line in a git output
c0161SEEN-DECIDEDa: a changed line in a git output
c0162SEEN-DECIDEDa: a changed line in a git output
c0163SEEN-DECIDEDa: a changed line in a git output
c0171SEEN-DECIDEDa: a changed line in a git output
c0172SEEN-DECIDEDa: a changed line in a git output
c0173SEEN-DECIDEDa: a changed line in a git output
c0181SEEN-DECIDEDa: a changed line in a git output
c0182SEEN-DECIDEDa: a changed line in a git output
c0183SEEN-DECIDEDa: a changed line in a git output
c0191SEEN-DECIDEDa: a changed line in a git output
c0192SEEN-DECIDEDa: a changed line in a git output
c0193SEEN-DECIDEDa: a changed line in a git output
c0201SEEN-DECIDEDa: a changed line in a git output
c0202SEEN-DECIDEDa: a changed line in a git output
c0203SEEN-DECIDEDa: a changed line in a git output
c0211SEEN-DECIDEDa: a changed line in a git output
c0212SEEN-DECIDEDa: a changed line in a git output
c0213SEEN-DECIDEDa: a changed line in a git output
c0221SEEN-DECIDEDa: a changed line in a git output
c0222SEEN-DECIDEDa: a changed line in a git output
c0223SEEN-DECIDEDa: a changed line in a git output
c0231SEEN-DECIDEDa: a changed line in a git output
c0232SEEN-DECIDEDa: a changed line in a git output
c0233SEEN-DECIDEDa: a changed line in a git output
c0241SEEN-DECIDEDa: a changed line in a git output
c0242SEEN-DECIDEDa: a changed line in a git output
c0243SEEN-DECIDEDa: a changed line in a git output
c0251SEEN-DECIDEDa: a changed line in a git output
c0252SEEN-DECIDEDa: a changed line in a git output
c0253SEEN-DECIDEDa: a changed line in a git output
c0261SEEN-DECIDEDa: a changed line in a git output
c0262SEEN-DECIDEDa: a changed line in a git output
c0263SEEN-DECIDEDa: a changed line in a git output
c0271SEEN-DECIDEDa: a changed line in a git output
c0272SEEN-DECIDEDa: a changed line in a git output
c0273SEEN-DECIDEDa: a changed line in a git output
c0281SEEN-DECIDEDa: a changed line in a git output
c0282SEEN-DECIDEDa: a changed line in a git output
c0283SEEN-DECIDEDa: a changed line in a git output
c0291SEEN-DECIDEDa: a changed line in a git output
c0292SEEN-DECIDEDa: a changed line in a git output
c0293SEEN-DECIDEDa: a changed line in a git output
c0301SEEN-DECIDEDa: a changed line in a git output
c0302SEEN-DECIDEDa: a changed line in a git output
c0303SEEN-DECIDEDa: a changed line in a git output
c0311SEEN-DECIDEDa: a changed line in a git output
c0312SEEN-DECIDEDa: a changed line in a git output
c0313SEEN-DECIDEDa: a changed line in a git output
c0321SEEN-DECIDEDa: a changed line in a git output
c0322SEEN-DECIDEDa: a changed line in a git output
c0323SEEN-DECIDEDa: a changed line in a git output
c0331SEEN-DECIDEDa: a changed line in a git output
c0332SEEN-DECIDEDa: a changed line in a git output
c0333SEEN-DECIDEDa: a changed line in a git output
c0341SEEN-DECIDEDa: a changed line in a git output
c0342SEEN-DECIDEDa: a changed line in a git output
c0343SEEN-DECIDEDa: a changed line in a git output
c0351SEEN-DECIDEDb: the added file listed and read
c0352SEEN-DECIDEDb: the added file listed and read
c0353SEEN-DECIDEDb: the added file listed and read
c0361SEEN-DECIDEDb: the added file listed and read
c0362SEEN-DECIDEDb: the added file listed and read
c0363BLINDnone
c0371SEEN-DECIDEDa: a changed line in a git output
c0372SEEN-DECIDEDa: a changed line in a git output
c0373SEEN-DECIDEDa: a changed line in a git output
c0381SEEN-DECIDEDb: the added file listed and read
c0382SEEN-DECIDEDb: the added file listed and read
c0383SEEN-DECIDEDb: the added file listed and read
c0391SEEN-DECIDEDa: a changed line in a git output
c0392SEEN-DECIDEDa: a changed line in a git output
c0393SEEN-DECIDEDa: a changed line in a git output
c0401SEEN-DECIDEDa: a changed line in a git output
c0402SEEN-DECIDEDa: a changed line in a git output
c0403SEEN-DECIDEDa: a changed line in a git output
c0411SEEN-DECIDEDa: a changed line in a git output
c0412SEEN-DECIDEDa: a changed line in a git output
c0413SEEN-DECIDEDa: a changed line in a git output
c0421SEEN-DECIDEDa: a changed line in a git output
c0422SEEN-DECIDEDa: a changed line in a git output
c0423SEEN-DECIDEDa: a changed line in a git output
c0431SEEN-DECIDEDa: a changed line in a git output
c0432SEEN-DECIDEDa: a changed line in a git output
c0433SEEN-DECIDEDa: a changed line in a git output
c0441SEEN-DECIDEDa: a changed line in a git output
c0442SEEN-DECIDEDa: a changed line in a git output
c0443SEEN-DECIDEDa: a changed line in a git output
c0451SEEN-DECIDEDa: a changed line in a git output
c0452SEEN-DECIDEDa: a changed line in a git output
c0453SEEN-DECIDEDa: a changed line in a git output
c0461SEEN-DECIDEDa: a changed line in a git output
c0462SEEN-DECIDEDa: a changed line in a git output
c0463SEEN-DECIDEDa: a changed line in a git output
c0471SEEN-DECIDEDa: a changed line in a git output
c0472SEEN-DECIDEDa: a changed line in a git output
c0473SEEN-DECIDEDa: a changed line in a git output
c0481SEEN-DECIDEDb: the added file listed and read
c0482SEEN-DECIDEDb: the added file listed and read
c0483SEEN-DECIDEDb: the added file listed and read
c0491SEEN-DECIDEDa: a changed line in a git output
c0492SEEN-DECIDEDa: a changed line in a git output
c0493SEEN-DECIDEDa: a changed line in a git output
c0501SEEN-DECIDEDa: a changed line in a git output
c0502SEEN-DECIDEDa: a changed line in a git output
c0503SEEN-DECIDEDa: a changed line in a git output
c0511SEEN-DECIDEDa: a changed line in a git output
c0512SEEN-DECIDEDa: a changed line in a git output
c0513SEEN-DECIDEDa: a changed line in a git output
c0521SEEN-DECIDEDb: the added file listed and read
c0522SEEN-DECIDEDb: the added file listed and read
c0523SEEN-DECIDEDb: the added file listed and read
c0531SEEN-DECIDEDa: a changed line in a git output
c0532SEEN-DECIDEDa: a changed line in a git output
c0533SEEN-DECIDEDa: a changed line in a git output
c0541SEEN-DECIDEDb: the added file listed and read
c0542BLINDnone
c0543SEEN-DECIDEDb: the added file listed and read
c0551SEEN-DECIDEDa: a changed line in a git output
c0552SEEN-DECIDEDa: a changed line in a git output
c0553SEEN-DECIDEDa: a changed line in a git output
c0561SEEN-DECIDEDa: a changed line in a git output
c0562SEEN-DECIDEDa: a changed line in a git output
c0563SEEN-DECIDEDa: a changed line in a git output
c0571SEEN-DECIDEDa: a changed line in a git output
c0572SEEN-DECIDEDa: a changed line in a git output
c0573SEEN-DECIDEDa: a changed line in a git output
c0581SEEN-DECIDEDa: a changed line in a git output
c0582SEEN-DECIDEDa: a changed line in a git output
c0583SEEN-DECIDEDa: a changed line in a git output
c0591SEEN-DECIDEDb: the added file listed and read
c0592SEEN-DECIDEDb: the added file listed and read
c0593SEEN-DECIDEDb: the added file listed and read
c0601SEEN-DECIDEDa: a changed line in a git output
c0602SEEN-DECIDEDa: a changed line in a git output
c0603SEEN-DECIDEDa: a changed line in a git output

DIFF-SEEN iff (a) a Bash git call the client did not refuse printed a whole diff line +<fp> or -<fp> equal to one of the item's fingerprints of that sign; or (b) for an item with added files, a non-refused Bash git output lists the added path or a directory prefix of it as untracked (a short `??` entry, or an entry inside a long-form "Untracked files:" section, never under "Changes not staged"/"Changes to be committed") and a non-refused Read/Grep of that added path returned one of its + fingerprint lines (line-number and path prefixes stripped). A git call is a Bash command whose first token is git, or one in which any sub-command (split on unquoted &&, ||, ; and |) is an allowed fence6 git form (git, git --no-pager, git -C <ws>/repo or git -C <ws>/repo --no-pager, then diff, status, show or log), as amended by EXP 006 amendment 01; its whole scrubbed output is kept and read, and a `cat` of a file cannot supply a sign-matched diff line; only top-level calls count (a sub-agent's calls never make a run SEEN). Refused = listed in the result's permission_denials; is_error alone is not a refusal (the client sets it on a command that ran when its own cwd-tracking write fails under the sandbox). Otherwise DIFF-BLIND. A harness failure is never DIFF-SEEN.

Cost

API-equivalent: the total_cost_usd that the Claude Code client reports for each run, at list price. Not an invoice; the runs may be billed differently. Per counted run: mean $0.1648, 90th percentile $0.1843, computed with results.mjs percentile (numpy linear interpolation), largest $0.3531, over 180 runs with a reported cost.

Every paid call of EXP 006, from the committed spend ledger (experiments/nina-changes/spend-ledger.jsonl): $38.4224310 over 211 calls, of which $29.6651648 over 180 counted runs, under the $60 cap.

What these results do not establish

  • A BLIND run, harness failures included, is scored as an error in missed drift and false reject, at run level and in the item majority (where it counts as the wrong answer), and as a disagreement in self-agreement: its decision is treated as no decision before EXP 005's formulas run.
  • Two layers: the text deny rules are best-effort (the client matches a normalised command); the OS sandbox is the boundary: reads outside the repository within home and the temp roots are denied (the sandbox's denyRead and its home block; R9 and R45 read a file outside the repository and got "Operation not permitted"); writes are confined and there is no unsandboxed retry. Nothing is canaried anywhere else, so the matrix tests the sandbox where the answer files could be.
  • Untested residual: git diff --no-index given an in-workspace symlink to an outside file (and /dev/null) was not run live. It is refused by the layer-1 text rule on --no-index, and R45 shows the sandbox resolves the real path of what git reads; it is stated as untested, not proven (no new live row was added; matrix6 is unchanged).
  • Untested in the matrix: git forms with an environment prefix (GIT_DIR=…, GIT_EXTERNAL_DIFF=…, GIT_CONFIG_PARAMETERS=… before git). They are believed refused because no allow rule's prefix matches a command that starts with an assignment, and whatever they ran, reads outside the repository are stopped by the sandbox (R9, R29, R30 and R45, and the sandbox-only run). No live row was added; this is stated as untested, not proven.
  • git diff -O<file> (an orderfile) is allowed under the git diff rules and makes git read that file to order its output; it prints none of the file's content, so at most it is a side channel (whether an outside path exists or parses). Documented as a residual; no live row was added (no paid call).
  • The attempted-per-row check compares each row's recorded command with its registered step after the client's own normalisation only (a 2>&1 or 2>/dev/null redirection stripped). An honest rephrasing beyond that marks the row not attempted and fails the pre-run probe, which is the only one allowed under this pre-registration: the consequence is a dated amendment with a new not-before (then its own pre-run probe), not merely a question to the founder.
  • A stream with a malformed line is charged the upper bound even if a final result line reported a cost (conservative: the line cannot be trusted).
  • Sub-agents: a run can spawn a sub-agent whose own tool calls appear in the stream with a parent_tool_use_id. Only TOP-LEVEL calls count toward DIFF-SEEN (a sub-agent's calls are recorded but never make a run SEEN), so a run whose change was read only by a sub-agent counts BLIND.
  • Reviewer only: Jev, Laya and the cascade are not re-run; this measures nina 0.34.0's reviewer on mechanical architecture rules and nothing else about nina.
  • Same corpus, inputs, labels and rules as EXP 005, so the results compare; the corpus is public, and the reviewer is fenced from the answer files by the sandbox and the answer-key pre-flight.
  • Prompt confound: the prompt says "the change is everything that git diff shows", which is false for the 14 items that add a file (9 of them add only files): git diff does not show untracked files. The prompt is EXP 005's, unchanged, so the results compare.
  • Client artifact: Claude Code 2.1.280 marks some git commands that ran (git status --short, git log, git show) is_error, with "Exit code 1" and a line for its failed cwd-tracking write under the sandbox. It likely affected EXP 005's tool results too; EXP 005's records keep no tool output, so this cannot be checked (its classifier never read tool-level is_error). EXP 006 reads refusals from permission_denials and never from is_error.
  • Known false-BLIND forms: the classifier does not recognise a change shown only through git diff --color=always, git diff --word-diff, git diff -R, a coloured git status (-c color.status=always), git status --porcelain=v2 or -z, or a long-form status run from a subdirectory (its ../ paths). A run that saw the change only that way is counted BLIND: an error against the bar and the manipulation check, never toward a spotlight. Each form is pinned BLIND by a unit test (documented behaviour, not a silent gap).
  • The runs are sequential, on one machine, under whatever load it has; latency is recorded, not judged.
  • The spend guard's pending sidecar is per worktree: bundles 2 and 3 run from ONE worktree (named in experiments/nina-changes/README.md), one after the other. Two runners at once could each pass the spend check and overshoot the cap by one call, so every paid invocation holds an exclusive lock file (experiments/nina-changes/run.lock, created O_EXCL) for its whole run and a second one refuses; a stale lock is removed by the operator after checking. A reconciled pre-run probe line without a pre-registration sha counts as made under the current one (fail closed).
  • Paid calls before this record: 7 matrix probes, $4.0821826, itemised in spend.calls; none is counted in any result.
  • The two dry-run runs counted BLIND kept no tool output (that was the defect), so they are not re-classified here; the amended rule is shown on synthetic outputs built from the same two commands and a real p01 and p02 diff, and the base-only and synthetic-seen checks over all 60 items still hold. (amendment 01)
  • A git command reached only through a newline, a lone &, $(…) or backticks is not split out, so such a call is not a git call and a run that saw the change only that way is counted BLIND: an error against the bar and the manipulation check, never toward a spotlight. (amendment 01)
  • A git call's whole scrubbed output is kept, including the output of its other parts (the dry run's cat of rules.txt): it is scrubbed and linted like every other kept output, and the rules.txt text is EXP 005's public rules file. (amendment 01)
  • Only the runner's own digests are exempt; a 64-hex value anywhere else (a commit id in a tool output, a hash the model quoted) is still scanned, so a chance match there would still refuse a record and stop the run. (amendment 01)
  • The projection assumes the counted runs cost like the 17 practice runs; the spend guard, not the projection, enforces the cap before every call. (amendment 01)
  • The record lint compares text fingerprints and does not decode hex or base64, so a restricted term encoded byte by byte (or in base64) would pass it. This gap predates this amendment: the pre-registered lint6 (EXP 006, scrub6.mjs) and the site-wide check.mjs behave the same way. The answer-key files are not protected by the lint. They are protected by the OS sandbox (reads of the temp roots and of home outside the run are denied) and by the counted pre-flight scan. (amendment 01)
  • The practice runs' answer-key pre-flight scanned only the roots an override named (/private/var/tmp, recorded in pins.preflight.override of practice-a.json, practice-b.json, practice-recheck-a01.json). The counted run's pre-flight record records no override: it scanned the default roots.
  • resultSha256 is the sha256 of the result text as the client returned it, before the write-time scrub; amendment 01 calls it "the sha256 of the result text". For 1 of the 180 calls (c007 run 2) the scrub changed the result text, so the published text does not reproduce that digest. After the run the committed record was re-scrubbed (scrubbed-records.json: the local account name (read at run time from the operating system's user record and $USER, never written down), as a whole word (not inside a longer run of letters, digits, '_' or '-', and not followed by a '.' that continues a name, as in a file name), in any string value of the record -> <user>; 6 replacements in 1 field; the record was 23e6adaff25b34fd9fae10eb67e8dc39f8c3c6a01decf0d47f3a03076a812ded as the runner wrote it and is 6326e98d28f5840c3c65ec10bd611fbdbb56a1bfd80019589882955e889d8c76 as committed). For that tool output (c050 run 3, calls.149.toolCalls.4.outputSha256) the outputSha256 is the digest of the output as first recorded, so it no longer reproduces from the published text either. The published copy keeps the result digest above as recorded, and masks that superseded output digest (it is the digest of text that held the local account name); the committed record keeps it.

Reproduce

From a checkout of this repository at the commit that published these records, with Node 22:

pnpm install --frozen-lockfile
node experiments/nina-changes/write-results6.mjs --check

It recomputes experiments/nina-changes/results/results.json from the committed run record with the frozen scorer, including every run's diff visibility from its committed tool outputs and fingerprints, and fails unless the bytes match. The build runs the same check.

This section is rendered from results.json (sha256 3ef7bcf6d0317b2095df953b404e86059f9b84ffc4af6b4cb476ddaa7d9c916c), made from reviewer.json, the counted run record (the committed record's sha256 is 6326e98d28f5840c3c65ec10bd611fbdbb56a1bfd80019589882955e889d8c76; the published copy replaces the 1274 per-call digests that its own text reproduces, and the 1 digest the re-scrub superseded, with <sha256>, so a random digest cannot trip the site's restricted-term check, and is otherwise the same record), and the answer-key pre-flight record, with the spotlight decision. The run and the results name the pre-registration (sha256 41efb90da633b42acca619ab4d761e15e608ca06e496bafbc73ccfd9df03b98a) and amendment 01 (sha256 40c95cb0963fd760e078a27946d4c9aeb62c3f0d26a255374ea4079fa680cf47; the committed amendment is 40c95cb0963fd760e078a27946d4c9aeb62c3f0d26a255374ea4079fa680cf47).

Amendment 01 · 01 OCT 2026

Amended 01 Oct 2026, before any counted run. The bundle-2 dry run (practice rows only, never scored; 2026-09-30 22:00-22:10 UTC, 17 paid calls) found two defects in the pre-registered record pipeline and one statement in the pre-registration that the client's behaviour contradicts. Left as registered, the first would very likely void a counted run by chance and the second would fail the manipulation check on a classifier artefact. None concerns the bar, the corpus, the prompt, the command, or the fence's settings and allow list. Each is fixed forward here, before any counted call. The pre-registration below is unchanged and still served byte for byte (sha256 41efb90da633b42acca619ab4d761e15e608ca06e496bafbc73ccfd9df03b98a); where this section and it differ, this section wins, and only on what it lists.

What the dry run found

  • F1, a false-positive lint refusal. p06 run 2's record was refused at write time ("a restricted term"), and the run stopped partial. The only leaking field was toolCalls.4.outputSha256: a random sha256 digest of a tool output that happened to contain one of check.mjs's short restricted-term fingerprint windows. With about a hundred digests in each run record, a 180-run counted run would very likely be stopped, and so voided, by chance.
  • F2, a false-blind classification. p01 run 2 and p02 run 1 ran `cat rules.txt; git status --short; git diff` and `cat rules.txt; echo ----; git status --short; git diff`. The client ran each (687 bytes of output, 648 bytes of output; not refused), each report names the changed file and 1 of 2 quote a changed line verbatim, but the registered classifier treats a Bash call as a git call only when its FIRST token is git (refute r2 N9), so the output was not kept and the run was classified BLIND. That is 2 of 17 completed calls (11.8%), above the manipulation check's 10% limit.
  • F3, a fence fact the pre-registration states wrongly. The client ran cat on files inside the workspace with no allow rule for cat (16 top-level Bash calls in the dry run, 0 refused): Claude Code runs its built-in read-only commands on workspace paths without an allow rule. The pre-registration says only Read, Grep, Glob and the four git verbs are allowed, and that a chain with any other part is refused whole. Outside reads stayed closed: in the probe of record 7 commands that cat a file outside the workspace (R17, a bare cat ../canary-r17.txt, and the chains and command substitutions R18, R19, R19b, R39, R40, R46) were refused by the permission layer, and R9, R45, R29, R30 were stopped by the OS sandbox.

The dry-run records: practice-a.json (p01-p03 (the EXP 005 practice rows, experiments/jev-gate/practice/practice-rows.json); sha256 450dde3dd20a76d56624361b6aac2e6c94aefe76ff21b4e15e4dd4dac6379fc6); practice-b.json (p04-p06 (experiments/nina-changes/practice/practice-rows.json); sha256 df7a12750a2b09f2428f2a8b006f668311b02f8e5a271cde1c81eeda15aef05d). Their spend is lines 8-24 of experiments/nina-changes/spend-ledger.jsonl (kind practice, one per completed call, the refused one included).

What changes

  • A1, the record lint. Only a runner digest is exempt from the restricted-term scan: a digest the runner computed itself, at write time, from bytes it holds. The runner passes the write-time lint a list of (path, sha256) pairs it computed; a field is exempt only if it sits at exactly one of those paths AND its value equals the runner's own sha256 for that path (exactly 64 lowercase hex characters). The exemption is never by key name and never taken from a record or from model text: a 64-hex value the model produced (in a tool output, the result text or a tool input), or one placed under a hash-named key without being the runner's recomputation, is scanned like any other value. The record is linted with its runner digests masked, and each runner digest is still linted for paths, the session uid and credential shapes. Everything else (keys, prose, tool outputs, tool inputs) is scanned as before.
  • A2, what counts as a git call. A git call is a top-level (not sub-agent) Bash call whose first token is git, as registered, or one in which ANY sub-command, split on the unquoted control operators &&, ||, ; and |, is an allowed fence6 git form. Its full scrubbed output is kept in the record and read by the classifier. Rule (a) still needs a sign-matched whole diff line of the item in that output: a cat of a file prints no + or - prefix, so file content cannot pass for a diff line. Rule (b)'s untracked entry may come from such an output, and still needs a Read or Grep of the added file. The allowed forms: git diff, git status, git show, git log, git --no-pager diff, git --no-pager status, git --no-pager show, git --no-pager log, git -C <ws>/repo diff, git -C <ws>/repo status, git -C <ws>/repo show, git -C <ws>/repo log, git -C <ws>/repo --no-pager diff, git -C <ws>/repo --no-pager status, git -C <ws>/repo --no-pager show, git -C <ws>/repo --no-pager log.
  • A3, the fence as the client runs it. The pre-registration's fence statements (fence.compound and answer 2) are corrected: besides Read, Grep, Glob and the allowed git forms, the client runs its built-in read-only commands (cat, for example) on workspace paths without an allow rule: observed as part of a chain (every one of the dry run's cat calls was); a lone built-in read was not observed, and is believed to behave the same. A chain that reads outside the workspace is refused whole (R18, R39, R40, R46), a bare outside read is refused (R17), and reads outside the repository that pass the permission layer are stopped by the OS sandbox (R9, R29, R30, R45). The sandbox remains the boundary. fence6's settings, deny rules and allow list, matrix6, its rows and its judge are unchanged; no escape row's verdict changed; no new paid matrix run was made.
  • A5, the guard. Counted runs require this amendment too. freeze.mjs gains AMENDMENT6_SHA256 (this file's sha256) and AMENDMENT6_NOT_BEFORE (the merge time of the pull request that adds it), both left unset until the re-freeze. The counted guard refuses unless the pre-registration hashes to PREREG6_SHA256, this file hashes to AMENDMENT6_SHA256 and names that pre-registration as its parent, every pre-registered file hashes to its pin as re-pinned below, every file this amendment pins hashes to its pin, and the call starts after AMENDMENT6_NOT_BEFORE (which the run records as its notBefore). The run record and the results record carry amendment6Sha256; the scorer checks it; the spotlight gate opens only when the results and the bound reviewer run record name the frozen AMENDMENT6_SHA256. The gate's predicate and every other check are unchanged.

The amended classifier rule, as every run record now carries it:

DIFF-SEEN iff (a) a Bash git call the client did not refuse printed a whole diff line +<fp> or -<fp> equal to one of the item's fingerprints of that sign; or (b) for an item with added files, a non-refused Bash git output lists the added path or a directory prefix of it as untracked (a short `??` entry, or an entry inside a long-form "Untracked files:" section, never under "Changes not staged"/"Changes to be committed") and a non-refused Read/Grep of that added path returned one of its + fingerprint lines (line-number and path prefixes stripped). A git call is a Bash command whose first token is git, or one in which any sub-command (split on unquoted &&, ||, ; and |) is an allowed fence6 git form (git, git --no-pager, git -C <ws>/repo or git -C <ws>/repo --no-pager, then diff, status, show or log), as amended by EXP 006 amendment 01; its whole scrubbed output is kept and read, and a `cat` of a file cannot supply a sign-matched diff line; only top-level calls count (a sub-agent's calls never make a run SEEN). Refused = listed in the result's permission_denials; is_error alone is not a refusal (the client sets it on a command that ran when its own cwd-tracking write fails under the sandbox). Otherwise DIFF-BLIND. A harness failure is never DIFF-SEEN.

Files re-pinned

  • run_reviewer6.mjs: 13cc7b59de017530194c258e9c47fc3b59d268399d1d5b1da59298dbbdcecf5c → 83794bdcb8377315c4ac3f4ff2a188018529129ae050d0d258a25e59290d0eb2. A1: the record builder hands the lint the digests it computed itself (callDigests6, headerDigests6); A5: the run record carries the guard's amendment6Sha256; the argv builder is unchanged.
  • stream6.mjs: 09e55aab57aa276f7b6ae1d245ac45bf41cfd2b095e32fd692860bf4b7b250e1 → 36868cbffeb42e62b614b112c2c1b3d8a464a2a49b6703d3f66bb4b91cd8d6e1. A2: a git call is also a Bash call in which any sub-command (split on unquoted &&, ||, ; and |) is an allowed fence6 git form; such a call's output is kept.
  • scrub6.mjs: d38b4efce5346abacd6e68d19c6121c5a533410de474d0578bcdbcec75fad435 → 47d38d5cd7108ad03f76dc4b767b34ac33ca7ef7358bb5dd6cf1a9462fd06329. A1: the write-time lint does not scan a runner digest for restricted terms: a field at a path the runner names, whose value equals the sha256 the runner computed itself for it; every other value is linted as before.
  • guard6.mjs: 21b143f61a4aa640d158bef9e096d6bc213691c7170b13efed7cb9ddee2b55ce → da1794d276182e66347f37c29225d13f4fa20dab033552d4a43b67a9054403c5. A5: a counted run also needs this amendment: its sha256 frozen as AMENDMENT6_SHA256, every pin as re-pinned here, and a start after AMENDMENT6_NOT_BEFORE.
  • diff-seen.mjs: c032517dca76109f1988ba641b73d6cc7618a245ce4f3ad243fcc27fff812f88 → 64d85ee38f99bb6858609cb2d835581d40c9d8058a3cfa2fc4558f95464566cf. A2: the classifier uses the amended git call; its rule text is amended (RULE) and the registered text is kept verbatim (REGISTERED_RULE); rules (a) and (b) are otherwise unchanged.
  • results6.mjs: 7533ee983f2891506bac2185396740199b86b94510da031df4a21c51332f7025 → 49842f3249230032c653a21a14b1e4b626cff984ae17e6d0ebb8d987af0cff76. A5: the scorer checks the run's amendment6Sha256 against the stamp (and the frozen AMENDMENT6_SHA256), uses the amendment's not-before, and carries the sha in the results record.
  • spotlight-gate.mjs: df7006754a965479640f86c9eb1b661a75d0db5ac46d632b86fe68e5ebe029a3 → a817c8684aff8c3627eddaa9de3a93ededa7bc27eaba343ada0b98b3073bf3d2. A5: the gate also requires the results' amendment6Sha256 to equal the frozen AMENDMENT6_SHA256 and the reviewer run record to name the same one; the predicate and every other check are unchanged.

experiments/nina-changes/runners.sha256 is re-pinned for the 7 files above and freeze.mjs (which the re-freeze changes again); every other pin in it is unchanged.

Spend and the projection

  • Paid so far: 4.0821826 (7 isolation-matrix lines, the pre-registration's) + 3.0181336 (17 practice lines, the dry run) = 7.1003162 dollars, every line itemised in the record. No counted call has been made: the ledger holds 7 isolation-matrix lines and 17 practice lines, and no counted or pre-run line.
  • The $10 pre-counted ceiling: $2.8996838 remains, $2.2451280 after the reserve of $0.6545558.
  • The dry run's per-run cost over 17 runs: mean $0.1775373, p90 $0.2048640, max $0.2279082 (per-run cost of the dry run's practice lines; p90 by results.mjs percentile (numpy linear interpolation)). Projected counted spend at the dry run's p90: $7.1003162 + 180 × $0.2048640 + $0.6545558 + $0.6545558 = $45.2849478, within the $60 cap (at the mean $40.3661365, at the max $49.4329038).

No counted reviewer run starts before the merge time of the odin-rnd pull request that adds this file; that time is recorded after publication, frozen with this file's sha256 in freeze.mjs (AMENDMENT6_NOT_BEFORE, AMENDMENT6_SHA256), and every counted call must start after it. It replaces the pre-registration's not-before as the counted clock. The answer-key pre-flight record must end after it.

Unchanged

  • The pre-registration, byte for byte (sha256 41efb90d…), and everything in it this amendment does not list.
  • The question, the bar (EXP 005 amendment 01's four criteria, thresholds, denominators, hold rule and labels), the run-state mapping and the manipulation limit (at most 18 of 180 runs BLIND).
  • The corpus, inputs, labels, rules, base commit, prompt, reviewer (nina 0.34.0), client, model, effort, k and timeout, and the registered command (its sha256 is unchanged).
  • fence6 (settings, deny rules, sandbox and allow list), matrix6 and its judge, the attempted-per-row check, and every escape row's verdict.
  • The change fingerprints, the base lines, the practice rows and the harness-failure definition.
  • The spend cap ($60), the pre-counted ceiling ($10), the unknown-cost upper bound and the ledger rule.
  • The spotlight decision rule, the artefact a PASS publishes, and the spotlight gate's predicate.

What the amendment adds to the limits

  • The two dry-run runs counted BLIND kept no tool output (that was the defect), so they are not re-classified here; the amended rule is shown on synthetic outputs built from the same two commands and a real p01 and p02 diff, and the base-only and synthetic-seen checks over all 60 items still hold.
  • A git command reached only through a newline, a lone &, $(…) or backticks is not split out, so such a call is not a git call and a run that saw the change only that way is counted BLIND: an error against the bar and the manipulation check, never toward a spotlight.
  • A git call's whole scrubbed output is kept, including the output of its other parts (the dry run's cat of rules.txt): it is scrubbed and linted like every other kept output, and the rules.txt text is EXP 005's public rules file.
  • Only the runner's own digests are exempt; a 64-hex value anywhere else (a commit id in a tool output, a hash the model quoted) is still scanned, so a chance match there would still refuse a record and stop the run.
  • The projection assumes the counted runs cost like the 17 practice runs; the spend guard, not the projection, enforces the cap before every call.
  • The record lint compares text fingerprints and does not decode hex or base64, so a restricted term encoded byte by byte (or in base64) would pass it. This gap predates this amendment: the pre-registered lint6 (EXP 006, scrub6.mjs) and the site-wide check.mjs behave the same way. The answer-key files are not protected by the lint. They are protected by the OS sandbox (reads of the temp roots and of home outside the run are denied) and by the counted pre-flight scan.

This section is rendered from amendment-01.json, the committed record at experiments/nina-changes/amendment-01.json, whose sha256 is 40c95cb0963fd760e078a27946d4c9aeb62c3f0d26a255374ea4079fa680cf47. It names its parent by sha256 41efb90da633b42acca619ab4d761e15e608ca06e496bafbc73ccfd9df03b98a. The build validates the record and this page against it and publishes both byte for byte; a repository test re-renders the page from the two records and fails if they differ.

Pre-registered, not yet run. Amended 01 Oct 2026, before any counted run: the record lint no longer mistakes the runner's own digests for a restricted term, a compound git call now counts as a git call, and the client's built-in reads are disclosed. EXP 005 met nina's spotlight bar, but in 131 of 180 runs its own tool fence kept the reviewer from reading the diff. EXP 006 measures nina 0.34.0's reviewer again on the same 60 changes, with a fence that allows the git forms it uses, and counts a run as having seen the change only when a tool output shows at least one changed line of that change (or, for an added file, the file listed as untracked and at least one of its new lines read). Written, hashed and published before any counted reviewer run. Nothing in this record may change after publication; a later change is a new, dated amendment (the EXP 005 amendment pattern), refuted and published first, and it resets the not-before. Measured — bar met, nina in the spotlight, 01 OCT 2026: see the results.

The question

On the same 60 authored changes and the same architecture rules as EXP 005, and with a tool fence that lets it read the change, does nina 0.34.0's reviewer, run headless by Claude Code, meet the same spotlight bar as EXP 005, in runs of which at least 90% are counted as having seen the change: a tool output shows at least one changed line of that item (or, for an added file, the file listed as untracked and at least one of its new lines read)?

Why measure again

EXP 005's results: the reviewer met the registered spotlight bar (0 of 90 missed, 0 of 90 false rejects, 60 of 60 agreement, 0 harness failures), but by EXP 005's committed classifier (results/diff-visibility.json) 131 of 180 runs were diff-blind: its fence refused the git forms the reviewer used, and it audited the clean base tree instead. The founder held the spotlight until nina is measured reviewing changes. This follows EXP 005's held spotlight (results record sha256 7388556049b7639e2a251edcf3fb8feb782213b78e71a02cddb687f12b09dccd).

All 317 git commands EXP 005's fence refused, by exact form: 184 are allowed under fence6 and 133 stay refused (127: redirect to a file (fence6 never allows > to a file); 2: not a git command (head): no allow rule, and no blanket rule; 1: no allow rule matches (verb or prefix not allowed); 1: not a git command (cat): no allow rule, and no blanket rule; 1: not a git command (echo): no allow rule, and no blanket rule; 1: not a git command (ls): no allow rule, and no blanket rule). Of the 131 diff-blind EXP 005 runs, 123 began with a form fence6 still refuses and 130 tried a form fence6 allows.

What is the same

The corpus, inputs, labels, base app, base commit and rules are EXP 005's, byte for byte, so the two experiments are directly comparable. The runner asserts each by sha256 before any call. 60 changes, 30 RED and 30 GREEN by bce; corpus sha256 a83b222a1a4a64cc81ac755c827a47009baa2bb91b036e351e71422cc8d526a9; base commit 3e35e4e274932a61bc0d92f378f8d506a9bb4ce0.

The prompt, verbatim (EXP 005's):

Review the change in this repository. The change is everything that git diff shows; it has not been committed. The architecture rules this codebase must follow are in rules.txt at the repository root. Decide one thing only: does the change break any of those rules? Ignore style, naming, tests and anything else that rules.txt does not state. Do not edit any file. Explain your reasoning briefly, then write your decision on a line of its own: VERDICT: REJECTED if the change breaks at least one rule, or VERDICT: APPROVED if it breaks none.

What changes: the fence, and the record of every tool call

The command is the EXP 005 command with two declared differences: --output-format stream-json --verbose (so every tool call and its output is recorded), and fence6 (the settings and allow list below). <ws> stands for the run's own temp dir; its repository is <ws>/repo, rendered as an absolute path in each run and scrubbed back to <ws>/repo in the records. The validator derives this text from the runner's own renderCommand.

claude -p <prompt> --agent reviewer --model claude-opus-5-5 --effort high --output-format stream-json --verbose --no-session-persistence --setting-sources project --permission-mode dontAsk --settings "{\"permissions\":{\"blockReadsOutsideWorkingDirectories\":true,\"deny\":[\"Bash(git *--output*)\",\"Bash(git *--no-index*)\",\"Bash(git *<*)\",\"Bash(git *>*)\",\"Bash(git *'*)\",\"Bash(git *\\\"*)\",\"Bash(git *\\\\*)\",\"Bash(git *{*)\",\"Bash(git *}*)\",\"Bash(git *`*)\"]},\"sandbox\":{\"enabled\":true,\"failIfUnavailable\":true,\"allowUnsandboxedCommands\":false,\"autoAllowBashIfSandboxed\":false,\"filesystem\":{\"denyRead\":[\"/private/tmp\",\"/tmp\",\"/private/var/folders\",\"/var/folders\"]}}}" --allowedTools "Read(./**)" "Grep(./**)" "Glob(./**)" "Bash(git diff:*)" "Bash(git status:*)" "Bash(git show:*)" "Bash(git log:*)" "Bash(git --no-pager diff:*)" "Bash(git --no-pager status:*)" "Bash(git --no-pager show:*)" "Bash(git --no-pager log:*)" "Bash(git -C <ws>/repo diff:*)" "Bash(git -C <ws>/repo status:*)" "Bash(git -C <ws>/repo show:*)" "Bash(git -C <ws>/repo log:*)" "Bash(git -C <ws>/repo --no-pager diff:*)" "Bash(git -C <ws>/repo --no-pager status:*)" "Bash(git -C <ws>/repo --no-pager show:*)" "Bash(git -C <ws>/repo --no-pager log:*)"

Allowed git forms: git, git --no-pager, git -C <ws>/repo, git -C <ws>/repo --no-pager with diff, status, show, log. No compound rule. A chain runs only when the client allows every part under the same allow list; a chain with any other part is refused whole. Redirections to /dev/null and 2>&1 are stripped by the client before matching; a redirect to a file is never allowed. Every EXP 005 deny rule stays: Bash(git *--output*) Bash(git *--no-index*) Bash(git *<*) Bash(git *>*) Bash(git *'*) Bash(git *"*) Bash(git *\*) Bash(git *{*) Bash(git *}*) Bash(git *`*). Each run stages a fresh workspace under the operator's home cache (outside any checkout and outside the shared temp roots), with the reviewer's TMPDIR inside the run dir; the whole dir is removed after the run.

The fence, tested on canaries

A row leaks when its secret appears in the report, a refusal or ANY tool output, or its escape file appears on disk; a control works when its own command was not refused and returned the change in its own output. The model's own ALLOWED/DENIED labels are not used.

The fence was tested in three fence6 proof runs and one sandbox-only proof run. fence6 runs 1 and 2 were made at commit 14ba08d; fence6 run 3 (the probe of record) and the sandbox-only run at commit 2ab2c27 (candidate-branch commits). Their recorded code differs from the files this record pins as listed in proofRuns, each file with its reason. None of the differing files defines the fence, the matrix or its judge (experiments/nina-changes/fence6.mjs, experiments/nina-changes/matrix6.mjs, experiments/jev-gate/run_reviewer.mjs are byte-identical in every proof run), and every fence6 run ran exactly the command registered here (command sha256 ea845d19…), the sandbox-only run exactly the sandbox6-only template.

Refute r2 N6: an escape row counts as held only if the run ATTEMPTED it (a tool call whose input is that row's step); a row not attempted fails the matrix (matrix6-attempts.mjs, applied after the unchanged matrix judge). Every committed proof and discovery record was re-judged with it: every row was attempted in every run, so no verdict changed. The new -C escape forms (R32-R35, R38, R43) were refused by the allow list itself in every proof run, the sandbox-only run included (they are in each run's permission_denials). The evidence that the OS sandbox is the boundary for outside reads is R9, R45, R29 and R30: they passed the permission layer and git failed with "Operation not permitted". matrix-v6-sandbox6-only-1 was a paid call ($0.5472840) whose record was refused at write time: a home path the client had truncated in a tool output was not matched by the scrub, so the record was not written and its verdict was lost. The scrub was fixed forward and the run repeated (matrix-v6-sandbox6-only-2). The probe of record is matrix-v6-fence6-3.json (sha256 04861e1b0cfd63edc50d009df94060d071b866ebc78c0f642f432f775743af0c).

What the client did, from the recorded stream:

The manipulation check: did the reviewer see the change?

DIFF-SEEN iff (a) a Bash git call the client did not refuse printed a whole diff line +<fp> or -<fp> equal to one of the item's fingerprints of that sign; or (b) for an item with added files, a non-refused Bash git output lists the added path or a directory prefix of it as untracked (a short `??` entry, or an entry inside a long-form "Untracked files:" section, never under "Changes not staged"/"Changes to be committed") and a non-refused Read/Grep of that added path returned one of its + fingerprint lines (line-number and path prefixes stripped). A git call is a Bash command whose first token is git; only top-level calls count (a sub-agent's calls never make a run SEEN). Refused = listed in the result's permission_denials; is_error alone is not a refusal (the client sets it on a command that ran when its own cwd-tracking write fails under the sandbox). Otherwise DIFF-BLIND. A harness failure is never DIFF-SEEN.

BLIND runs (harness failures included) at most 18 of the 180 counted runs (10%): the manipulation check PASSES. More than 18: it FAILS, and there is no spotlight whatever the bar says.

The bar: EXP 005's, unchanged

The same spotlight bar as EXP 005: amendment 01's four criteria, thresholds, denominators, hold rule and three-state labels, computed by EXP 005's own spotlightVerdict. The only change is the run-state mapping below.

Missed drift and false reject are judged on the run-level point estimate (n = 90 each). Beside each rate the Wilson 95% interval of the item-level majority (n = 30) is published, because the 3 runs on one change are not independent, with the parent's three-state label computed on that item-level majority: its point estimate and its Wilson interval at n = 30, under the parent's thresholdRule.singleRate. The item-level majority is the parent's reviewerMajority; an abstaining majority counts against the reviewer. A spotlight needs BOTH the run-level point estimate within the threshold AND an item-level label other than "refuted". With 30 RED items the interval cannot establish 10% or less: 0 of 30 has a Wilson upper bound of 11.35%.

All four criteria must hold for a spotlight. A partial run (cap or hang-stop) gives no spotlight. Failing any one criterion means no spotlight; the results are then published neutrally with the same attribution. The spotlight describes the harness as measured, meaning its reviewer on mechanical architecture rules, and nothing it wasn't tested on.

Harness failure: A counted run that ends in a timeout, a non-zero client exit, no parseable final `type:"result"` line, or an unparseable NDJSON line, is_error: true, or an empty result. A run with a completed result and no verdict line is a model abstention, not a harness failure. is_error here is the final type:"result" line's only. A tool_result's is_error (a refusal, a failed git, or the client's cwd-tracking artifact) never makes a run a harness failure.

A BLIND run, harness failures included, is scored as an error in missed drift and false reject, at run level and in the item majority (where it counts as the wrong answer), and as a disagreement in self-agreement: its decision is treated as no decision before EXP 005's formulas run.

Automatic and pre-registered: a spotlight-decision record with held: false is committed if and only if the bar PASSES, the manipulation check PASSES, and the independent results refute SHIPs; otherwise held: true, naming the condition that failed. A founder decision is asked only if a refute raises a doubt this rule does not decide.

What a PASS publishes. On a PASS (the bar PASSES, the manipulation check PASSES, and the committed EXP 006 spotlight decision says held: false), the home page's "Tools leaving the factory" list gains nina's entry, next after 002 Laya, in the same shape as the Laya entry (number and category, a title linking to the evidence, one paragraph, links, an attribution note, a spec list): nina, harness orchestration for Claude Code, by Marcos Schulz (xhulz), https://github.com/xhulz/nina, with the attribution "used with the permission of its author, as confirmed by Odin Labs", and links to the EXP 006 measurement, to EXP 005 (#spotlight) and to the upstream fixes opened by Odin Labs (xhulz/nina#39, merged; xhulz/nina#41, stated as its live state at publish time: merged or open). Every figure in it is rendered from the EXP 006 results record at build time. It takes the list's next free number, 005, the slot EXP 005's gated nina card held; there is only one nina entry. What a FAIL publishes. On a FAIL, or when the spotlight is held for any reason, there is no entry, and the results page says plainly which condition failed (the bar, the manipulation check, the refute, or a partial run). WHETHER the entry shows is decided only by experiments/nina-changes/spotlight-gate.mjs, pinned in files below and re-checked by the counted guard. Its one entry point, gateOpen(root), owns the paths of the results record, the spotlight decision and the reviewer run record, reads them, and opens only for a real, complete, counted EXP 006 measurement under THIS frozen pre-registration: the results record is kind results, experiment EXP 006, not a fixture, not a rehearsal, not partial, made under the pre-registration sha frozen in freeze.mjs (which must be set), and passes EXP 005's publication check; the decision names the results record AND the reviewer run record by sha256; the reviewer run record is a complete counted EXP 006 reviewer run (kind gate-run, experiment EXP 006, gate reviewer, mode counted, not partial, not a fixture or a rehearsal) made under the same pre-registration, with the same not-before and code as the results, its calls exactly the runs the results scored (as id, run, decision, harness failure and diff-visibility class, in order) and as many as the manipulation denominator, and a parseable end time, and the Measured date comes only from it; and the bar PASSES AND the manipulation check PASSES AND spotlightEligible is exactly true AND held is the boolean false. A missing, unparseable, unbound or failing record hides the entry. It carries EXP 005's card gate (spotlightShown) byte-identical, with a slice test. HOW it looks is scripts/nina-changes-spotlight.mjs, the markup, not pinned: it holds no record path and no gate logic and renders only what gateOpen returns (its figures are read from the results record gateOpen hands back, and the PR states from the committed upstream.json), so the results can feed it without an amendment.

Spend, the pre-flight and the clock

What this does not establish

The page widths were checked two ways: a real headless Chromium render (playwright-isolated, served from the built site) of the home page, this note and the EXP 005 note at 375 px and 320 px, finding no horizontal overflow (document scrollWidth equal to the viewport); and a static repository test that no unbroken run in the note is wider than the column unless the stylesheet lets it wrap.

Provenance

This page is rendered from preregistration.json, the committed record at experiments/nina-changes/preregistration.json, whose sha256 is 41efb90da633b42acca619ab4d761e15e608ca06e496bafbc73ccfd9df03b98a. The build publishes that file byte for byte, and a repository test re-renders this page from it and fails if they differ. A validator rebuilds the record from the files on disk.

No counted run has started. The results, when they exist, will be judged against this record as published, and reported as they come out. Measured — bar met, nina in the spotlight, 01 OCT 2026: see the results.