R5 post-overflow follow-up (2026-10-10)
R5 = 1RB1LA_1RC1RE_1RD0RD_1LA1RC_1RF0LE_1RA---. Follow-up to the funded watch run (work/qleft_24h.txt), which reached the overflow and died at loop 304M with MemoryError. Approved by Dennis.
Status: a direct simulation of 2e13 steps from just before the overflow is running, detached. It was launched 2026-10-10 23:11 PDT. Its log is work/r5_post.log. ETA: about 22 h at 2.5e8 steps/s, so around 2026-10-11 21:30 PDT if the machine does not halt first.
1. What was dumped
scripts/r5_dump.py re-ran the same qsim configuration: block 12, backsymbol, prover, recursive, exact steps. It ran to loop 300,000,000 in 6,481 s under nice -n 10 and ulimit -v 7000000, and wrote work/r5_qsim_dumps.jsonl (742 full configurations plus check lines).
- Reproduces the 24 h run exactly: the step count matches at all 150 loops where both runs logged (every 2M loops up to 300M).
- Schedule: one full row every 2M loops from 200M on, every 100 loops in 287.99M..288.03M, every 10k loops up to 290M, and every 100k loops up to 300M.
- The overflow is between loops 288,010,300 and 288,010,400, at steps 4,391,021,972,196,788 .. 4,391,022,056,149,912.
- Up to loop 288,010,300 the left end is the old one: the first block is 011110111111, and the 1^4 still sits at cells 1..4.
- At loop 288,010,400 a new block 000000000011 appears to its left, so the tape grows to the left for the first time since step 35,809.
- After that qsim crawls: 100 loops cover only about 4e3 to 1e4 steps, against about 3e9 before.
Why the direct run starts at loop 288M, not 286M
Loop 286M is at step 4,329,936,209,482,021. That is 6.11e13 steps before the overflow, so a 2e13-step run from there would never reach it. Loop 288M is 3.147e11 steps (about 21 min of C) before the overflow, and it is also a row of the old 24 h log.
Both dumps are written:
- work/r5_pre_overflow.json: loop 288,000,000, step 4,390,707,259,988,964. State D, head moving R, backsymbol 111010101010. 100,660,080 explicit cells, head at index 25,165,236, 79,689,235 nonzeros.
- The file holds every left and right [word, exponent] block in left-to-right order (12-cell words; the 0^inf ends are listed as exponent "inf").
- dh is a directed-head string with block words and exponents, for example 0^inf 011110111111 ... D> (111110111110)^6291236 111111100000 0^inf. tools/sim.py Config.parse reads it.
- The conventions are stated in the file.
- work/r5_pre_overflow.cfg: the same configuration in R5CFG text form, which is the input of scripts/r5run.
- work/r5_loop286M.json: loop 286,000,000, the configuration the task named, in the same format. It is not used by the run.
Cell frame. Index 0 is the first cell of the first finite left block, which is absolute cell -60 of the blank-start run. This was checked against tools/sim.py from blank at loops 20k, 100k and 200k. At loop 288M the 1^4 is still at index 1..4, i.e. absolute -59..-56, the left edge of the 1e10 direct run. Every position in the log uses this frame: absolute = rel - 60. Cells left of the old edge get negative indices.
2. How it was checked
- Expansion vs direct simulation from blank. The qsim rows at loops 20k, 100k and 200k (up to step 2.1e9) were expanded by
scripts/r5_expand.pyand compared withtools/sim.pyrun from the blank tape to the same step. Tape, head, state and dir were identical. Thedhstring also parses back to the same configuration. - The C driver vs qsim.
scripts/r5run(C, the same table engine as tools/sim/tmsim, 2.55e8 steps/s on a 1.4e8-cell tape) compares its tape cell by cell against a qsim dump, aligned on the head, at the dump's exact step. It also checks state and direction. A "verify" line is written each time. - From loop 20k to 400k: 19/19 exact. - Tests that the check fails when it should: refs shifted by a prepended zero block still pass, and a corrupted cell (including one at a negative position) is reported. - A resume from a checkpoint reproduces the same log lines. - The halting path matchestools/sim.pyon0 <A 101: halt after 4 steps, F reading 1. - Pre-launch, from the 288M dump. Over 1e10 steps, 3/3 qsim refs were exact (loops 288,000,100, 288,000,200 and 288,000,300). Log:
work/r5_pre_check.log. - In-run. The long run carries all 597 qsim dumps from loop 288,000,100 to 300,000,000 (
work/r5_refs.cfg) and verifies each one when it reaches its step. That covers the overflow at rel step 3.147e11 and qsim's whole post-overflow stretch up to rel 4.735e11 (loop 300M, step 4,391,180,753,576,240). - Result at return time: see section 5. - Past rel 4.735e11 there is no reference. qsim never got further (MemoryError at 304M), so the run is on its own from there.
3. Where things are
| what | where |
|---|---|
| log (JSON lines) | work/r5_post.log |
stderr (a plain HALT at step N line goes here too) |
work/r5_post.err |
| checkpoint, rewritten every 1e12 steps (packed bits, about 13 MB) | work/r5_post_ckpt.bin |
| start configuration | work/r5_pre_overflow.json / .cfg |
| qsim dumps and refs | work/r5_qsim_dumps.jsonl, work/r5_refs.cfg |
| scripts | scripts/r5_dump.py, scripts/r5_expand.py, scripts/r5run.c (+ binary), scripts/r5_post_launch.sh, scripts/r5_post_view.py |
The process is scripts/r5run r5_pre_overflow.cfg 2e13 1e10 --refs r5_refs.cfg --ckpt r5_post_ckpt.bin --ckpt-every 1e12.
- It runs in its own session under nice -n 10 and ulimit -v 6000000, single-threaded, with about 170 MB RSS.
- Find it with pgrep -af 'scripts/r5run r5_'. Stop it with kill <pid>.
- After a reboot or kill, scripts/r5_post_launch.sh resume continues from the last checkpoint into the same log, with the same schedule.
4. How to read the log
One JSON object per line, keyed by ev:
- start: the configuration loaded and the run limits.
- log, once every 1e10 steps:
- step (absolute) and rel_step (from 4,390,707,259,988,964);
- state, and dir (the last move);
- head, lo and hi (the span is the explicit cells plus every visited cell), span, nonzeros;
- first1/last1 (the outermost 1s), head_from_right;
- left, the 300 leftmost cells of the span, and right, the 200 rightmost;
- steps_per_s, and t (seconds since the start).
- verify: ok, and the qsim loop and step it was checked at. ref_cell0_rel is where qsim's own cell 0 falls in our frame (0 before the overflow; it goes negative when qsim adds blocks on the left). first_mismatch_rel / nonzero_outside_ref_rel are null when the match is exact.
- HALT: the exact step of the halting transition, counted as a step as in tools/sim.py, plus halt_from/halt_read. It is followed by a halt_config line, the same fields as log.
- end: reason is max_steps or halt.
Quick looks:
cd "[local working file]"
python3 -B scripts/r5_post_view.py --cells 80 --every 10 # table: rel/1e10, state, head, lo, hi, span, nonzeros, ...
grep -n '"ev":"HALT"' r5_post.log; tail -c 2000 r5_post.log
What to look for:
- lo going negative: the tape grows to the left, a new left-moving front.
- Whether hi (the right edge) resumes its slow growth, which was about +4 cells per cycle in the old epoch.
- Whether the left window settles into a repeating gadget pattern (a new epoch) or keeps changing.
- nonzeros over time.
5. State at return (2026-10-10 23:45 PDT)
- The run is at rel step about 4.8e11, at 2.5e8 steps/s. It started at 23:11 PDT; 2e13 steps should end around 2026-10-11 21:30 PDT. The first checkpoint is due at rel 1e12, around 00:20.
- All 597 qsim references were exact: 597 ok, 0 failed. That includes the two across the overflow:
- loop 288,010,300, with qsim's frame still at 0;
- loop 288,010,400, where qsim has put a new block on the left (
ref_cell0_rel-12). - What the overflow did (first post-overflow log rows, confirmed by the qsim dumps). Preliminary, from 16 log rows:
- It erased the old tape. qsim's dumps show 8.39e7 nonzeros at loop 288,010,400 (step 4,391,022,056,149,912) and 1,681 at loop 288,030,000, 3.7e8 steps later.
- What is left, besides a few cells near the head, is a small island near rel 2.5166e7 (where the head turned at loop 288,010,300) and
1^7at the old right end, rel 100,663,687..693. - A new structure then grows from a new left edge. The span starts at rel -2 (absolute -62) from rel step 3.2e11, and at rel -7 at 4.7e11.
- Its nonzeros grow 71,715 → 400,378 over rel 3.2e11 → 4.7e11. The head works within the first ~5e5 cells.
- From rel 3.2e11 to 4.6e11 the new left end reads
1^10 0 1 0 1^7 0 1^7 0 1 0 1 0 1^3 0 1^9 (01)^8 .... - At rel 4.7e11 the edge moves to rel -7, and the left end becomes
1^4 0 1^7 (01)^4 0 1^7 .... - So the left edge is still moving, as in the first epoch's early phase (steps 0..3.6e4). The old main-epoch prefix was
1^4 (01)^11 1 (10)^4 .... - Reading so far: the overflow resets the machine to a fresh epoch on an almost blank tape. Its scale looks like the first epoch: the first epoch had 107k nonzeros at 1e10 steps from blank, and this one has 4.0e5 at about 1.6e11 steps after the reset.
- If it is the same counter with a new reservoir, its right front reaches only about 7e6 cells by the end of this run. It would meet the island at 2.5e7 after roughly 3e14 steps.
- So this run shows how the new epoch is built and how big its reservoir is, but probably not the next overflow.
- Possible next step, for Dennis to decide: a fresh qsim run seeded from a post-overflow dump. The old run's MemoryError came from its long history, not from the new epoch. Or the epoch-map stage, now with one real overflow to model.