Skip to content

Decision: an exact int64 value kind and IEEE-faithful doubles (#1644 phase 2), with the observer signal (#1667) in the same tape bump #1758

Open

Description

@InauguralPhysicist

Owner verdicts (Jon, 2026-10-13 and 14):

  • "how can you be a Turing complete language if you can't host a language … and those things are needed in languages": an exact int64 value kind and IEEE-faithful doubles are REQUIREMENTS.
  • "No outside" is retired as a constraint on the number space and on verification; the observer still reports from inside.
  • Rank by correctness, never by difficulty.
  • Decisions (A), (B) and (C) are resolved: "I'll go with your recommendations" (comment below).

This is #1644 phase 2 (numbers). Following the memory rule that the tape is the most irreversible pre-v1 commitment, the observer signal change (#1667) lands in the same tape-format bump.

Revision 1 (2026-10-14). The body was revised after a blind bar-critic pass. The full report is in the comment below. The changes:

  • INT64_MIN edges are pinned;
  • N6 cites Python repr exactly (Lua's %.14g is not round-trip);
  • N12 gets payload fidelity through int64 bit reinterpretation;
  • N14's JSON edges are decided;
  • num_type of a non-number is defined;
  • the population counts are corrected;
  • the Done-when has a command, binary and setting for every item;
  • the observer gate becomes per-predicate floors, set after the oracle gains an IEEE mode, int rows and JIT coverage.

Evidence

Decided semantics

Each item is decided by the owner or by the standard answer, with its source. The owner may overrule any of them.

Integers

  • N1 — An exact int64 value kind beside the double.
    • A literal without . or an exponent is an integer (3, 0xFF). 3.0 and 1e3 are floats.
    • A decimal integer literal outside int64 becomes a float; hex literals wrap modulo 2⁶⁴. (Lua 5.4 §3.1; probe on Lua 5.4.9: 9223372036854775808 → float, 0x1FFFFFFFFFFFFFFFF → -1)
  • N2 — The subtype is visible at runtime, and numbers compare by value across it.
    • 1 == 1.0 is true.
    • int/float comparison is mathematically exact: 9007199254740993 == 9007199254740992.0 is false. (Lua §3.4.4, Python)
    • Unifying map keys belongs to phase 4 (map keys).
  • N3 — + - * on two ints give an int, and overflow RAISES (A). int op float gives a float.
  • N4 — Division.
    • / is always float division, as today (Lua, Python 3).
    • Add // (floor division) and make % floor modulo (sign of the divisor), following Lua and Python. Lua 5.4.9 gives -7//2 = −4, -7%3 = 2, 7%-3 = −2.
    • On ints, // and % by zero RAISE value (Lua 5.4.9: "attempt to divide by zero", "attempt to perform 'n%%0'").
    • On floats, x/0 is ±inf, 0/0 is NaN and x%0 is NaN (IEEE 754).
  • N4b — The INT64_MIN edges follow (A), with no silent wraparound. Where Lua and Go wrap; WASM traps; Rust panics in debug:
    • -x (OP_NEG), abs of x and x // -1 with x = INT64_MIN RAISE value (overflow);
    • INT64_MIN % -1 is 0, the correct result, computed without a hardware fault (x86 idiv faults on it).
  • N5 — Float→int conversions use Bitwise operands: adopt Lua's exact-integer rule (raise unless the number is an exact int64) instead of the interim INT64_MIN #1740's exact rule wherever an integer is needed (index, count, bitwise). (Lua §3.4.3)
  • N6 — Printing.
    • Integers print as exact decimal digits.
    • Floats print exactly as Python 3's repr(float):
      • the shortest digit string that round-trips;
      • fixed notation when the decimal exponent is between −4 and 15, otherwise scientific (1e+16, 1e-05);
      • .0 appended when the fixed form has no . (3.0, 1000000000000000.0);
      • -0.0 prints -0.0;
      • non-finite values print inf, -inf and nan. The spelling -nan never appears.
    • Python is the printing oracle. Lua is not: its %.14g does not round-trip.
  • N7 — (B), the Lua model.
    • type of 3 and type of 3.0 are both "num".
    • num_type of x returns "int", or "float", or null for a non-number (Lua math.type returns fail for a non-number).
  • N8 — Bitwise ops operate on ints (operands converted per N5).
    • Shifts follow Lua: a count of 64 or more gives 0, a negative count shifts the other way, and >> is logical. (Lua §3.4.2; probe: 1<<64 = 0, 1<<-1 = 0, -1>>1 = 9223372036854775807)
    • Bitwise results are 64-bit patterns and never raise overflow: 1 << 63 is INT64_MIN.
  • N9 — Width-parameterized wrapping, checked and saturating builtins for i8..i64 and u8..u64, plus unsigned compare, div, rem and to-string, plus fround for f32 (the matrix's "one design"). Bigint is a library (Python only).
  • N10 — num of reports parse failure instead of accepting partial input (num of a malformed string returns a number instead of raising: "12abc" → 12, "" → 0, "1_000" → 1 #1638), and accepts radix prefixes. Integer text outside int64 becomes a float, as in N1.

Floats

  • N11 — IEEE-754 doubles.
    • num_guard, the 1e308 ceiling and NaN→0 are retired.
    • sqrt of -1 is NaN and log of 0 is −inf. Lua, Go and WASM give NaN for sqrt of a negative; Python's front end can raise.
    • EIGS_STRICT becomes an opt-in trap mode, analogous to enabling IEEE 754's overflow and invalid-operation exceptions (§7.2, §7.4): it raises value when an operation on finite operands produces inf or NaN. Default today is strict-on, so this is a change.
  • N12 — NaN is canonical inside slots, so it can never read back as a tag (the Experiment: IEEE-faithful doubles (real inf/NaN, canonical NaN-boxing) with unchanged observer behaviour and deterministic replay #1746 single write path, and the JIT bails on NaN).
    • Payload fidelity goes through int64 bits: f64_bits of x returns the IEEE bit pattern as an int, and f64_from_bits of i builds the double from bits. Buffer elements are also readable and writable as bits.
    • Ints are never NaN-canonicalized, so a WASM f64.reinterpret_i64 / i64.reinterpret_f64 round-trip preserves the payload exactly.
  • N13 — Writers that have no representation for non-finite values refuse them themselves: JSON and store (raise value, write nothing) and every int conversion.
  • N14 — JSON (RFC 8259 has no inf or NaN).
    • json_encode of a non-finite value raises value (N13). It writes ints as digits and floats per N6 (3.0).
    • json_decode reads integer text inside int64 as an int, and integer text outside int64 as a float (N1).
    • A number whose magnitude overflows a double (1e400) RAISES value rather than decoding to inf.

Observer, in the same bump (#1667)

Tape

Surfaces that must move together (the #1637 touch map, extended)

  • The value representation: the reserved SMI tag 0xFFFA holds 48-bit ints inline, and a boxed int64 holds the rest.
    • A canonical-form invariant: an int that fits inline is never boxed. Equality, hashing and the tape depend on it.
    • It must be decided together with N12, because both live in the NaN space.
  • VM arithmetic, comparison and conversion, and the JIT fast paths (which mirror the interpreter: int add with overflow check, and bail on NaN).
  • The ouroboros AOT, the embed ABI (int constructors and accessors), and lint/LSP type knowledge.
  • Encoders: JSON, store and db.
  • The tape (T1) and the observer (O1–O4).
  • Every consumer: printing changes (N6), division and modulo (N4), and overflow (A).
    • The 16 acceptance consumers hold 54 type of … == "num" lines (58 checks) in 10 files, and those keep working under (B).
    • The consumers are fixed against the integration branch and land before the release.
    • ouroboros pins EIGS_REF to the merge SHA and lands its mirror with that pin, the mechanism used for Breaking change: a boolean type (#1637, value-model release phase 1) #1647 (ouroboros 1d5675e).
  • Docs and builds: SPEC, COMPARISON, LANGUAGE_CONTRACT, README and llms.txt; the playground/WASM build.

Done when

Every item names its command. "The v0.46.0 TAG" means a build of the tag commit 4a3a5c19, not main.

  • Semantics tests.
    • tests/phase2/MAP.md maps every N, O and T item above to the test rows that pin it.
    • Every mapped row FAILS on the v0.46.0 TAG and PASSES on the branch, under EIGS_JIT_OFF=1, the default JIT and EIGS_JIT_OSR_THRESHOLD=1.
    • Command: tools/phase2_check.sh <tag-binary> <branch-binary> prints examined=N rows tag_fail=N branch_pass=N for every tier, with N > 0.
  • Full suites. make test green; the ASan suite (make asan plus the suite) green; CI's TSan lane green.
  • Planted faults. tools/phase2_plants.sh applies each plant to a scratch copy and asserts that its named check turns RED:
    1. an int that fits inline stored boxed (canonical form);
    2. a NaN stored raw in a slot;
    3. a writer (JSON, store) accepting a non-finite value;
    4. + wrapping instead of raising on overflow;
    5. -INT64_MIN wrapping;
    6. num_type of 3.0 returning "int";
    7. a v6 tape accepted.
  • Tape. v7 is in place, and a committed v6 tape fixture is refused with a nonzero exit and a message naming the version. Int, float, inf and NaN programs record twice and replay strict byte-identically.
  • Observer. Done in two steps:
    1. Before R3 starts, the oracle PR lands:

      • an IEEE mode in which check_value accepts the generator's inf and NaN, and the reference arms see the held values;
      • int-literal rows (a counter, doubling to 2⁶², an INT64_MIN↔INT64_MAX swing);
      • loop forms run in all three tiers;
      • --floor FILE, which exits nonzero below any per-predicate TP or TN floor.

      The floors are measured on the v0.46.0 TAG at the post-Decide: the MATH definitions the observer oracle grades against (oscillating, improving, converged, equilibrium) and verify citations #1754 corpus, with the corpus sha256 recorded in floor.json.

    2. Done: make observer-oracle with --floor exits 0 on the branch binary.

  • AOT (ouroboros, at the merge-SHA pin): bash aot/test/run.sh all PASS, and python3 aot/fuzzdiff.py --count 500 --seed 1758 reports DIVERGENCES: 0 and HANGS: 0. Outputs are byte-exact except the ULP-marked float reductions (ULP_BOUND).
  • Consumers. tools/consumer_acceptance.sh run <branch-binary> passes for all 16 consumers, with EigenLua run under a timeout long enough to finish, stated in the run record.
  • EigenLua. EigenLua is re-graded on the release. The int64 D rows (int_maxinteger, int_past53, int_wrap, rng_xoshiro) and the math.huge row PASS, no previously passing row regresses, and the score is posted here.
  • Docs. Executable docs are updated and their suite sections are green. Pre-adoption: language decisions to settle while we are the only users (lessons from other languages' v1 regrets) #1286's numbers row links here.

Generated by Claude Code

Activity

  1. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    Owner decisions (Jon, 2026-10-14): "I'll go with your recommendations."

    • (A) Int overflow on + - * RAISES: a value error naming the operator. There is no silent wraparound. Wrapping, checked and saturating arithmetic is explicit through the N9 builtins (i8..i64, u8..u64), which the Lua, WASM and Go front ends use.

    • (B) The Lua model: type of 3 and type of 3.0 are both "num". A subtype query (proposed spelling num_type of x → "int" / "float"; final name decided in implementation, following Lua's math.type) exposes the kind.

    • (C) Under the distance observer:

      • where is x = the value's position (the value itself);
      • why is x = its last displacement Δv;
      • how is x = its settledness f(|Δv|), on the same relative scale the predicates use.

      Entropy is no longer computed for numeric bindings.

    Every item in the issue body is now decided; implementation can begin. The standard-answer items remain overrulable by the owner at any time.

    Generated by Claude Code

  2. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    Bar-critic report (blind, 2026-10-14), verdict DEFECTIVE. The body above is revised to address every item (Revision 1).

    Full report

    I did not write /home/jon/src/wt/bar-critic-EigenScript-1758.md, because my operating rules forbid writing report .md files. The full report is below. Save it there if you need the file.

    VERDICT: FAIL (DEFECTIVE). Below is the output I observed from the oracle the Done-when names (tools/observer_oracle/score.py at origin/main 0740af0).

    v0.46.0 tag binary, which reproduces the baseline:

    RUNTIME MATH: examined=51 rows, math_verdicts=291, agree=210, disagree=81
    RUNTIME CONVENTION: examined=51 rows, convention_verdicts=146, agree=126, disagree=20
    

    #1746 IEEE prototype (/home/jon/src/wt/briefs/es-1746-critic-r2/diff/bin_ieee/eigenscript), rc=2:

    OBSERVER_ORACLE_ERROR: geo_growth_1e20: V_16 generator overflowed to inf, runtime=inf (expected the clamp)
    

    Planted fault: an observer that reports every predicate as false (probes/gutted_observer.sh). The run exits 0:

    RUNTIME MATH: examined=51 rows, math_verdicts=291, agree=207, disagree=84
    RUNTIME CONVENTION: examined=51 rows, convention_verdicts=146, agree=107, disagree=39
    

    Copy of the in-flight relabel branch (es-obs-oracle2, two snapshots, same result), v0.46.0 tag binary:

    RUNTIME MATH: examined=51 rows, math_verdicts=292, agree=211, disagree=81
    RUNTIME CONVENTION: examined=51 rows, convention_verdicts=219, agree=187, disagree=32
    

    LARGEST GAP

    Done-when #4 ("make observer-oracle … at or above baseline (210/291, 126/146)") can neither pass on compliant work nor fail on degraded work.

    1. Any runtime that meets N11 makes it exit 2 before scoring. score.py:46 hard-codes CLAMP = 1e308. Line 128 demands the clamp wherever the generator overflows, and line 239 feeds the reference arms clamped values. N11 retires exactly that ceiling. The in-flight score.py has the same three lines and also exits 2.
    2. It never goes red on a bad score. The docstring says exit 0 "whatever the agreement". The planted fault exited 0, and the baseline (210) sits only 3 verdicts above that constant-false observer (207).
    3. The baseline is tied to a corpus that Decide: the MATH definitions the observer oracle grades against (oscillating, improving, converged, equilibrium) and verify citations #1754 is relabelling.
      • In closed form, moving stable from EIGS-DEFINED to CONVENTION adds its 73 checkpoints: 146 + 73 = 219.
      • On the relabelled corpus, unchanged v0.46.0 scores 187/219 = 85.39%. That is below the stated 126/146 = 86.30% when compared by ratio.
      • Compared by count instead, the gutted observer's 153/219 clears 126.
    4. It examines zero items for two things the bar adds.
      • Ints: 0 of 21,446 emitted literals are int-form under N1.
      • JIT: rows are straight-line code, and EIGS_JIT_STATS=1 reports [jit] scanned=0 compiled=0.

    Fix: land an oracle PR first and restate the item.

    • score.py gets an IEEE mode, alongside the existing clamp mode:
      • check_value accepts the generator's inf/NaN.
      • The reference arms see the values the runtime actually held.
      • My scratch patch at /home/jon/src/wt/bar-critic-EigenScript-1758/patched-oracle/score.py does this. The IEEE prototype scores 213/291 and 127/146; v0.46.0 is unchanged.
    • Add int-literal rows (a counter, doubling up to 2^62, an INT64_MIN↔INT64_MAX swing) and a loop form, run in all three tiers.
    • Add --floor FILE, which exits nonzero below per-predicate TP/TN floors.

    LAYER

    Oracle: the Done-when's grading instrument and its baseline. The brief names no previous-round gap to compare against.

    BLOCKING

    Yes. As written, Done-when #4 cannot pass on any artifact that satisfies N11.


    Checks 1–6

    1. Thresholds and run settings: FAIL

    • Baseline: the denominators move, and the bar does not say whether to compare counts or ratios (see above).
    • "Fails on v0.46.0": the binary is not named. The tag build (4a3a5c1) and the main build (ba77d91) both print 0.46.0 but disagree on N5:
      • 1.5 | 0 gives 1 on the tag;
      • it gives raised value: '|': number 1.5 has no integer representation on main.
    • fuzzdiff:
      • The bar demands "byte-for-byte", but fuzzdiff compares its reduction arm within ULP_BOUND = 32 (fuzzdiff.py:869).
      • No --count is given (the default is 100) and no --seed.
      • It is documented as "a manual tool, not CI".
    • EigenLua re-grade: there is no target score.

    2. External oracles and citations: FAIL

    • N1 (Lua §3.1): PASS. Lua 5.4.9 gives 9223372036854775808 → 9.2233720368548e+18 and 0x1FFFFFFFFFFFFFFFF → -1.
    • N2 (§3.4.4): PASS. Lua and Python both give 9007199254740993 == 9007199254740992.0 → false.
    • N4 floor division and modulo: PASS. Lua gives -4, 2, -2 and 0.5 for -7//2, -7%3, 7%-3 and -7.5%2.
    • N4 division by zero: PARTIAL. §3.4.1 says nothing about it. Lua's implementation raises (attempt to divide by zero, attempt to perform 'n%%0'). Python raises for floats too.
    • N8 (§3.4.2): PASS. 1<<64=0, 1<<-1=0, -1>>1=9223372036854775807.
    • math.type (§6.7): PASS, with a gap: non-numbers return fail in Lua, and the bar leaves num_type of a non-number undefined.
    • N6: FAIL. §3.4.3 says the number format is "non-specified". Lua actually prints 0.3, 1e+15 and -nan where Python repr prints 0.30000000000000004, 1000000000000000.0 and nan, so the two do not "agree". Python also prints 1e+16 with no .0, a case the item's wording does not carve out.
    • N11: PARTIAL.
      • The numpy docs say all also covers underflow, which produces finite results, so the analogy does not match.
      • "4 of 5" holds for sqrt (Lua, Go and WASM give NaN; Python raises). WASM has no log instruction.
    • N14 ("Python json"): PARTIAL. Python writes Infinity/NaN by default and decodes 18446744073709551615 exactly and 1e400 as inf. The bar decides none of those cases.

    3. Consistency between items: FAIL

    • (A) vs N1, N8 (1<<63 gives mininteger, no raise) and N9: consistent.
    • (A) vs INT64_MIN: FAIL.
      • Unary minus is its own opcode (OP_NEG, compiler.c:2191), so "+ - * on two ints" does not reach it. //, % and abs are not pinned either.
      • Lua, which N4 cites, wraps silently: -mininteger, abs(mininteger) and mininteger//-1 all give -9223372036854775808. Go wraps too.
      • WASM traps (divide result unrepresentable).
      • On x86, C idiv faults on INT64_MIN / -1 and also on % -1, whose correct answer is 0.
      • The owner's "There is no silent wraparound" is pinned by nothing for these four operations.
    • (B) vs N6/N14: consistent.
    • N11 vs N13: consistent. However, N12's "buffers keep payload bits" has no path that bypasses a slot. On the prototype, payload 0x7FF0…01 comes back as [127, 248, 0, …] through a variable, through a buffer, and directly.
    • T1 vs the ouroboros deferred-mirror rule: satisfiable. Precedent is ouroboros 1d5675e, which pinned EIGS_REF to the unreleased Breaking change: a boolean type (#1637, value-model release phase 1) #1647 merge SHA. But Decision: an exact int64 value kind and IEEE-faithful doubles (#1644 phase 2), with the observer signal (#1667) in the same tape bump #1758's "ahead of the pin bump" contradicts ouroboros's "never ahead of it" (CLAUDE.md:86), so the wording should name the SHA-pin mechanism.

    4. Populations: FAIL

    • "78 checks across 21 consumer files": this reproduces only as lines matching type of [^=]*== "num" across all ecosystem .eigs.
      • That count includes EigenScript's own lib/ and tests/ (23 lines in 10 files) and the archived iLambdaAi (1 line).
      • The 16 acceptance consumers alone have 54 lines (58 checks) in 10 files.
    • Evidence line "IEEE inf/NaN blocks Lua, WASM, Rust and Go": the matrix rows say "blocks 5/5", including Python.
    • "16 consumers": PASS. It matches EXPECTED in consumer_acceptance.sh.
    • Oracle invocation: make -n observer-oracle shows a release build, then python3 tools/observer_oracle/score.py src/eigenscript. That is one tier, default environment.

    5. Each Done-when item checkable by a command: FAIL

    6. Closest calls cited with margins: FAIL. The issue cites none. Observed margins:

    • MATH: the baseline is 3 above the constant-false observer.
    • CONVENTION: the IEEE prototype is +1 over the baseline.
    • Per predicate, oscillating (57/73) and improving (63/73) have a margin of 0.
    • Relabelled corpus: −0.91 pp below the stated CONVENTION baseline by ratio.

    How I verified each claim

    • By probe:
      • all the oracle runs above;
      • the planted fault;
      • the JIT stats;
      • PUC-Rio Lua 5.4.9 (EigenLua/.ref/bin/lua), Python 3.12, Go, and a WASM module under Node;
      • the N5 tag/main split and the NaN payload test;
      • the default strict-mode check;
      • the grep counts for the 78/21 claim.
    • By source or closed form:
      • Lua manual §2.1, §3.1, §3.4.1–3.4.4 and §6.7;
      • the numpy seterr docs;
      • score.py lines 25, 46, 128 and 239;
      • fuzzdiff's ULP bound and defaults;
      • the 219 count (146 + 73);
      • TRACE_FORMAT_VERSION 6;
      • the ouroboros pin history.
      • The Rust claims and the JSC/SpiderMonkey claim were not checked.

    Scratch files are in /home/jon/src/wt/bar-critic-EigenScript-1758/. I also left a worktree at /home/jon/src/wt/bar-critic-EigenScript-1758/es-main, detached at 0740af0; remove it with git worktree remove when done.

    Generated by Claude Code

  3. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    Q1–Q6 from the round-0 design (docs/design/phase2-numbers.md §11, branch phase2-numbers). Each is decided by the standard answer and verified by probe; the owner may overrule any of them.

    • Q1, N5's scope. The rule is decided by the PARAMETER'S MEANING, not by whether the C side happens to take an int.
      • Integer-valued parameters (indices, counts, sizes, byte values, handles, ports, seeds) follow N5: 1.5 raises value. Lua: string.sub("abc", 1.5) raises "number has no integer representation" (probed, 5.4.9).
      • Continuous parameters (gfx coordinates and sizes, colour channels given as numbers, durations, audio gain) accept floats. Where the C API needs an int, conversion rounds to nearest, documented per builtin, replacing today's truncation toward zero (which gets negative coordinates wrong).
      • This follows SDL3's float coordinates and LÖVE's numeric drawing API. No app that computes float positions breaks.
    • Q2, an int stored into float storage (buf_set, buf_from_list, copy_into, set_at on a buffer, stream_write): CONVERT with IEEE round-to-nearest, documented as the container's contract. A buffer is explicitly f64 storage, so the conversion is requested, not silent: Python float(2**53+1) gives 9007199254740992.0 (probed), and numpy and JS Float64Array do the same.
    • Q3, the embed API: follow Lua's C API exactly.
      • eigs_value_as_num(int) converts (lossy above 2⁵³, like lua_tonumber).
      • Add eigs_value_new_int.
      • Add eigs_value_as_int, which succeeds only when the value is exactly an integer in int64, with a success flag (like lua_tointegerx).
      • Add a kind query, eigs_value_is_int (like lua_isinteger).
      • EIGS_TYPE_NUM covers both kinds (like LUA_TNUMBER).
    • Q4, round. Precedent splits on ties: Python and IEEE use half-to-even (probed: 2, −2, 4), JS rounds half up (−2, 3), and C and Rust round go half away from zero. KEEP today's behaviour (half away from zero), so nothing churns for no gain. Following Lua's math.floor and math.ceil, the result is an int when it fits in int64 and a float otherwise (math.floor(1e300) stays 1e+300, probed).
    • Q5, why is x for an int binding: an int when Δv fits in int64, otherwise a float. A readout never raises; (A) applies to operators, not to observer readouts.
    • Q6, //=: ADD it beside /= (Python has //=; the compound forms follow their operators).

    Generated by Claude Code

  4. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    Observer oracle round 3: the capability rows Phase 2 must pass, and two semantics they leave open. Branch observer-oracle-defs, local commit 7f095a4, not yet pushed.

    tools/observer_oracle now has CAPABILITY rows. A row runs only on a binary whose probe shows its capability, and every scored verdict on it must be right, or the run exits 1. Skipped rows are counted and printed.

    • ieee rows. The probe is print of (0.0/0.0), which must print nan. Every non-finite value is computed in the runtime.
      • ieee_inf: x * 1e200 overflows to inf and holds it.
      • ieee_neg_inf: the same from -1, reaching -inf.
      • ieee_inf_alternating: x * -1e200 gives inf, -inf, inf, ...
      • ieee_nan: inf * 0 gives NaN, which then holds.
      • ieee_inf_recover: the value reaches inf, is reset to 10, and x/2 + 2.5 then tends to 5.
    • int64 rows. The probe is print of 9223372036854775807, which must print the same digits back.
      • int64_swing: INT64_MIN <-> INT64_MAX literals.
      • int64_count: x * 1 + 1 counted up from 2^53, compared bit-exactly.

    The #1746 IEEE prototype (bin_ieee, sha256 74852996...) gets 54 of 60 ieee verdicts right, identically in all four arms (interpreter straight/loop, JIT, OSR). Two of its misses contradict the prototype's own documented semantics in tests/ieee/observer.eigs on exp-ieee-p1:

    • ieee_inf_alternating@20 and @41 read diverging=true for an inf <-> -inf alternation computed in the runtime. The prototype's literal-value test asserts not diverging.
    • ieee_nan@3 and @30 read diverging=true while the current value is NaN. The test header says every predicate is false then.

    The other misses:

    • ieee_inf_recover@2 reads diverging=true, but the sequence has limit 5.
    • ieee_inf_recover@45 reads equilibrium=true, but the sequence is not constant.

    The int64 rows have not run yet, because no binary has int64.

    Two semantics the rows avoid deciding (owner questions for Phase 2):

    1. bounded for a sequence with an inf term. The oracle reads |x_n| < K literally: an inf term makes the sequence unbounded even when it has a limit. Only ieee_inf_recover depends on this, and its improving label is false either way.
    2. The whole-sequence predicates for a sequence that recovers from NaN. The certifier refuses such a row. It also refuses checkpoints that come before a NaN tail.

    Generated by Claude Code

  5. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    The two questions above are decided by the standard answer: limit notions depend only on a sequence's TAIL. Rudin 3.1 and Hardy §58–62 define convergence, divergence to ±∞ and oscillation by what holds for all n ≥ N, so finitely many early terms never matter. The owner may overrule.

    1. bounded, in improving's clause, means EVENTUALLY bounded: lim sup |x_n| < ∞.
      • The clause exists to exclude sequences that set new lows by coming apart, and coming apart is a property of the tail.
      • A sequence with finitely many inf terms that then settles (ieee_inf_recover) is eventually bounded.
      • inf ↔ −inf alternating forever is not.
    2. The whole-sequence predicates are tail-determined for NaN too.

    The oracle's next round labels the NaN-recovery rows the certifier currently refuses under this rule.

    Generated by Claude Code

  6. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    Q7 and Q8, raised by design round 2 (docs/design/phase2-numbers.md §11, branch phase2-numbers, commit 102e6634). The design parks both, so round 1 does not pick either one silently. Each needs the standard answer cited, or an owner decision.

    • Q7. A finite continuous parameter outside the C type's range.
      • Q1 decided that continuous parameters (gfx coordinates and sizes, colour channels, durations, audio gain) round to nearest where the C API needs an int. N13 already refuses a non-finite one, because that is an int conversion.
      • Q1 does not say what gfx_rect of [3e9, 0, 10, 10, ...] does. Today the cast is undefined behaviour (Builtins cast an out-of-range number to a C int unchecked (undefined behaviour): exit of 3e9 exits 0 #1763: exit of 3e9 exits 0).
      • Options:
        • (a) saturate to the C range: it draws off-screen, as a huge coordinate does in SDL3's float API;
        • (b) raise value, as N5 does for integer-valued parameters.
      • Until this is decided, R1.2 keeps today's truncation for these reads (behaviour-preserving), and the part of R1.6 that installs the rounding reader waits.
    • Q8. NaN in an ordering.
      • From R2.2 (num_guard retired), a NaN can reach sort, sort_by, min and max. NaN has no order.
      • Probed on Lua 5.4.9: math.min(0/0, 1) is -nan but math.min(1, 0/0) is 1. table.sort of a list holding NaNs returned without an error and left the list unsorted (0 2 3 -nan -nan 1 4 5 ...).
      • Probed on Python: sorted([3, nan, 1, nan, 2, 0]) gives [3, nan, 0, 1, nan, 2].
      • Options:
        • (a) raise value when a NaN is compared for order;
        • (b) a total order with NaN last, as IEEE 754 totalOrder (for a positive NaN) and numpy's sort do. min/max would then propagate NaN, as numpy's do.

    Generated by Claude Code

  7. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    Q7 and Q8, decided by the standard answer (probed; the owner may overrule):

    • Q7. A finite continuous parameter outside the C range follows the quantity it represents:
      • Geometry (coordinates and sizes): clip in FLOAT space against the drawable area, then round to nearest. Saturating each argument separately would be WRONG: gfx_rect of [-3e9, 0, 6e9, 10] saturated per endpoint covers half the screen instead of all of it. Clipping first is exact for every finite coordinate, the result a float-coordinate API (SDL3, LÖVE) gives.
      • Bounded quantities (colour channels, gain or volume): clamp to the domain, as CSS Color clamps out-of-range rgb() channels and audio APIs clamp volume.
      • Unbounded magnitudes the C call cannot honour (durations, sleeps): RAISE value, naming the builtin. Python time.sleep(3e12) raises OverflowError: timestamp out of range (probed).
      • Each continuous parameter's class (geometry, bounded, magnitude) is recorded in the design's builtin table.
    • Q8. NaN in an ordering: IEEE 754-2019 totalOrder. The canonical (positive, quiet) NaN sorts AFTER +inf, deterministically, in sort and sort_by. numpy sort([3, nan, 1, inf, 2]) gives [1, 2, 3, inf, nan] (probed); Rust f64::total_cmp is the same order.
      • min and max PROPAGATE NaN (IEEE 754-2019 minimum/maximum; numpy min([1, nan]) is nan, probed), as already decided.
      • Lua and Python produce a garbage order here (the design's probes). That is the silent-wrong this decision rules out.

    Generated by Claude Code

  8. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    Phase 2 Q1-scope note (blind design critic, round 2): buf_from_pcm16le's input bytes are byte values, but nothing in the design gives them the N5 / 0..255 rule.

    Probed on main (0740af03) and on the v0.46.0 tag (4a3a5c19); both print the same:

    b is buffer of 2 / b[0] is 300 / b[1] is 0
    buf_from_pcm16le of [b, 0, 1]      -> sample numerator 300 (no wrap, no raise)
    the same with b[0] is 1.5          -> numerator 1.5
    str_from_bytes of b (byte 300)     -> code 44 (wraps modulo 256); byte 1.5 -> "\u0001"
    
    • Two byte decoders already disagree on the same out-of-range byte.
    • Q1 makes byte values integer-valued (N5, then 0..255). The design's §6 table applies that rule to str_from_bytes, write_bytes, net_send, f64_from_bytes, inflate, gfx_fb and ppu_render_frame.
    • It classes buf_from_pcm16le as float-producing ("decodes bytes to floats"). Its two byte reads (builtins_buf.c:754 and :756, buffer_read_num) are among the 338 kept-token sites classed "a float by contract", so nothing forces them in round 1.
    • docs/BUILTINS.md:176 documents v = b0 + 256*b1 with no validation. This is therefore not a defect against today's contract; it is a gap in the Phase 2 table's Q1 scope.

    Done when

    • The §6 row for buf_from_pcm16le reads its bytes elements through the Q1 byte reader (eigs_byte_arg: N5, then 0..255).
    • A MAP row calling buf_from_pcm16le of [b, 0, 1] with a byte of 300, and again with 1.5, raises value on the branch and fails on the v0.46.0 tag.

    Generated by Claude Code

  9. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    Phase 2 design note from the observer-oracle critic (round 3, observer-oracle-defs @ 7f095a4): int64_count needs an exact raw-step floor for int bindings.

    int64_count is an ALL-CORRECT capability row: x is x * 1 + 1 counting up from 2^53. At checkpoints 10 and 60 its labels are converged false, stable false, diverging true and equilibrium false.

    The documented raw-step guard (docs/OBSERVER.md, #422) treats a step below 4·ε·(1+|x|) as floating-point noise. At 2^53 that floor is about 8, so a step of 1 reads as no motion. The float analog x_n = 2^53 + 2n (step 2, run in a loop while) shows this on both the v0.46.0 tag and the #1746 prototype:

    n=10 x=9007199254741012 converged=true stable=true improving=false oscillating=false diverging=false equilibrium=true
    n=60 x=9007199254741112 converged=true stable=true improving=false oscillating=false diverging=false equilibrium=true
    

    An observer that keeps that floor for ints gets 4 of 6 verdicts wrong at both checkpoints, and the oracle exits 1. Ints carry no rounding noise. If an int binding uses a raw-step floor of 0:

    • the non-vanishing, same-sign steps of 1 read diverging;
    • that excludes the rest bands, so converged, stable and equilibrium read false;
    • this matches the labels without any corpus-specific rule.

    Recorded here for the Phase 2 observer work (O1/O2). The oracle's labels for this row are correct for the integer sequence.

    Generated by Claude Code

  10. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    Two Q7 classifications made in design round 3 (docs/design/phase2-numbers.md §6 and §11, branch phase2-numbers, commit e3c9b23c), recorded here so the owner can overrule them.

    The Q7 decision defines geometry as "coordinates and sizes: clip in float space against the drawable area". Two continuous parameters are sizes, but there is no drawable area to clip them against:

    • gfx_open's window width and height: the size defines the drawable area;
    • the scale of gfx_text_width / gfx_text_height: a measurement that draws nothing.

    The design classes both as magnitudes: rounded to nearest, and a value the C int cannot hold raises value naming the builtin. This is the decision's definition of a magnitude, "a quantity the C call cannot honour". All other continuous parameters keep the class the decision names for them.

    Generated by Claude Code

  11. InauguralPhysicist commented on Oct 14, 2026

    @InauguralPhysicist
    MemberAuthor

    For the IEEE-faithful doubles (Phase 2): number text drops the sign of zero. Found by the code review of #1769 (its V36) and confirmed in that PR's fix round.

    x is -0.0
    print of x                      # prints 0
    print of (atan2 of [x, -1.0])   # prints -3.141592653589793: the value IS -0.0
    

    The output is the same on v0.46.0, main (b125225d) and the IEEE prototype. The cause is eigs_num_text (src/eigenscript.c, the #875 number->text rule): any exact integer below 2^53 prints through %lld, and -0.0 == (long long)-0.0, so -0.0 prints as 0.

    LANGUAGE_CONTRACT.md's num of (str of x) == x still holds, because -0.0 == 0.0. The sign does not round-trip, though, and under IEEE-faithful doubles it is observable: 1 / x is -inf for one zero and +inf for the other.

    Mature languages differ here. Python (-0.0), Lua (-0.0) and Go (-0) print the sign; JavaScript's String(-0) is "0". So this is a decision, not an obvious bug.

    Until it is decided, the observer oracle reads each zero's sign through atan2 on the test side (commit 11939a04 on observer-oracle-defs); it does not depend on the decision.

    Proposed Done-when line for this issue: the number-text rule's treatment of -0.0 is decided and pinned by a suite assertion (str of -0.0, and 1 / (num of (str of -0.0)) on the IEEE build).

  12. 283 remaining items

  13. InauguralPhysicist commented on Nov 6, 2026

    @InauguralPhysicist
    MemberAuthor

    ACCEPTED: R3.2 at 54008422b7bb4950131f4dd4d15ead942a2ecb2e (phase2-numbers). — Claude DevBox, 2026-11-06

    Both conditions hold at this exact head.

    1. Hosted train: every check-run green except the named exception.

    • 76 check-runs: 66 success, 9 skipped, 1 failure.
    • The one failure is the CodSpeed app check, the named R5 exception.
    • The 9 skipped are the pull-request run's placeholders for lanes that the lanes=all dispatch ran under their real names, plus deploy and the queue-promotion jobs. In the dispatch run: 33 jobs success, 1 skipped.
    • Bench gate: no instruction-count regressions vs reference (threshold 0.5%; declared rows applied=31; measured rows=31).
    • phase2 (MAP + builtins + readers + lib): green on the push and on the dispatch run.
    • Gate self-tests: selftests: 80 passed, 0 failed in both runs. tools/phase2_plants.sh passed with its pins ocfg-plants=37 killed=37 survived=0 broken=0 transverse=37 and ocfg-unplanted=37 expected=37, in 2,318 s and 2,734 s (4,188 s at the previous head with 33 plants). The job took 55 and 64 minutes of its 90.

    2. Blind critic: PASS (the seventh critic pass, on round 7 of the build), all eight items.

    • The row: 372 examined, 0 mismatches, in four tiers; the transcript only adds lines.
    • The sixth critic's three survivors and the free(q0) mutant are each red in all four tiers on their own case.
    • The generator's counts recount exactly; a random sample of six red and four non-building mutants confirms.
    • The 42 survivors argued equivalent: one built mutant per group and 45 adversarial inputs, all identical to the head. The premise two groups rest on (the state values hold their defaults whenever a tape is read or a fold begins) holds in every client; the critic also showed both checks can see a difference when the premise is broken.
    • rec + 1 is red only on the new placement, rec - 1 only on the old.
    • The plant runner's checksum guard catches a planted stale binary; with the guard disabled the same stale binary is a false kill.
    • The critic's own four mutants: two equivalent, two outside the operator set.

    What R3.2 now is (design O3). The tape's observer-configuration record carries exactly dh_zero dh_small window scale (format 10). A reader refuses any other field count by name, before installing anything, with exit 3. h_low is gone from the tape and from state; the entropy readers and get_observer_thresholds use the compiled constant 0.1. src/ has not changed since round 1 (binary 4b39c6ff…0720). The contract is one row of 93 cases in four tiers, a direct-read check in the embed test, and 37 named plants.

    How it got here.

    • Rounds 1 to 3 (builder): the change, the installation witnesses, the start-state and entropy witnesses. Three critic FAILs, each a one-token mutant of a line R3.2 wrote that passed every case (R32-1 to R32-3).
    • Rounds 4 to 7 (orchestrator, test-only): the sampling was replaced by enumeration over a stated line set and operator set. Four more critic passes each found the enumeration narrower than I had said it was: an equivalence claim a direct read refutes (R32-4), a tolerance that exact equality through a snapshot dict refutes (R32-5), a hand-written identifier table (R32-6). Round 7 derives the identifier class from the code (6,231 mutants) and passed.
    • Every critic FAIL after round 3 was a gap in my rulings or my sweep, not in the builder's work.

    Carried forward, visible through R5.

    • The CodSpeed app check exception.
    • 31 declared instruction-count rows, all recover_round=R5.
    • Tape reader: corrupt O records that are skipped or accepted instead of refused (unknown subtype, non-canonical numbers, embedded NUL) #2334: unknown O sub-records skipped, non-canonical numbers, the O win narrowing, a folded O record never pinned as not stored, and which stop owns a record that sits between two stops (the row pins what tape_read.h and the code say; docs/TRACE.md is ambiguous).
    • The oracle floor is blind to the entropy threshold (R32-2): it prints the same count with h_low at 0.01 or 10.
    • Outside the sweep's model, stated: the stepper's save and restore observed directly; the unreachable writer; the dead condition at eigenscript.c:1887; tr 315 (a leak on a path that exits 3); function swaps other than ctype; type-name changes other than three float declarations; multi-token edits.
    • The seventh critic's largest note: the generator takes swap candidates from identifiers that appear in the enclosing function, not from every name visible at the line. It built 29 of the missing names at one refusal line: 11 do not build cleanly, 5 are red, and 13 pass; all 13 are NULL in the stepper, so free of them only leaks, the tr 315 class. No in-model survivor, but the class is narrower than "in scope"; the next sweep should take candidates from the preprocessed declarations.
    • Three smaller critic notes: a plant rejected for a build warning is not added to the checksum guard's list; the comment on cfg-valid-then-5-fields describes a build-dependent fact about the mutant, not the head; and O 0 cfg 0.001 inf 10 0.001 is accepted (dh_small is not required to be finite), which is long-standing and now on Tape reader: corrupt O records that are skipped or accepted instead of refused (unknown subtype, non-canonical numbers, embedded NUL) #2334.
    • One line of the design's builtin table changed its note in round 1 ("O3 drops h_low" → "O3 drops h_low from the tape only"); no arm, split or decision rule moved.

    Next: R3.0-R (#2330).

  14. InauguralPhysicist commented on Nov 6, 2026

    @InauguralPhysicist
    MemberAuthor

    RULING R30R-2 (2026-11-06): the outcome mapping for the Round 3 reveal, made total. Deviation D12, recorded before any H1 row exists.

    The R3.0-R builder stopped before writing the driver, as its brief told it to: the pre-registration's "Outcomes" (comment 6430031838) and the amendment (6430139845) do not give one outcome for every combination of rule results. It showed three cases with the frozen judge.decide() on synthetic statistics, and a fresh-context reviewer confirmed each from the texts alone. No arm was built or scored, and the frozen files are unchanged. The stop was right.

    The three gaps.

    1. R3 beats INC under rule 2, misses the margin against R3-STD, and fails rule 3 (safety). "It fails criterion 2, 3 or 5 against INC: INC's band stays" and "Otherwise R3-STD ships" both apply, and nothing orders them.
    2. The amendment's step 3 says "any further divergence from STD_p in a predicate" must beat R3-STD by the registered margin. Its last paragraph, and the frozen judge, apply that comparison to converged and stable only.
    3. Rules 1 to 5 pass and only rule 6 (existing gates) fails. No listed outcome covers it. The same holds when only rule 4 fails: the text opens an issue and says nothing about what ships.

    The ruling. Three principles, then the table. Nothing here adds a criterion or moves an arm, a split, a margin or a threshold.

    • Each band ships on its own verdict. The frozen judge already scores two subjects, R3 and R3-STD, each against all six rules. A band ships for a predicate only if the arm that carries it passes all six rules for that predicate itself.
    • The fallback follows the amendment's order: the language, then the device, then the incumbent. R3 is the further divergence on top of R3-STD. When R3 does not ship for p, its divergence for p is reverted, which leaves R3-STD's test, and that ships only on R3-STD's own verdict. Otherwise INC stays.
    • The reporting duties are additive. They never decide what ships.

    For each predicate p, first match:

    # condition (the judge's verdicts for p) what ships for p registered sentence it applies
    1 subject R3 passes all six rules (rule 2 as amended: against INC, and against R3-STD for converged and stable) R3's band "All six criteria pass: R3's band ships."
    2 otherwise, subject R3-STD passes all six rules (rule 2 against INC, as first written) R3-STD's test; R3's further divergence for p is reverted "Otherwise R3-STD ships for that predicate."
    3 otherwise INC's band stays; every Round 3 change to p is reverted "INC's band stays for p, R3's change to p is reverted, and the table is posted."

    Duties, from subject R3's results, whatever ships:

    • The table is always posted, with both subjects' rule results for every predicate.
    • R3 fails rule 4 for p: a kind:silent-wrong issue is opened and docs/PREDICATES.md states the measured BA (as registered).
    • R3 passes rules 2 to 5 for p but fails rule 1: the STD_p replacement is scored on a fresh sealed H2 (as registered). What ships in the meantime is rows 2 or 3.

    How each gap closes.

    1. Gap 1. R3 fails rule 3, so row 1 does not match. R3-STD is then judged on its own results. R3's safety failure says nothing about R3-STD's false-positive rate; R3-STD's own rule 3 does. The sentence "INC's band stays" was written before the amendment made R3-STD an arm; it still holds whenever R3-STD does not pass.
      • One consequence, stated so it is not a surprise: "Otherwise R3-STD ships" is read as "R3-STD ships if it passes the registered rules as a subject". An R3-STD that fails safety, the floor or unit invariance on H1 does not ship because R3 failed to beat it.
    2. Gap 2. The comparison against R3-STD applies to converged and stable, as the amendment's last paragraph says ("Under decision rule 2, converged and stable are therefore judged against R3-STD as well as INC … Every other rule stands") and as the frozen judge does. Rule 2 has a margin only for those two. For the other four, a divergence is held by the rules as written: rule 1 keeps R3 within 0.05 of STD_p (which is the test R3-STD starts from for improving), and rule 2 keeps it within 0.02 of INC. The driver adds no comparison outside the judge.
    3. Gap 3. Rule 6 is one fact about a build, not about a predicate: --floor exits 0, the Observer: int64_count has 32 wrong capability verdicts above 2^53; floor preserved #1830 declaration list is empty, and the subject has every registered capability (D11). The judge evaluates it per subject, so a subject that fails rule 6 fails "all six" for every predicate and the table falls through to the next row. Rule 6 needs no H1 row, so the driver also checks it first:
      • Preflight. Before the beacon round is read, the driver evaluates rule 6's inputs for subject R3 at its declared SHA. If they fail, the run is REFUSED: no seed is drawn, no H1 row exists, and the SHA is not final. A red floor is fixed before the reveal, not judged by it.
      • R3-STD's SHA is fixed (3eed5caf). If its rule 6 fails, that is reported and R3-STD does not pass row 2.
      • A rule-4-only failure is the same shape: R3 does not pass all six, so rows 2 and 3 decide, and the duty above applies.

    VOID (a control fails), INCOMPLETE (a roster gap, or the judge exits 2) and a FINDING (the judge exits 1) stay as the brief has them: no outcome is printed.

    What this changes for the driver. The outcome is a function of two judge verdicts per predicate (subject R3, subject R3-STD) plus the two duties. The selftest gets one fixture per table row, one per duty, the three gap cases above as named fixtures, and the preflight refusal.

    Who can change this. It is a reading of the owner's rule ("the standard measurement first, then the device, then the language") where the registered text is silent. Jon can overrule any part of it until R3.3's final SHA is posted; after that it is frozen with the rest of the pre-registration. Two parts are real choices and are flagged to him: row 2 over the literal "INC's band stays" in gap 1, and the scope in gap 2.

    — Claude DevBox

  15. InauguralPhysicist commented on Nov 6, 2026

    @InauguralPhysicist
    MemberAuthor

    RULING R30R-3 (2026-11-06): which score.py is the frozen one, and three smaller answers from the builder's second stop. Deviation D13, recorded before any H1 row exists.

    The R3.0-R builder's second round stopped again, correctly (r3-0r.report.md, STOP-4). Its Dry A built the Phase 2 subject 3eed5caf by recipe, put it in both subject slots, and ran RULING R30R-2's rule-6 preflight. The preflight ran score.py --floor from the builder's own tree, a clone of main at bc509681, and that scorer refused the build with rc 2: VACUOUS: 236 JIT-tier run(s) did not run their loop body natively and stopped on finite values, first ['jit issue1891_row63@10: stops at no thunk (bked=10)']. No beacon was read, no H1 row exists, nothing was scored, and no frozen file was changed. R30R-1 says score.py does not change; it did not say which copy. This ruling names it.

    The facts.

    • The instrument PR (R3.0-I, observer oracle: the Round 3 instrument of #1758's pre-registration (R3.0-I) #2331) landed on main at 96e15c33 and was merged into phase2-numbers at c8e59616 (2026-11-04). families.py (sha256 3acedd90…), standard.py, judge.py, certify.py, derive.py, reference.py and seal.py are byte-identical on the two branches today (git diff bc509681 54008422 -- tools/observer_oracle/ names only score.py, ci_lane.sh and plants.py).
    • score.py differs. The phase2-numbers copy is main's copy plus Phase 2's int64 work: float loop scaffolding and float recurrence operands for every row "as on the pinned pre-int anchor", exact count parsing, the explicit INT-opcode refusal witness for int64 rows until R5, and the --declared FILE flag (Observer: int64_count has 32 wrong capability verdicts above 2^53; floor preserved #1830). Those changes were made on 2026-10-19 and 2026-10-26 (3dd9f2b2, 198c1919, f406359c), all before the pre-registration was posted (2026-10-26 23:45Z). The copy has been byte-identical since c8e59616: blob 9ba62101, sha256 e74b1c84d5e2e7f019e946d4cd4807fd418c67d7541ee5c1bde1063d1bc267e4, the same at 3eed5caf (R3-STD) and at 54008422 (today's head).
    • main's copy (blob 26970375) predates int64. Its loop scaffold counts with int literals; on an int64 runtime those are INT_* opcodes, which the JIT refuses until R5, so the JIT tier never runs the body natively and the scorer's own witness rule calls every such run VACUOUS. The same scaffold drives every row, so the refusal is not about the floor: main's copy cannot score a Phase 2 build on any corpus.
    • The pre-registration's rule 6 reads "--floor exits 0, and Observer: int64_count has 32 wrong capability verdicts above 2^53; floor preserved #1830's declaration list is empty", and its preamble says "Its gate today is non-regression against v0.46.0 (--floor) plus the Observer: int64_count has 32 wrong capability verdicts above 2^53; floor preserved #1830 declarations." --declared exists only in the Phase 2 copy. The rule was written about the gate observer oracle (floor) as it runs on phase2-numbers: score.py <candidate> --floor tools/observer_oracle/floor.json --declared tests/phase2/oracle_expect.txt, followed by judge.py --calibration on the candidate and the anchor. That job is green at 3eed5caf and at 54008422, which is also the evidence that this copy drives both an int64 runtime and the pre-int anchor through the frozen judge.

    The ruling.

    1. The frozen score.py is the Phase 2 copy, sha256 e74b1c84…. The driver takes it from the R3-STD checkout (3eed5caf, a SHA the amendment already fixes), asserts the sha256 before anything runs, and uses that one scorer for every runtime arm: ANCHOR, INC, R3-STD and R3. The other frozen files it takes from its own tree, where they are identical to both branches; the manifest records every hash. No instrument file changes on any branch.

    2. Rule 6 is the gate as CI runs it at the subject's SHA. The preflight for a subject is: its own tree's floor.json and tests/phase2/oracle_expect.txt, the pinned scorer, --floor exit 0, and a declaration file with no data rows; plus the D11 capabilities per R30R-2. REFUSED before the beacon, as R30R-2 says.

    3. Step 1 is repeated, as the pre-registration says, and it is cheap. Step 1 scored ANCHOR and INC on the calibration corpus with main's copy (out/r30i/r3_judge_calibration.log). Before Dry A, the builder scores ANCHOR and INC on the calibration corpus and H-cal again with the pinned scorer, through the frozen judge, same resamples and seed, and writes both tables beside the step-1 tables with a line per predicate saying whether every reading and every number is identical. The orchestrator posts that on Decision: an exact int64 value kind and IEEE-faithful doubles (#1644 phase 2), with the observer signal (#1667) in the same tape bump #1758 as the repeated step 1. If every reading is identical, the two copies were one instrument for a pre-int runtime and D13 says so. If any reading differs, the difference is posted, the pinned scorer's tables are the step-1 tables from then on, and nothing else moves: the H1 commitment, the rules, the margins and the arms are untouched, and R3's SHA is still not final.

    4. Dry B's stand-ins (R30R-1 item 2). In --dry only, and only when a subject slot holds INC (v0.47.0) or ANCHOR (v0.46.0), the preflight records rule 6 and the capability check as NOT APPLICABLE (stand-in) and does not refuse; every outcome line already carries the DRY prefix and decides nothing. Outside --dry the exemption does not exist, and a Phase 2 SHA in --dry on an H1 draw is still refused, as R30R-1 requires. The selftest pins all three.

    5. The manual-argument templates (scope 4). The round's blind critic, who is independent of the builder, reviews them; the orchestrator records verdict, reviewer and date in the review record. The production records stay blank until the reveal's blind review, as registered.

    6. The sweep. The builder's bar is unchanged: full enumeration on the final source, every survivor argued or killed. 247 green fixtures with a partial sweep is not acceptance.

    What this is not. It adds no rule, moves no margin, threshold, split or arm, and touches no file in the instrument. It names the copy of one instrument file that the registered rule 6 already names, and it repeats step 1 because the text says to when the instrument's identity is in question. The step-1 repetition is the check on this ruling: if the pinned scorer reads a pre-int runtime differently from main's copy, that will be posted, not argued away.

    Who can change this. Jon can overrule any part until R3.3's final SHA is posted. The part that is a real choice: pinning the scorer to the Phase 2 copy rather than carrying main's copy forward and building a third one that drives both runtimes. The second road is a new instrument file written after the pre-registration, by people who have seen H-cal, and the first is a file that existed before it; that is why I chose the first.

    — Claude DevBox

  16. InauguralPhysicist commented on Nov 6, 2026

    @InauguralPhysicist
    MemberAuthor

    RULING R30R-4 (2026-11-06): the builder's third stop (STOP-5, family 9's equilibrium label), the repeated step 1, and four smaller answers. Deviation D14, recorded before any H1 row exists.

    The R3.0-R builder's third round ran the repeated step 1 (R30R-3 item 3), ran Dry A to a printed status, and had the manual-argument templates reviewed by a fresh-context reviewer independent of it. That reviewer approved all 17 templates for the three claims they certify (limit, tends_to, bounded) and found one thing the templates do not cover: family 9's equilibrium label. The builder stopped, as its brief says, because the smallest fix it could name touches families.py. No frozen file changed, no beacon was read, no H1 row exists.

    1. STOP-5, the finding. F9 is "a stationary AR(1)": x <- mu + phi (x - mu) + sigma u, u iid uniform on [-1, 1], phi drawn from [-0.9, 0.9], started at x = mu and burned 200 steps before the first retained value. Its equilibrium label is true (variance_changes=False, derived by derive._equilibrium). The reviewer's exact arithmetic: started at mu, the process has mean exactly mu at every step, but Var(x_n) = sigma^2/3 * (1 - phi^(2(200+n))) / (1 - phi^2), which rises by sigma^2/3 * phi^(2(200+n)) per step, strictly positive for every phi != 0. A finite burn approximates the stationary process; the label asserts it. docs/PREDICATES.md states no tolerance. The finding is correct.

    2. The ruling: the label stands; the tolerance is stated and pinned. Both the mean and the autocovariance of the generated process differ from the stationary process only through the factor phi^(2(200+n)). Over everything F9 can draw (|phi| <= 0.9) that factor is at most 0.9^400 = 4.98e-19, which is below 2^-53 = 1.11e-16, the relative resolution of a double, by a factor of 223. The generated variance is therefore within one unit in the last place of the stationary variance at every retained step, for every row F9 can produce, and no sequence of doubles can carry evidence of the difference. The F15 copies of F9 (×0.001, ×1000, and the F15b bases) scale the values and leave the ratio unchanged.

    • Deviation D14. The labels of the stochastic families describe the generating process up to deviations below double resolution: a property holds for the label when every moment the predicate's MATH question names agrees with the asserted value to within 2^-53 relative, for every parameter the family can draw. F9 is the only family where this clause does anything; F8 (iid) is exactly stationary and F10 (a walk) is labelled with its variance growing. The deterministic families are certified exactly, as before.
    • Pinned, not argued. The driver computes, in exact rational arithmetic, |phi|^(2*burn) < 2^-53 for every F9 row (and every F15 row built on one) in the sealed H1, from the row's own phi and burn, before any arm is run. A row that fails it is refused by name and the run is INCOMPLETE. The selftest plants a phi just inside and just outside the bound (0.9 passes; a phi with phi^400 >= 2^-53 fails, and burn changed to a value that breaks the bound fails). The bound is the deviation's whole content; this makes it a check rather than a sentence.
    • Not done: the flag is not flipped. variance_changes=True would make the label say the process is not in equilibrium, which is false at every resolution the data has, and would turn a correct equilibrium answer on F9 into a scored error. families.py stays byte-identical at 3acedd90…; the generator is not changed either (no finite method samples the exact stationary distribution of a uniform-innovation AR(1), and a longer burn would move the committed generator for nothing the data can show). docs/PREDICATES.md gains D14's sentence in this round's docs group, beside the equilibrium row.

    3. The repeated step 1 (R30R-3 item 3): the two scorers are one instrument for a pre-int runtime. ANCHOR and INC were scored on the calibration corpus and H-cal through the frozen judge, 10,000 resamples, seed 1758, once with main's score.py and once with the pinned Phase 2 copy (e74b1c84…), everything else identical. Every reading (392 per predicate) and every table number, confusion cells, BA, CI bounds and FPR, is identical for all six predicates (out/r3-0r/step1-repeat/comparison.txt, main-judge.log, pinned-judge.log). D13 therefore records no measured difference; the pinned scorer's tables are the step-1 tables, and they equal what main's copy prints at the frozen instrument.

    The builder also compared against the older R3.0-I log out/r30i/r3_judge_calibration.log: confusion cells, BA and FPR are identical to it for all six predicates; the CI bounds differ in the third decimal (for example converged ANCHOR [0.6881, 0.8004] then, [0.6893, 0.8000] now). That log predates the instrument that was merged: its header names families.py a53f1037…, standard.py 91be771a… and an H-cal corpus af06b086…, where the frozen instrument has 3acedd90…, 3830286c… and 47f9fedd… (the R3.0-I critic rounds after that log changed them, and the judge's bootstrap with them). It is not the frozen instrument's table. The frozen instrument's own table is the one both scorers print now.

    4. Dry A's status is INCOMPLETE, and that is the registered answer on H-cal. H-cal has no family-15 rows, so rule 5 is NOT EVALUATED, and no positive diverging or equilibrium label, so those two BAs are undefined and control (b) cannot be checked for them. The judge prints the tables and the driver prints no outcome, which is what R30R-2 says for INCOMPLETE. Nothing is forced to COMPLETE, nothing undefined is read as 0.5, no family-15 data is invented. Two consequences, stated now:

    • The pull-request dry run of observer-reveal.yml (scope 3) passes exactly when the driver runs to a printed status that is INCOMPLETE with no reasons other than these two (rule 5 unevaluated for want of family-15 rows; BA undefined for diverging and equilibrium for want of a positive class). Any other reason, and REFUSED, VOID or a FINDING, fails the job. The selftest pins both sides.
    • The end-to-end exercise of a COMPLETE run on real data is Dry B: the seal path on a published round with INC in both subject slots (R30R-1 item 2, R30R-3 item 4). It has every family and is mandatory before delivery.

    5. Control (c1) must fail through a rule about readings. Under D11, W4 (built from INC) lacks int64 and ieee, so rule 6 FAILS and rules 1, 3 and 4 are not evaluated for it, whatever its window does. D5 wrote (c1) as "the W4 build must FAIL the decision table (it does, by rules 2/3)". A failure by rule 6 alone says nothing about the window, so it does not satisfy (c1). (c1) holds when W4 FAILS at least one of rules 1 to 5 that the judge evaluated for it on converged; rule 6's result is recorded and does not count. (c2) stands as D5 has it and remains the control that resolves the margin.

    6. Control (a) ran against the wrong root. The driver stages the instrument files in its own directory and reloads them from there; plants.py --selftest derives the repository root from its own path and runs make … observer-anchor there, where the stage has no Makefile. That is a driver defect, not an instrument one: the stage must carry the unchanged build context the frozen entry point needs, and the selftest must exercise the real entry point, not a mock of the control's command. The builder's fix is in progress and is not accepted until Dry A shows control (a) true through plants.py itself.

    7. The manual-argument review record. The review was done by a fresh-context Codex reviewer spawned under the build loop, independent of the builder, from product files only (out/r3-0r/blind-review-round3.md; it read the Wenocur–Salant source for F10 itself). I record its verdict, APPROVED for all 17 templates, with that reviewer's identity and the evidence path, in out/r3-0r/manual-review-verdicts.json; the builder copies the fields into tools/observer_oracle/manual_review.json unchanged (the inventory check verifies every hash) so that Dry B can run. The round's blind critic re-reviews the 17 arguments as an item of its bar, blind to this record; its verdict is appended before the reveal, and a disagreement reopens the entry. The F9 entries carry D14 in their note: the argument certifies bounded and no limit, and the equilibrium label rests on D14, not on the argument.

    What this does not do. No rule, margin, arm, split, threshold or seed moves. No instrument file changes. The one new sentence (D14) is a stated tolerance that was implicit in using a finite generator, made exact and made into a check the driver runs on every F9 row before any arm is scored.

    Who can change this. Jon can overrule any part until R3.3's final SHA is posted. The real choice is item 2: keep the label with a pinned tolerance below double resolution (this ruling) or flip the flag and re-commit families.py. The second makes the label false at the data's resolution to make it true in exact arithmetic; I chose the first because the predicates are judged on doubles.

    — Claude DevBox

  17. InauguralPhysicist commented on Nov 7, 2026

    @InauguralPhysicist
    MemberAuthor

    RULING R30R-5 (2026-11-07): the blind rule-derived tests found two disagreements between the referee and the rules. The census is stopped; the driver is fixed; the final census restarts on the fixed source. No frozen file changes.

    Under ACCEPTANCE ADDENDUM R30R-A1 item 1, a Claude-family tester with no access to the driver's source, the selftest or the sweep drivers wrote 216 tests from the pre-registration, the rulings and docs/PREDICATES.md, and ran them against the referee's public functions (out/r3-0r/rule-tests/). Result: 191 PASS, 8 FAIL, 17 AMBIGUOUS, 23 UNCOVERED; VERDICT: DISAGREEMENT FOUND. The judge's rules 1–6 matched the text at every margin, both sides; so did the amendment's R3-STD comparison, D11, the R30R-2 shipping table and duties, the status and controls logic, the stand-ins and the D14 bound. The two disagreements are in the driver, not the frozen judge.

    F2 (blocking). Extraction trusts the recorded status. reveal.extract takes raw['status'] and each subject's verdict as given. A raw that says COMPLETE with one rule list cut to 2 of its 7 entries, or empty, or with no controls record, or with controls.b = False, or with zero H1 rows, or with no preflight record, extracts to status=COMPLETE and ships R3 for all six predicates, and write_outputs prints six OUTCOME lines. decision.json and the byte-identical replication are built from extract, so this is the path the public verdict comes through. Ruling: extraction re-derives the status from the raw's own evidence (status_for on the recorded controls, judge exit codes and verdicts) and refuses when the re-derived status differs from the recorded one; every subject's rule list is checked against the registered names for that predicate (seven for converged/stable, the registered set for the others) and refused when any is missing; a raw with no controls, no preflight, or zero H1 rows is refused. Refusal means exit 2, no decision.json, no OUTCOME line. The selftest pins each of the seven inputs (X.3–X.8, X.10).

    F1. The Dry A gate cannot tell a failed control from an uncheckable one. controls_ok stores an undefined constant-false BA as b = False, and dry_a_ok requires b == False; so a constant-false arm scoring BA 3/5 on stable (a real control-(b) failure, VOID on H1) still passes the PR dry job with exactly the two registered reasons. Ruling: control (b) is recorded tri-state, true, false, or undefined with the list of predicates it is undefined on; dry_a_ok passes only when (b) is undefined on exactly diverging and equilibrium and true on the other four; false fails the job. On H1, false is VOID and undefined is INCOMPLETE, as R30R-4 item 4 already says. The selftest pins both sides.

    Resolved from the rule text (AMBIGUOUS items that are the driver's to fix).

    • D11.absent: a subject with no capability record is treated as lacking both capabilities (rule 6 FAILS), never as fully capable. PF.5: a capability value that is not a boolean is refused by the preflight. Both fail closed.
    • D14.14: the D14 check resolves every F15 and F15b row to its base family through the wrapper; a row whose base family cannot be resolved is refused by name, not skipped. The tester saw a non-ar1 kind skipped silently.
    • R6.6: the frozen judge.rule6 passes only on the string "0". The frozen file does not change. The driver passes the floor exit as the judge expects (Dry A's table already reads PASS: --floor exit 0 for the capable subject), and one fixture pins the value's type at the call so a future driver edit cannot turn every subject's rule 6 into a FAIL.
    • O.14, G.9, G.10, S.12, O.13, A.6, R3.10: consistent with the rules as read; no change.

    Addendum items carried into this round. R30R-A1 item 3 (fail-closed on a kill during H1 scoring in --dry: no decision.json, no OUTCOME, no stale result reused; the tester's X.13 stub names the command) and item 2 (the rule-to-test checklist with the 23 UNCOVERED entries each covered by a named fixture or argued in the acceptance post; a synthetic win of known size at the rule-2 margin).

    The census. The running census (source 967a1500…, 190k of 387,133 at the stop) is evidence about a referee that is not the final one. It stops now. The equivalence proposals and the sixteen fixtures it produced carry forward where the lines are unchanged; the final census runs from mutant 0 on the fixed source, as R30R-3 item 6 requires. The blind tests are re-run against the fixed source before the census starts; a FAIL there stops the round again.

    What this does not do. No rule, margin, arm, split, threshold or seed moves. No instrument file changes. The fixes make the driver refuse what it previously accepted; nothing it previously refused is now accepted.

    Who can change this. Jon can overrule any part until R3.3's final SHA is posted. The costly part is restarting the census (about a day of box time); I did it because the alternative is accepting a census of a referee known to ship a verdict from a truncated record.

    — Claude DevBox

  18. InauguralPhysicist commented on Nov 10, 2026

    @InauguralPhysicist
    MemberAuthor

    RULING R30R-6 (2026-11-10): the round-6 builder's stop. A malformed sealed-set row on which the driver ends with no outcome is not a disagreement with the rules. The driver stays as it is. Recorded before any H1 row exists.

    The round-6 builder (checkpoint 6a: closing the gate's surviving mutants in the reveal driver's selftest) stopped under its brief's rule "if the text and the driver disagree anywhere, stop and report both". Its finding is exact. No frozen file changed, no beacon was read, no H1 row exists.

    1. The finding. check_d14 (reveal.py b002d937…, lines 148 to 196) reads a base row's family number with int() on line 165, before it can raise its own refusal on line 166. A family string whose number has more than 4,300 digits makes int() raise ValueError, the interpreter's limit on integer conversion. The run then ends with exit 2, status REFUSED, the interpreter's sentence as its message, no decision.json and no OUTCOME line (out/r3-0r/round6/work/d14-family-conversion-repro.json). R30R-5's D14.14 says a row whose base family cannot be resolved "is refused by name, not skipped", and R30R-4 item 2 says a row that fails the bound "is refused by name and the run is INCOMPLETE". Here the row is not named and the status word is REFUSED.

    2. What those two sentences protect. D14.14 was written because the blind tester saw a row skipped silently: the check went on as if the row had passed. The harm is a verdict taken from a set that the D14 check did not pass. On the builder's input no verdict is taken. The exception leaves check_d14 before any arm is run, and the driver writes its status and nothing else. Nothing is skipped.

    3. Where "by name" binds. For every row the frozen generator can write (families.py 3acedd90…: family numbers 1 to 15, a phi and a burn that are numbers), and for every malformation the check tests for itself: a base id that is missing, repeated or not a string; a family that is not in the registry; a wrapper it cannot unwrap; a generator kind outside the listed ones; the bound. Those are the refusals check_d14 raises, and each names its row and reads INCOMPLETE. I ran them again today on the unchanged driver: a broken bound, an unknown base id and a family that is not in the registry each end with exit 2, INCOMPLETE, the row's name, and no decision.

    4. What is outside it. A row so malformed that a Python built-in raises before the driver's own test. No frozen file writes such a row: on a reveal run the H1 set is written by the frozen generator from the beacon and read by the check in the same run, so it takes a set altered between those two steps. For such a row the driver ends without an outcome, in one of two ways (run today on the unchanged driver):

    the row what the check raises the run
    family number of 5,000 digits ValueError exit 2, REFUSED, no decision, no OUTCOME
    phi that is not a number ValueError exit 2, REFUSED, no decision, no OUTCOME
    burn, gen or id missing KeyError an uncaught exception, exit 1, no decision, no OUTCOME
    family that is not a string AttributeError an uncaught exception, exit 1, no decision, no OUTCOME

    In none of them does the message name the row. That is a limit of the driver's diagnostics on an input outside the instrument. It is recorded here. It is not a deviation of the decision procedure: no rule is evaluated and no outcome exists.

    5. The driver does not change. R30R-5 changed the driver because it could ship a verdict from a truncated record. Nothing here ships anything. A change now would void a census of 523,212 mutants for the wording of a refusal on an input no instrument file can produce. If the driver is opened again for another reason before R3.3's final SHA, naming the row in these four cases is a small change to take along; it is not a reason to open it.

    6. For the selftest. For such an input a check may pin that check_d14 does not return, by the type of the exception, and that a run writes no decision and no OUTCOME and exits non-zero. It may not pin the interpreter's sentence. A mutant that makes the check pass over such a row is killed by that, and that is the property worth a check.

    7. The stop rule, restated for round 6. Stop when the text and the driver disagree about what a run decides: the driver would print an OUTCOME, write a decision or read COMPLETE where the text says it must not, or it skips a row, an arm or a control the text requires. A malformed input on which the driver ends with no outcome is reported and is not a stop.

    What this does not do. No rule, margin, arm, split, threshold or seed moves. No instrument file changes. The driver does not change.

    Who can change this. Jon can overrule any part until R3.3's final SHA is posted. The real choice is item 5: keep the driver and record the limit (this ruling), or name the row in the driver and run the census again, about a day and three dollars of hosted time. I chose the first because the run is refused either way.

    — Claude DevBox

  19. InauguralPhysicist commented on Nov 11, 2026

    @InauguralPhysicist
    MemberAuthor

    RULING R30R-7 (2026-11-11): the mutation census of the final reveal driver. The first run is void, the census was run again from mutant 0, and the committed gate command, not the builder's runner, says which mutants are open. 13,620 of 523,212 are. Recorded before any H1 row exists.

    R30R-3 item 6 asks for a full enumeration on the final source, with every survivor argued or killed. This ruling records how that enumeration was made for the driver as fixed after R30R-5 (reveal.py b002d937…, selftest 7b6c0e49…, 642 checks), what departed from the reviewed method, and the numbers round 6 now has to close.

    1. The first census (r5b) is void. I launched it on the dev box with a limit of 3 s per mutant. One pass of the selftest takes 9 to 13 s there, so the runner's alarm always fired inside a fixture and every mutant was recorded as caught. It was stopped at 410,442 of 523,212 rows with 0 survivors. The control that shows it: the unmutated driver, pushed through the same runner, is "caught" at 3 s and survives at 60 s. Of 32 seeded "caught" rows run again at 60 s, 27 fail on the same check, 2 on a later one and 3 survive. The reviewed limit is 20 s. The error was mine, at launch. No row of r5b is used; its file is kept, read-only.

    2. The census again, from mutant 0 (r5c). The same 523,212 candidates, the builder's reviewed runner unmodified, 20 s per mutant, with the unmutated driver as a control before and after every shard of 2,000. Result: 502,240 caught, 12,500 survived (335 sites on 140 lines), 8,472 not runnable (3,167 do not compile, 5,123 fail at import, 182 fail in a fixture or the entry point). 1,130 rows ran to within half a second of the limit.

    3. Departures from the reviewed method.

    • It ran on hosted machines (Hugging Face Jobs, 8 vCPU), not on the dev box. The image has the same interpreter packages, the same absolute paths and the same user; every job checks the tree's fingerprint before it computes. As an A/A check, 100 seeded rows were run again on the dev box through the same runner: all 100 classifications agree, and 2 caught rows name a different check.
    • PYTHONHASHSEED is pinned, so a row can be run again with the same set and dict order, and each parallel worker has its own temporary directory.
    • One shard (ids 320000 to 321999, the loop at lines 179 to 185) was still running after 2.5 hours. It was cancelled and run again as 20 units of 100.

    4. The gate decides, not the runner. The runner is the builder's instrument: it has its own limit and a filesystem guard. What CI runs is the row in tools/selftests.txt: timeout 60 python3 -I tools/observer_oracle/reveal.py --selftest, with its three pins. A mutant is open when that command does not fail on it. So every census row was run again under the gate command, with no guard, in 1,024 chunks. Each chunk is bracketed by two controls: the unmutated driver must pass, and a plant that exits 0 without running a check must fail on the pins. All 2,048 pairs held.

    the gate's verdict rows
    fails (red) 509,592
    passes 12,509
    reaches the 60 s bound 1,111
    all 523,212, one verdict each

    Runner and gate differ on 19 rows: 14 the runner caught and the gate passes, 5 the runner let survive and the gate fails. The gate's verdict stands for all 19. The open population is 13,620: the 12,509 that pass and the 1,111 that reach the bound. The round-6 builder started on the 13,597 known from the first two parts of the replay; the other ten parts added 23 (17 at the bound, 6 passing), all rows the runner had called caught.

    5. Three checks on the replay, each over all 523,212 rows. The recorder calls any exit 124 or 137 a timeout, and calls a run that timeout had to kill "red". So: rows marked timeout that ended under 60 s: 0. Rows marked red that ran 60 s or more: 0. Red rows whose only failing check is the selftest's one clock-dependent check (A1-kill-during-H1-scoring-fails-closed): 0; 8,476 red rows name it together with other checks. Timeout rows took 60.0 to 62.7 s.

    6. Two faults in the replay, both recorded.

    • The collector refused all 96 chunks of the last part. It compares each chunk with the gate row in the live worktree, and the round-6 builder, already at work there, had moved that row from 642 checks to 662. The chunks were sound. I collected that part again with the row read from the tree package the jobs ran, whose table file has the sha256 in the campaign's manifest. No chunk was changed or run again. The tool is to take its expected row from the manifest before the next census.
    • In the last part, 14 of its 192 unmutated controls took 23 to 43 s where all 2,034 others took 2 to 19 s: each was the first run of its chunk, on one slow job. None failed. Slowness can add rows at the bound, which only enlarges what round 6 must close; the three rows of that part at the bound each replace a name by main or cli_entrypoint, a mutation that reaches the bound in 17 rows of the other parts too.

    7. What follows. Round 6 closes the 13,620: each is failed by a new selftest check, or belongs to a class shown equivalent to the unmutated driver, or to a class shown not to finish. The driver stays as it is. The selftest will change, so the gate enumeration runs once more on the delivered files before acceptance, as R30R-3 item 6 requires.

    What this does not do. No rule, margin, arm, split, threshold or seed moves. No instrument file changes. The driver does not change.

    Who can change this. Jon can overrule any part until R3.3's final SHA is posted. The census and the replay together cost about $3.50 of hosted time.

    — Claude DevBox

  20. InauguralPhysicist commented on Nov 11, 2026

    @InauguralPhysicist
    MemberAuthor

    RULING R30R-8 (2026-11-11): the acceptance census of round 6. What it runs on, which attempts count, when a row gets a second run, what decides acceptance, and one decision about bound arguments that I make after seeing a number. Fixed before the census starts and before any H1 row exists.

    R30R-7 item 7 says the gate enumeration runs once more on the delivered files before acceptance. This ruling fixes how, before it runs.

    1. What it runs on. All 523,212 mutants of the first census (R30R-7), under the committed gate command, on the four gate files as the round-6 builder delivered them at checkpoint 9, its second delivery: selftest 9180c733…, fixtures c6b4727e…, commitment 18aa1629…, table 2c818e15…. The referee itself, reveal.py, the file that is mutated, is unchanged (b002d937…).

    The selftest has 663 checks: the 642 start checks, each as it was and in their start order, and 21 new ones, which run right after the first start check. A run now ends at the first failing check whose name begins R6- (the 21 new ones and one start check). So for a mutant that such a check fails, the checks after it do not run.

    A census that has started is published and judged, whatever its outcome. A later change to any of the four files makes a new delivery, which needs a census of its own. It does not erase this one.

    A hosted replay of the 13,620 open ids on these files is already on record. All 7,671 claimed kills are failed. All 1,058 members of the bound classes reach the 60 s bound. Each of the 21 new checks fails for at least one killed mutant. 4,889 of the 4,891 members of the equivalence classes pass; the other two are the case of item 3.

    2. Which attempts count. The census runs in chunks of rows on hosted jobs. Each chunk is bracketed by controls: before and after it, the unmutated driver must pass and a plant that exits 0 without running a check must be failed by the pins; and the tree must be unchanged at the end. An attempt at a chunk whose controls do not hold, or that does not finish, gives no verdict for any of its rows. Whatever it uploaded is kept on file, and the chunk is attempted again. Whether an attempt counts is decided from its controls and from whether it finished, never from any row's verdict.

    The number of attempts is fixed before launch and is not raised afterwards: a job tries a chunk at most twice, and the jobs of one namespace of P parts are started at most 2P + 4 times in all. The census is complete when every row has a verdict from an attempt that counts. A chunk that has none when its launches are used up cannot be completed; a row that itself keeps its chunk from counting (it uses up the job's memory or time, or changes the tree) has that effect. Then the census is not complete, nothing is accepted, and what is done about it is a new ruling, posted before any further run.

    3. A second run, for two kinds of first verdict and for no other. Two things are known to make a verdict depend on the machine in a way that running alone undoes. One selftest check, A1-kill-during-H1-scoring-fails-closed, waits on clocks. And a run that is slow on a loaded machine can reach the 60 s bound. So a row gets a second run if and only if its first verdict is

    • (a) red, with that check as its only failing check; or
    • (b) at the bound, meaning that the command itself ran the 60 s (not a child that exits with status 124 or 137 by itself, sooner), while the row is not a member of a bound class.

    The second run is alone: a job that holds one chunk and one recorder process, which runs its rows one after the other, with nothing else of the census in that job. Item 2 applies to it as to any attempt. Its verdict replaces the first, whatever it is. Both are published. There is no third verdict.

    Nothing else is run again. A claimed kill that passes, a class member that fails any other check, a bound-class member that ends, a row that ends with status 124 or 137 before the bound, a mutant the first census failed that now passes: each is a verdict and counts against the delivery. So does a verdict that the machine changed in some other way, such as hash order (random per process under python -I) or memory.

    What the second run can do, by what is claimed for the row:

    • A class member, expected to pass: red on that check alone, then passing alone, it passes. That is the better of two runs on one check, and I say so. The round's brief already holds that this check's failure by itself is no evidence about a mutant ("no verdict from a clock"), and the pinned checker refuses it as evidence for a kill. If the second run is red too, by that check or by any other, the member fails.
    • A claimed kill, expected red: red on that check alone both times is refused by the checker and counts against the delivery, and so does a pass. The kill stands only if the second run is red and not on that check alone.
    • A mutant the first census failed, expected red: if the second run passes, or is red on that check alone again, that counts against the delivery. The checker does not test this for such rows; the census tool does (item 4).
    • Any row outside the bound classes that reached the bound: its second verdict is judged like a first one, and being at the bound again counts against the delivery.

    Why (a) is the machine: in the replay of the first delivery, four class members were red on that check alone among 13,597 rows, on jobs that ran eight chunks at once; run alone, all four pass in about 3 s. In the replay of the second delivery it was two other class members, whose runs had taken 33 and 37 s; run alone, both pass in under 6 s. In the first census no red row had that check as its only failure (R30R-7 item 5).

    4. What decides acceptance. Three things, and all of them must hold.

    • The pinned checker (closure_check.py, 8dfba8a0…) in its acceptance form, on the census after item 3 and on the closure file of item 6. It requires: the closure lists exactly the rows the first census did not fail, each once, as a claimed kill or in a class that has a name of its own, a rule and an argument; both censuses are complete and carry the same ids; the census ran the selftest the closure names; every claimed kill is red, and not by the clock check alone; every class member passes; every bound-class member is at the bound, the command itself having run the 60 s; no other row passes, and no other row is at the bound; and the list of rows that need a source change is empty.
    • The census tool (census6.py over replay6.py; their hashes, the recorder's, the plan's, and those of the launcher and of the job code package are posted when the census is launched) requires more: every chunk that counts was checked against the tree its namespace staged (a fingerprint over every tracked file, the four among them), and against the command, the pins and the bound; all namespaces staged the same tree; each of the 21 new checks fails for at least one claimed kill; and after the second runs no row at all is red on the clock check alone. The hash each blind review of the tool read is posted with the tool's.
    • A blind reading of the rewritten bound arguments finds them sound (item 5).

    5. A decision about bound arguments, made after seeing a number. A bound class claims that its members never finish a named fixture: either there is no exit with memory unbounded, or "at least 10^18 steps" come before any exit, "derived from the code and not timed" (the round's brief). A blind reader found that two delivered arguments say "no exit" where CPython has one: a container may not grow past a size that a check refuses before any allocation. For one member it is a list, at 1,108,046,317,219,334,709 items. For 72 members it is a set that gains one entry on every pass of the driver's loop, at 172,938,225,691,027,046 entries. No machine holds either, so no hosted verdict changes. The arguments are wrong as written.

    The brief did not say what a step is. The reader counted loop passes. Counted so, the list member is over the line and the 72 set members are under it, by a factor of about six.

    I fix the unit now, knowing those counts: a step is one bytecode instruction executed by the interpreter, or one iteration of a loop in CPython's own C source that the argument names. Loops inside the allocator or the C library do not count. Under it the 72 are members if one pass of that loop executes at least six instructions, which the builder has to show from the loop's bytecode on CPython 3.12.3, 64-bit (Ubuntu package 3.12.3-1ubuntu0.17). The first census ran on it, and a hosted job of this one refuses to start on any other.

    This is a choice made after the count was known, and it favours the delivery. I make it for this reason: these 72 mutants cannot be failed by any check that ends. On an input with a cycle they run until that size check, which no machine reaches. On every other input they behave as the unmutated driver does, by the class's own rule: the replacement is a total operation with no output, and its result is only stored in a set that is only searched for something else. The only other outcome would be that mutants no machine will ever see finish hold up the round over a unit the brief left open.

    One blind reader reads all 73 rewritten arguments against this unit before acceptance: the kind of reader that found the fault, in a fresh context. Sound means, for each member: the growth rule and the count at which the size check refuses are taken from named source; the steps are the fewest any one pass can take, counting only bytecode and named C-source loops that run on every pass; the arithmetic is right; and the product is at least 10^18. The reading depends on no number of the census, and no number of the census depends on it: these members reach the bound whatever their argument says. So an argument found unsound may be corrected once and read again, by a reader of the same kind that is shown the first reading and the correction; that changes text, not files, and the census stands. The reader, not the author, says whether a member's count is under 10^18, and that word is final for round 6. A member under the line is not a bound member, and round 6 is then not accepted: closing it needs a change to the selftest, and that is a new delivery (item 1).

    6. The closure file that is judged. closure-6b.json (da5b8627…) fixes which ids are claimed killed, which are in a class and which in a bound class. The reviews of the second delivery found two faults outside the selftest: three equivalence rules grant "this generator is never empty" by a function's name where it must be computed from the source; and the arguments of item 5. Both are being fixed in a turn that may not touch the four files. The file judged is the one that turn delivers, and only if it makes the same claim for every id: rule code and argument text may differ, nothing else. Its hash is posted when it exists.

    What the reviews found in the selftest: two blind critics from different model families read everything the second delivery changed there. Both found each defect of the first review gone, for the right reason, and every changed check within what the brief allows it to pin. One of them raised the first two caveats of item 7. A second blind re-derivation of 50 members of the changed classes found no disagreement (260 members with the first).

    7. Known, and accepted as caveats.

    • Two checks use a pasted copy of the driver's docstring as an opaque row id. If the docstring is edited later, they stop failing, by a check, the mutants that replace a name by __doc__; those mutants then reach the bound instead.
    • One kill relies on a set's own order differing from sorted order for at least one of 63 subsets. A critic's probe saw no miss in 400 seeds. A miss in the census would count against the delivery (item 3).
    • Four start checks assume the driver's canonical path and fail when the checkout is reached through a symlink. That predates round 6.

    8. Cost. About $2.20 to $2.90 of hosted time, and several hours of wall clock.

    What this does not do. No rule, margin, arm, split, threshold or seed of the pre-registration moves. No instrument file changes. The driver does not change.

    Who can change this. Jon can overrule any part, item 5 above all, until R3.3's final SHA is posted.

    — Claude DevBox

  21. InauguralPhysicist commented on Nov 11, 2026

    @InauguralPhysicist
    MemberAuthor

    R30R-8, addendum to item 6 (2026-11-11). Posted before the census starts.

    The turn that item 6 names has delivered: closure-6c.json (d490b674…). Every id keeps its kind, its class name and its class, and none of the four gate files changed.

    The blind reading of item 5 is done, on that file: all nine bound arguments hold, and no member is under 10^18. Both step counts were found sound: the list member at 1,108,046,317,219,334,708 iterations of CPython's own loop, and the 72 set members at six call instructions on every pass, 6 × 172,938,225,691,027,045 = 1.0376 × 10^18. The reader compiled all 72 replacements and found the six call sites in each.

    Two blind critics, from different model families, read the fix to the three equivalence rules. Both found it real and not finished. The rules now compute "never empty" and "no element raises" correctly over a domain, and still do not check that the domain is the one the generator really iterates: a second caller, a statement between the validation and the use, or a rebound name would leave the certificate standing. No classification changes: both critics classified all 63 candidate rows with the old and the new rules and got the same 24 members, and every one of those 24 has been re-derived blind as equivalent.

    So one more turn follows, restricted as the last one was and one step further: no gate file, no id, no class membership, and now no byte of a bound argument. Item 6 said "the file judged is the one that turn delivers". It now reads: the file judged is the last one delivered before acceptance that differs from closure-6b.json in nothing but the rule and argument text of its classes. Its hash is posted when it exists. If the text of a bound argument differs from closure-6c.json, that argument is read again under item 5.

    The census is planned with closure-6c.json. What it expects of each row depends only on the ids and what is claimed for each, and those do not move.

    Nothing else of R30R-8 changes.

    — Claude DevBox

  22. InauguralPhysicist commented on Nov 11, 2026

    @InauguralPhysicist
    MemberAuthor

    R3.0-R round 6: the acceptance census of R30R-8 is planned and starts now. What runs, and every hash item 4 asks for. Posted before the first job is started.

    What runs. All 523,212 mutants of the first census (R30R-7), under timeout 60 python3 -I tools/observer_oracle/reveal.py --selftest and its three pins (663 checks ok, none failed, the summary line), with the bound at 60 s. The four gate files are those of checkpoint 9, as item 1 names them: selftest 9180c733…, fixtures c6b4727e…, commitment 18aa1629…, table 2c818e15….

    How. 10 namespaces (r6c0 to r6c9) of 52,321 to 52,322 rows each, in chunks of 512 rows: 1,030 chunks on 130 jobs, one namespace's jobs at a time. A namespace of 13 parts may be started 30 times in all (2P + 4). The rows were shuffled with seed 1762 and dealt to the namespaces in turn.

    What each row must do, from the claims in the closure file: 517,263 rows must be failed (the 509,592 the first census failed, and the 7,671 claimed kills), 4,891 must pass (class members), and 1,058 must reach the bound (bound-class members).

    Hashes (sha256).

    what hash
    census tool, census6.py 8b0a8f0fcf662543c23610d4b19703c56b6a8922f6c7fd89e34abe0f0b9744eb
    replay6.py, which it drives cf14587724416b871dc5d2be6a423a6009c2675f85937d8753388ce0611a44ec
    recorder, gate6.py 57f6fcbf3e378dc30b3fffe9c647b7f646c0058919f2894dc2f4cfaf91fe2e5c
    gatepool.py c50c547e491475f4581b340cc9b28bce85cdba53e5004132ab9b93a5a2d2a94f
    launcher, launch.py 4a72dd4db006f4df71d21af7d95df75cfea79e8cb10f3d1a13bd687ebec1af8d
    job.sh 04f5b8cb4bae481bb9bf20038c97bb083c72edec06c38224c8d167a6ac83ede1
    job code package, the same in every namespace 58d10a968943a157c31c5522a5a5c916f399b791d359634a346d2699e073ccfc
    the plan, PLAN.json d03a981457dca148dafe7801215fca96d6c7957bab13a8f86073d27f87339136
    checker, closure_check.py (pinned) 8dfba8a0756b49a9e2b01bbd3cb3d9ed33da8b313c7e35f2215919d7a739be24
    closure file the plan was made with, closure-6c.json d490b674a55a89cce9429c4e76a0e42095cf5cd3e26d7fd01fbf57433252b564
    verdict file of the first census 49cd02f2a617c7973ee1c6ef16dd8f484509c1b192ebcbf13d623291463934c3
    tree staged in every namespace (fingerprint over every tracked file) bdb56f6f97041163dcb2a6dc2d7a00d164a3fa012480bd7440bca295fdc08077

    The blind review of the census tool. One critic in a fresh context read the tool four times. The file it read each time, and its verdict:

    pass census6.py verdict
    first b3e7f611e4d85d245a8e050e3a6567db6878b79fb92ff1809b3302f90d14d683 FAIL
    second b68b5c31bb9f16ab71b55edf438e0567e50116dd6f96dd727ccb729a8e9bb36e FAIL
    third 52295b97f0f2583bf6fcf0d8316143651f6d5b94a633eb95dc7515507599f680 PASS, three points left
    fourth 8b0a8f0fcf662543c23610d4b19703c56b6a8922f6c7fd89e34abe0f0b9744eb PASS, "nothing that needs the tool changed before the paid run"

    The launched file is the one the fourth pass read. What the two failures were: the first version let final and accept trust files that an earlier step had written, where they must rebuild from the verified chunks; the second read a later closure file three times, so it could judge bytes it had not checked, and compared two closure files more loosely than item 6 allows. After the third pass I closed its three remaining points: a pass now refuses to start anything when a namespace's launch cap is not the 2P + 4 that the plan recorded (item 2); the comparison of two closure files is one comparison of canonical text with only the rule and argument texts left out; and the offline test now covers the lock every command takes. After the fourth pass only the offline test changed. replay6.py was read in the first pass, and its hash was the same at each later pass.

    Rehearsals. Two, with the launched tool, on a seeded sample of the census's own rows. y: 63 rows on four jobs, the same rows as an earlier rehearsal x that ran before R30R-8 with the tool's first version: 40 rows that the first census failed, 10 claimed kills, 10 class members and 3 bound-class members. Every verdict was as claimed. z: 28 rows, all but one of them among those 63, planned with a scratch copy of the closure in which one bound-class member (id 320146) is wrongly put in a class, so that it reaches the bound and gets a second run alone under item 3. It did, and reached the bound again. So 40 of the rows that the first census failed have already been seen to fail under the delivered selftest; the verdicts of the other rehearsal rows were on record from the replay that item 1 cites. The namespaces stay in the dataset (r6x0, r6x1, r6y0, r6y1, r6z0, r6zr). No verdict of a rehearsal is part of the census: every row is run again, and accept refuses a rehearsal.

    Not finished when this was posted.

    • The mutation run over the tool's own offline test (50 weakened copies of the tool) is running. It tests the test. If it shows a fault in the tool itself, the change and the new hash are posted here before accept runs, and the critic reads that change.
    • The rules-only turn of addendum 1. The closure file that is judged is posted with its hash when it exists; accept is given it only if it makes the same claim for every id as the file above.

    Cost. 130 jobs at $0.03 an hour each; the estimate of item 8 stands.

    Whatever comes out is published and judged (item 1).

    — Claude DevBox

  23. InauguralPhysicist commented on Nov 11, 2026

    @InauguralPhysicist
    MemberAuthor

    R30R-8, addendum 2 to item 6 (2026-11-11). Posted while the census runs. It depends on no number of the census, and no number of the census depends on it.

    The turn of addendum 1 has delivered: closure-6d.json (f22f6618…), with a rules script 53a63d37…. Every id keeps its kind, its class name and its class. No gate file changed. Every bound argument is byte for byte the one that was read. The census tool's own comparison of the two closure files says so, and so does mine.

    How it closed the fault of addendum 1: for the three reduction classes the script now checks one thing, that the whole syntax tree of the referee it is given equals a copy of the reviewed referee carried in the script, and it declines otherwise. Their arguments list every fact the 24 certificates lean on, 302 in all, each marked as checked by the script, as reasoning about the pinned text, or as a fact about a file the script is not given.

    A decision about what counts as a check, made after seeing the delivery. The round's brief says a class rule "never looks at … the hash of the source". A comparison of the whole tree is close to that in effect: it certifies this program and no other. I accept it for these three classes. It is a choice made after seeing the delivery, and it favours the delivery. My reasons:

    • the referee is frozen, and the round exists to freeze it;
    • an equivalence argument is about one exact program in any case;
    • the mutants are still told apart by line, operator and token, and the rules check over all 523,212 rows still passes with no falsifier;
    • all 24 members were re-derived blind as equivalent;
    • three deliveries (lists of lines, grants by a function's name, facts computed over a domain that was not tied to the value) showed that anything narrower leaves a premise granted in silence.

    What it costs: these three rules cover no later version of the referee, and a planted edit can no longer test the analysis behind the comparison. So the lists carry the weight, and they are read instead.

    Two blind critics from different model families read the script and the lists; one read all 201 facts of the 16 generators, the other 12 of the 16 lists in full. Both found the findings of addendum 1 closed for ordinary source text, a real analysis behind the comparison and no table of lines, and the same 24 members. They also found:

    • a seam: the script parses the file as text, and Python first decodes the file's bytes by its own rules. A file that declares an unusual encoding can hide a statement inside a comment, which the comparison does not see. The referee has no such declaration;
    • one listed fact that is false for a malformed input (a list where a mapping is expected). The mutant still ends as the original does there, by another argument than the one written;
    • one fact, repeated in every list, that is about outside files and names none; and two inventories that are not complete.

    No member was shown to differ from the original. One more turn corrects these: the script must compare what Python would run, and the lists must say only what is true and cite what they lean on. It may not touch a gate file, an id, a class membership or a bound argument. Item 6 as amended by addendum 1 stands: the file judged is the last one delivered before acceptance that differs from closure-6b.json in nothing but the rule and argument text of its classes, and its hash is posted when it exists.

    Jon can overrule any part of this, the decision above first.

    — Claude DevBox

  24. InauguralPhysicist commented on Nov 11, 2026

    @InauguralPhysicist
    MemberAuthor

    R30R-8, addendum 3 (2026-11-11): a boundary of the round's equivalence standard, ruled after a review surfaced it; and the closure file that is judged. Posted while the census runs. It depends on no number of the census, and no number of the census depends on it.

    1. What the review surfaced. Round 6 holds an equivalence class to this standard: the mutant and the original end alike "for every run of the driver's command line", "with any arguments, any environment, any contents in the files it reads, and any behaviour of the programs it starts. The frozen instrument files are as they are in the tree."

    A critic of the fact lists asked where the corpus comes from. The builder traced it and reported it as a boundary instead of arguing it away, as it was told to. On a live run the driver copies the two corpus files that sit beside it (corpus.json and hcal/corpus.json) into the output folder, builds the H1 corpus there, and the instrument then evaluates each row's expression as Python inside the driver's own process (gen.py line 27), before any check of the files' content. No argument of the command line carries an expression. A corpus file with other contents would.

    2. The ruling. The corpus that the process evaluates is not an input in the sense of the standard. It is what the frozen instrument provides and builds:

    A run in which those files hold anything else is outside "every run", whoever put it there: a changed checkout, another process, or a program the driver started that wrote outside what it was asked to produce. The programs the driver starts may still do anything with their exit status, their output and the files they are there to write.

    I rule this now, after the review, and it favours the delivery. I do not think the other reading can be held. Text that the process evaluates as code can look at the program that is running it, so it can make any two programs end differently, a mutant and the original among them. Under that reading no mutant of this referee is equivalent to it and none can be shown killed by argument, in any class of this round or of an earlier one. The brief already makes the same cut in one place: where the driver reads its own file, the mutant is treated as having the original's bytes.

    What is true of the frozen contents was checked by parsing, with nothing evaluated: the two files hold 51 expressions (35 and 16), each built only from numbers, the names n, x and step, six functions of math (cos, sin, sqrt, log, floor, exp) and arithmetic; the H1 templates insert only the text of numbers they drew; no selftest fixture hands the evaluator an expression. The builder and a blind critic each made that count their own way.

    3. What this does not say. It does not say the referee is hardened against a checkout that was changed, or against a candidate build that attacks it. A reveal's protection there is what it was: the commit the workflow checks out, and the manifest hashes the run records. Checking the corpora's digests before anything in them is evaluated would be a change to the frozen instrument or to the driver. I note it for after the reveal and change nothing now.

    4. The closure file that is judged. closure-6f.json (518fb239dee0cd63aa4fa082fb977cc7cf170bc7a6c230dc6c6d1b00dee0db03), with the rules script 1151e39563a9135ae0929c10573c59daecc41e786d9e63362140ed44abc9bbdb. Since addendum 2:

    • The turn it announced (6e) closed the seam: the script now reads the referee as bytes and certifies nothing unless Python's own parse of those bytes equals the parse of the text it analyses. It also replaced the false fact with the argument that holds, and corrected the lists. The second-family critic passed it: both of its findings closed, all sixteen generators' lists hold, nothing must change. It ran 32 files through the script's command line and 202 combinations of codec and declaration, and found none that is still certified and that Python would read as another program. The other critic closed its three findings, counted the inventories its own way to the same numbers, and asked for one entry more: the corpus, above.
    • A last turn (6f) added that entry and two notes. It changed no byte of the rules script. The critic that asked for it passed it: nothing must change.
    • My checks of the final file: by the census tool's own comparison it makes the same claim for every id as the file the census was planned with; every bound argument is byte for byte the one that was read; every class entry outside the three is unchanged; the four bar commands pass, the rules check over all 523,212 rows among them; every earlier planted edit loses its certificate; and the four files that hid a statement behind an encoding declaration were certified by the script before 6e and by nothing since.

    accept is given this file. The three classes' arguments say that their live-path facts hold on the condition that the corpus only computes numbers and leave the scope of that condition to this ruling; item 2 is that ruling.

    Jon can overrule any part of this, item 2 first.

    — Claude DevBox

  25. InauguralPhysicist commented on Nov 11, 2026

    @InauguralPhysicist
    MemberAuthor

    R3.0-R round 6: the acceptance census is done, and the round is accepted (2026-11-11). Published as R30R-8 item 1 requires, whatever the outcome; this is the outcome.

    The census. All 523,212 mutants of the first census ran under the gate on the four files of checkpoint 9, on 130 hosted jobs, from 07:11Z to 12:15Z. Every job was started once and every chunk counted at its first attempt; no attempt was uploaded as failed. The unmutated driver, run as a control before and after every chunk (2,060 runs), passed each time, in 2.2 s to 28.5 s. The jobs' own run times add up to 55.4 hours, about $1.75 of hosted time.

    what is claimed for the row rows failed by the gate passed reached the bound
    the first census failed it 509,592 509,592 0 0
    a claimed kill 7,671 7,671 0 0
    a member of an equivalence class 4,891 0 4,891 0
    a member of a bound class 1,058 0 0 1,058

    No row qualified for a second run under item 3: none was red on the clock check alone, and none outside the bound classes reached the bound. So there are no second verdicts, and the first verdict file is the final one: 119cd0c91395369acc7dcd9c194308b1dc4d62462f37e6b31263e6a1e5c72b34.

    The three conditions of item 4.

    • The pinned checker (closure_check.py, 8dfba8a0…), in its acceptance form, on this census and on the closure file of addendum 3 (closure-6f.json, 518fb239…): exit 0. Every count it reports against the delivery is zero: kills that are not red, kills red by the clock check alone, class members that do not pass, bound members that end before the bound or do not reach it, passing rows outside every class, rows at the bound outside every bound class, rows that need a source change.
    • The census tool (census6.py, 8b0a8f0f…, the file posted at launch and not changed since; plan d03a9814…, as posted): every chunk was checked against the tree its namespace staged, all ten namespaces staged the same tree, each of the 21 new checks fails for at least one claimed kill, and no row is red on the clock check alone.
    • The blind reading of the bound arguments (item 5) found all nine sound (addendum 1). The nine arguments in the judged file are byte for byte the ones that were read.

    The judgment is recorded in ACCEPT.json, sha256 649cfba361266f63fb22cfe95549d7deab201515e2b8c3146acbf75444298cf7.

    What is accepted. The referee's selftest as delivered at checkpoint 9: reveal_selftest.py 9180c7330e5b2ed6bf5451d5a8e97da7a8986d03783e61a654b55b28d6d94e2d (663 checks), with fixtures c6b4727e…, commitment 18aa1629… and table 2c818e15…, for the driver reveal.py b002d937…. Of the driver's 523,212 mutants the gate now fails 517,263. The other 5,949 are accounted for one by one: 4,891 in 57 classes, each with its rule as code (run over every row with no falsifier) and a written argument that it cannot be told from the original; 1,058 in 9 classes argued never to finish one fixture, read blind.

    What it rests on, said once more.

    • The decisions made after seeing a number or a delivery, each published when it was made: the unit of a step (R30R-8 item 5), the whole-program comparison as a check (addendum 2), the corpus as part of the frozen instrument (addendum 3).
    • The caveats of item 7. The three kills that rely on hash order (58629, 58637, 332024) and the four that rely on the pasted docstring (311688, 312710, 317674, 318696) were each red in this census.
    • The census tool's own offline test was put through a mutation run while the census ran: 49 weakened copies of the tool, each caught by the case written for it. Two of them needed a change to the test first, none to the tool.

    What follows. The builder turns the delivery into commits, patches and a bundle for #2330. R3.3 then posts the final SHA that freezes the referee. No rule, margin, arm, split, threshold or seed of the pre-registration moved, and no instrument file changed.

    Jon can overrule any part of R30R-8 and its addenda until that SHA is posted.

    — Claude DevBox

  26. InauguralPhysicist commented on Nov 11, 2026

    @InauguralPhysicist
    MemberAuthor

    RULING R30R-9 (2026-11-11): what the first hosted run of the reveal's own workflow found, after the acceptance. The driver is not changed. This is decided after the acceptance, and it leaves two known defects of the driver in place.

    The round was accepted this morning (the result is above, comment 6795808590). I then opened #2339 from the accepted tree. Its first CI run failed two checks, and the review of the PR found one thing more. This ruling says what each was and what I decided.

    1. The hosted dry run ended VOID. The workflow gave the driver --out build/reveal-result, a relative path. The driver writes that path into the .git file of its instrument copy. Git reads a relative path in such a file against the file's own directory, so the copy pointed at a repository that does not exist. Control (a) runs the floor plant from that copy; the plant builds its anchor through git and found no repository; the control was false and the run VOID. Everything else in that run was the registered diagnostic. The sealed step had the same relative path: a dispatched reveal would have read the beacon, judged H1 and then ended VOID.

    Nothing before the census met this. The selftest's fixtures give the driver an absolute path, and no dry run that was recorded as passing can have had a relative one, since it would have ended VOID in the same way. The census measures the selftest against the driver. It does not run the workflow.

    2. The decision: the driver stays byte for byte as accepted, and the workflow passes an absolute path. reveal.py is b002d937…, the file the 523,212 mutants were made from and the file the commitment names. Changing a line of it would need the census again. With a relative path the driver fails closed: it prints VOID and no outcome, never a wrong outcome. The reveal runs through the workflow, and both of its steps now pass the workspace's absolute path. docs/PREDICATES.md says to do the same by hand, and why.

    The evidence that this is enough is the same dry path on the fixed workflow: run 43029555404, runner image ubuntu-24.04 20261101.360.1, GCC 13.3.0. It ended INCOMPLETE with exactly the two reasons R30R-4 describes (no-family-15, undefined-BA:diverging,equilibrium). Controls (a), (c1) and (c2) are true, control (b) is undefined on those two predicates, both judge runs exit 0 with no finding, and the floor exits 0 for both subjects, at 10,000 resamples and seed 1758. Its raw.json has sha256 41b3b0c57163eb75ca7552dfbd80c03632f783e855b87d485a799022aa68a9ec and names the driver as b002d937….

    I make no exception for the cause of a VOID. If the reveal itself ends VOID, for this reason or any other, the pre-registration applies as written: no outcome, and step 1 is repeated.

    3. A second defect of the driver, found by the review of the PR, also stays. When a commit is not in the local repository, the driver fetches it by the id it was given. Git fetches a commit only by its full id, and two of the driver's own pins are short (3eed5caf for R3-STD, 3d8a14b4 for INC). On a checkout that lacks one of them the driver therefore stops, INCOMPLETE, before any arm is built and before the beacon is read. The workflow checks out the whole history, and all three pins are reachable there today: INC and the anchor are release tags, and R3-STD is on phase2-numbers. Before the reveal I tag R3-STD and the final R3 commit, so that both stay fetchable after that branch is merged and deleted.

    4. What changed on top of the accepted tree. Two commits and four files: the selftest registry tools/selftests.sh, the workflow, and two docs. The registry had taken the selftest's body for a self-test with no row of its own and refused the tree; nobody had run the registry on this tree before the PR. reveal.py, reveal_selftest.py, reveal_fixtures.json, reveal_commitment.json and the selftest's row are byte for byte what the census accepted (the hashes are in #2339's description). R3.3 names the referee by those hashes.

    5. #2329 stays open. Its three boxes change the frozen instrument, which R30R-1 forbids before the reveal. The source is recorded outside the instrument, and family 10's argument was reviewed blind with it in evidence. The instrument's own citation changes after the reveal. The comment on #2329 has the detail.

    6. The reveal runs on the hosted runner, as built, and not in the pinned image of the floor check. Each arm and the anchor are built in the one job with the runner's compiler, and raw.json records each binary's toolchain. Rule 6 re-measures the floor on the anchor built there: a toolchain that moved a floor verdict would end the run REFUSED before the beacon is read. Every dry run so far, on the build machine and hosted, used the same compiler (GCC 13.3.0).

    What this ruling is. It is decided after the acceptance, by the party that ruled the acceptance, and it leaves two known defects of the accepted driver in place. Both fail closed, and both are avoided by how the reveal is run. The other choice is to fix the driver and run the census again: about five hours and two dollars of hosted time, and a builder round for a new closure file. Jon can overrule any part of this, item 2 first, until R3.3's final SHA is posted.

    — Claude DevBox

  27. InauguralPhysicist commented on Nov 11, 2026

    @InauguralPhysicist
    MemberAuthor

    The blind review that manual_review.json cites as its evidence, posted so that it can be read. The record names it by a path that is not in the repository (out/r3-0r/blind-review-round3.md). It was written on 2026-11-06 by a reviewer with a fresh context, independent of the builder, and it is given below as written (sha256 ae3e4204da9be516063afc45e9b9d2828b257c1533d2601af64f212505cac8e6).

    Its four findings were answered before the census. BR3-1 is RULING R30R-4's subject (deviation D14). BR3-2 was answered by staging the instrument's build context, the change whose relative-path defect R30R-9 describes. BR3-3 is the Dry A check of the pull-request job. BR3-4 is control (c1) as the driver computes it now: rules 1 to 5 on converged, with rule 6 recorded apart.

    — Claude DevBox


    R3.0-R round 3 blind review — 2026-11-06

    Reviewer: Codex /root/blind_review, independent of the builder. Product files were read only. No build, scoring run, H1 draw, mutation sweep or heavy job was performed. The only executions were source/inventory inspection and exact rational arithmetic. The builder was concurrently revising scorer installation/preflight; those revisions need a final re-read after this review.

    Verdict

    The 17 manual argument templates are APPROVED as mathematical arguments for the three claims they actually certify (limit, tends_to, bounded), with F10's supplemental Chung–Fuchs source included in the evidence. This is the blind critic's recommendation in an evidence file, not a production approval. All production verdict/reviewer/date fields remain blank. The orchestrator records this review separately and obtains the registered reveal-time blind approvals.

    The shipping mapping implements R30R-2's first-match table and additive duties. I found no new unresolved outcome combination. I do not recommend declaring the driver accepted yet: an isolated-instrument build-context defect needs repair; dry calibration cannot legitimately yield a complete shipping verdict; and the frozen AR(1) label semantics need an orchestrator ruling before H1 scoring.

    Concrete findings

    BR3-1 — frozen AR(1) label conflicts with exact weak stationarity; STOP/ruling needed before H1

    families.py:169-178 sets F9's variance_changes=False and calls it stationary. gen.py:80-86 initializes the AR(1) at the deterministic value mu and performs exactly 200 burn steps. For the mathematical process it represents, with independent uniform innovations of variance 1/3,

    Var(x_n) = sigma^2 / 3 * (1 - phi^(2*(200+n))) / (1 - phi^2)
    Var(x_(n+1)) - Var(x_n) = sigma^2 / 3 * phi^(2*(200+n)).
    

    The second expression is strictly positive whenever phi != 0. The contract in docs/PREDICATES.md calls equilibrium a MATH answer requiring constant variance, and derive.py:304-314 returns true from the supplied false flags without checking this initialization. Finite burn-in approximates stationarity; it does not establish the exact stationary process asserted by the label. Positive F15 scalings and F15b copies retain this issue.

    A small exact arithmetic check used phi=1/2, sigma=1, burn=200 and proved V(1)-V(0)=1/(3*4**200)>0; no stochastic draw or runtime reading was used. This is deliberately a statement about the mathematical label, not a claim that the tiny transient is detectable in floating execution. The text gives no tolerance that equates approximate and exact stationarity.

    The F9 manual argument remains valid: it certifies boundedness and no finite/infinite limit, not stationarity. Approval of that argument cannot approve the additional equilibrium label. Fixing the generator, its flags, or the definition touches frozen material or its meaning; this reviewer does not choose among those changes. Record a ruling/deviation under R30R-1 before revealing, or identify an already recorded decision that explicitly permits this finite-burn approximation. The narrowest label correction would affect the F9 variance_changes assignment; it must not be made silently.

    BR3-2 — isolated instrument lacks the root that frozen plants.py invokes

    The observed install_instrument() stages out/instrument/tools and reloads judge/score/seal from it. The revised execute() invokes the staged plants.py --selftest. Frozen plants.py:768-769 derives its root as the grandparent of its own directory and calls make -C <root> observer-anchor. That root becomes out/instrument, where this installation stages no Makefile. Control (a) therefore cannot run through its actual entry point, even with an already cached anchor.

    This is a driver staging defect, not a reason to edit the frozen instrument. Supply the unchanged build context needed by the frozen entry point and add a fixture that checks the real root lookup rather than mocking the whole control command. This finding was sent to the builder while the patch was in progress; final resolution remains to be checked.

    BR3-3 — Dry A must remain diagnostic; its population cannot pass the H1 acceptance table

    The brief says Dry A must run the calibration corpus/H-cal to a printed result, and agree with the old H-cal controls. It does not authorize an H-cal shipping decision. Frozen judge.rule5() returns None when declared == 0; calibration/H-cal have no family-15 rows. The judge emits FAIL when another criterion fails, otherwise INCOMPLETE. A missing unit-invariance measurement must not become PASS.

    The old designated receipt already demonstrates the additional one-class problem: out/r30i/r2_control_c_hcal.log:46-62 has no positive labels for diverging or equilibrium, and their BA is undefined for every arm. Its W4 diverging verdict is INCOMPLETE at lines 137-143; the judge itself exits 0 at line 1542 because it successfully printed a table. Consequently the current driver cannot require every dry verdict to be PASS/FAIL or require CF BA=1/2 for all six on this population.

    status_for() currently rejects an INCOMPLETE predicate verdict and execute() returns 2 for non-COMPLETE; the PR workflow runs the command as a success-required step. The current mock calibration fixture supplies six invented complete subject tables and CF BA=1/2, masking the real dry population's structure. Print and retain the actual diagnostic table/status, with no shipping outcomes. Any special exit semantics for this explicitly dry workflow must be stated narrowly and tested; do not amend the judge, silently treat undefined BA as 1/2, invent family-15 H-cal data, or force a COMPLETE outcome. This distinction follows from the existing brief's 'printed result' language and R30R-2's no-outcome rule for INCOMPLETE.

    BR3-4 — W4 failure is presently contaminated by D11 (documented limitation)

    The W4 recipe starts from INC, which lacks the registered int64/IEEE capabilities. The frozen judge's D11 rule thus forces W4 rule 6 to FAIL, irrespective of its window-dependent readings. controls_ok() checks that each W4 verdict is FAIL, so this control can pass even if the intended window degradation is not what rejects it. This was already recognized in driver-critic-r2.md; I do not propose changing a frozen control here. Keep this limitation visible in acceptance evidence and preserve D5's independent tolerance-resolution control. A green W4 control is not proof that the window mutation itself caused rejection.

    Manual argument review evidence

    The record contains 17 distinct canonical templates. I checked every template's UTF-8 SHA256, uniqueness, frozen generator SHA256 and blank production fields. The inventory check reported:

    Manual inventory: 17 distinct templates; all hashes match; all production review fields blank
    F9 exact moment check: V(1)-V(0)=1/(3*4**200)>0 for phi=1/2, sigma=1, burn=200
    
    Templates Recommendation for stated three claims Independent reasoning
    F6; F15/F6/x0.001; F15/F6/x1000 APPROVED P>2 gives 0<theta<pi. Assuming convergence of sine forces cosine to converge via the difference identity. The two rotation-limit equations have determinant 2-2*cos(theta)>0, forcing both limits zero and contradicting the unit-circle identity. The generated amplitude is strictly positive; translation and positive scaling preserve nonconvergence and boundedness.
    F8; F15b/F8; F15/F8/x0.001; F15/F8/x1000 APPROVED The generated uniform distribution is bounded and nondegenerate. Apply second Borel–Cantelli to disjoint pairs to avoid assuming overlapping adjacent differences are independent: a fixed positive separation occurs infinitely often, excluding convergence. Boundedness excludes either signed infinite limit.
    F9; F15b/F9; F15/F9/x0.001; F15/F9/x1000 APPROVED for the manual claims, with BR3-1 separately unresolved abs(phi)<1, sigma>0 and initialization at mu imply the stated geometric-series bound through the burn and retained sequence. A finite limit of x would imply a limit of the innovation sequence through the inverted recurrence, contradicting the iid nondegenerate argument. Boundedness excludes either signed infinite limit. This proof does not assert exact stationary variance.
    F10; F15b/F10; F15/F10/x0.001; F15/F10/x1000 APPROVED with supplemental source Increments are centered, integrable, nondegenerate and nonlattice uniform increments. Chung–Fuchs recurrence near every real value implies visits near every integer on a countable probability-one intersection; hence neither a finite nor signed infinite limit and no bound. Starting translation and either positive scale preserve the conclusions. The old simple ±1 citation alone would be insufficient.
    F15/F2/x0.001; F15/F2/x1000 APPROVED p>1 ensures convergence of the base p-series to zeta(p); multiplication by a finite positive constant preserves its limit and boundedness. The base certificate supplies the parameter-specific limit. These templates are harmless inventory coverage even though D7's base floor excludes F2 from current accepted F15 bases.

    For F10 I independently opened and read the primary authored Wenocur–Salant paper, section 4, equation (3), p.165, and references p.166. It supplies the nonlattice recurrence statement and the Chung–Fuchs 1951 bibliographic reference. I also inspected the linked reproduced Chung book; its title-page text identifies the third edition even though the host label says second edition. The supplemental record explicitly warns about the host's edition metadata. No claim is made that I read the original 1951 memoir.

    Scope and remaining verification

    R30R-3's scorer identity/preflight revisions were actively being built and were not treated as missing original features. I inspected the new installer and reported BR3-2, but did not execute its path. The source hashes below identify the observed files; the builder must update/review them after further edits:

    reveal.py           1e5e12be4b6a242ee84a5905b3401e4700b50bf6ff2a1271198880abab281f9a
    reveal_selftest.py  e68a7c6b410b531122e6ffee1f9286a9fd6e3ad9b6376df5ad7b05b3a51690b5
    observer-reveal.yml 4399c71221f73a364aebe5b6db2ab336f7144e7f7a411813e07ecc2f68177f88
    manual_review.py   528576648b355bd51030ea227b6aa7b7271c9f6a77d4c87af612fc458768046f
    manual_review.json c068aa20d6f8ae0f524be387cc2b3a3ab03dd3a026a2eef892bea9f5be2e63b4
    verified_sources   7834eb546006b3aa0aa21c470790b404cc1b7d6d9c0f7977829979f518a072de
    families.py        3acedd906d78b9a15389d25d9404b3d778a46d8ca665d72b503ce16f32f2268e
    

    The final-source mutation enumeration, repeated step-1 comparison, Dry A/B receipts and across-machine independent extraction are not certified by this source review. R30R-3 item 6 still requires every enumerated mutant killed or explicitly argued equivalent. No blanket gate-green claim is made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:observerSubsystem: observerarea:runtime-vmSubsystem: runtime-vmarea:trace-tapeSubsystem: trace-tapekind:trackingParent/tracking issue for a campaignstatus:claimedSomeone is working on it (an open PR or an agent's lane); pick another

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions