Chaotic Bell Class 3: the write-1 exit study
2026-10-14, strategy direction 4. Claim: CB3 core (coord/claims.tsv). All paths are under [local working file]
In plain words
The 12 lines are one machine core started in 12 ways. Its tape is a long stripe of 0101.... Two kinds of marks sit in that stripe:
- separators, the 5-cell word 00110;
- gliders, a single extra cell (0 or 1) that breaks the stripe's rhythm.
The head bounces between the left end of the tape (the wall) and the nearest glider. Each bounce pushes the glider one step further right. When no glider is left, the head sweeps the whole tape instead. Each full sweep pulls the first separator one step closer to the wall and adds a new separator at the right end.
When a separator reaches the wall, the rare transition fires. This is the "exit", and it turns that separator into a new glider.
The holdouts differ from their proven siblings only at the exit: there it writes a 1 instead of a 0.
Answer to the key question: the extra 1 stays bounded. It never survives as a mark of its own. Within two bounces it merges into the stripe next to the wall, and the result is exactly the sibling's glider, one bounce later and with the wall one stripe unit (01) further away (rules X1/X0 below, 20/20 random checks each against tools/sim). So each exit acts as a one-bounce delay, not as a counter.
Over 10^10 steps on all 12 lines: - the number of loose marks (anything that is not a separator) never exceeds 9; - the parity defects it causes (separator gaps of even length) never exceed 7 among up to 20,600 separators; - in the write-0 siblings even gaps are only transient (at most 2, in 4-16% of samples), while the holdouts carry a few persistently (in 83-97% of samples).
So the stop rule points to the regular-language route, not to a cryptid write-up. This stage found no certificate: - upstream's sibling recipes fail on the holdouts (FAR: 0 of 450 runs, critic; RWL_mod: out of memory at the 6 GB cap on all 3 tables, though it proves the write-0 sibling in 7 s); - a quick n-gram closed-position-set search is too weak even for the siblings.
The language that should close is described below. Building a checker for it is the next stage (decision.md).
The 12 lines and the working labelling
All 12 machines are one table up to renaming and mirroring, except for one transition. In the labelling of line 206, which I use throughout ("W"):
A: 1RB 0LC B: 1RC 0RA C: 1LA 0LD D: 1LE 0RB E: ??? 1LF F: 0LA ---
The free slot is E0 (upstream's canonical labelling calls it F0):
| table | E0 (W) | canonical F0 | lines (W start state) |
|---|---|---|---|
| T1 | 1LC | 1LD | 23 (D, mirrored), 206 (A), 403 (C, mirrored), 415 (B) |
| T2 | 1RD | 1RE | 69 (A), 245 (B), 330 (D, mirrored), 668 (C, mirrored), 696 (E) |
| T3 | 1RB | 1RC | 178 (A), 376 (C, mirrored), 382 (B) |
| siblings S0LC / S0RD / S0RB | 0LC / 0RD / 0RB | 0LD / 0RE / 0RC | proved upstream: FARv1.v (first two), RWL_mod_v5.v (third) |
The mapping comes from scripts/wlabel.py. Halting needs state F to read a 1, and F is entered only through E1.
Mechanism
Notation
Configurations are taken at left-end visits: state C has just stepped onto a blank left of every visited cell. They are written as the word to the right of the head:
0^inf <C w 0^inf
Inside w, 01^a means (01)^a and S is the separator 00110. A glider is a lone 0 (type _) or a lone 1 (type =) between two 01 runs.
Run rules
Every sweep flips the stripe, and two sweeps restore it:
B> (10)^n -> (01)^n B> A> (01)^n -> (10)^n A>
(10)^n <C -> <C (01)^n (01)^n <A -> <A (10)^n
At the wall, C writes two new cells and turns. The stripe grows by one 01 on each bounce.
Macro rules (all checked against tools/sim)
Each rule was tested at 20 random parameter points, by direct simulation with the project's simulator imported as a library (scripts/validate.py, scripts/rules.py, results in rules_check.json). "Visits" is the number of round trips the rule spans.
| rule | tables | from | visits | to |
|---|---|---|---|---|
G1 glider _ to = |
all 6 | 01^a 0 01^(b+2) S 01^c |
1 | 01^(a+3) 1 01^b S 01^c |
G2 glider = to _ |
all 6 | 01^a 1 01^(b+1) S 01^c |
1 | 01^(a+1) 0 01^(b+1) S 01^c |
| Sw full sweep | all 6 | 01^(a+1) S 01^c S 01^e (S 01)^d |
1 | 01^a S 01^c S 01^e (S 01)^(d+1) |
| X1 exit, T1 | T1 | S 01^(b+2) S 01^c |
2 | 01^2 0 01^(b+2) S 01^c (S 01)^2 |
| X0 exit, sibling | S0LC | same | 1 | 01^1 0 01^(b+2) S 01^c (S 01)^2 |
| X1 exit, T2 | T2 | same | 2 | 01^3 0 01^(b+1) S 01^c (S 01)^2 |
| X0 exit, sibling | S0RD | same | 1 | 01^2 0 01^(b+1) S 01^c (S 01)^2 |
| X1 exit, T3 | T3 | same | 2 | 01^4 0 01^b S 01^c (S 01)^2 |
| X0 exit, sibling | S0RB | same | 1 | 01^3 0 01^b S 01^c (S 01)^2 |
Taken together:
- Bounce phase. G1 and G2 move a glider right by one 01 unit per round trip, relative to the separators ahead of it. The wall run a grows meanwhile.
- Full-sweep phase. With no glider, Sw shortens the first gap by one per sweep and appends S 01 at the right end. This builds the long (S 01)^d tail, the "array of 1s" that dominates the tape at 10^10 steps.
- Exit. When the first gap reaches 0, the separator is at the wall, and the exit turns it into a _ glider.
Gliders and separators meeting
These cases were observed in scripts/macro.py runs, but not validated as general rules.
- A glider passes through a separator. The outcome depends on the parity of its distance to it: an even distance passes through = = _, an odd one through _ _.
- The separator ends up behind the glider and drifts toward the wall by one unit per bounce. When it arrives, the next exit fires.
- If an exit fires while an old glider is still in flight, two gliders are in flight at once. This is what the "lone defect" counts below measure.
This is the "two arrays of integers on top of one another" in the sheet's description: - the gaps between separators ahead of the glider; - the gaps behind it, which drift to the wall.
Gliders carry separators from the first array to the second.
Epochs
Exits come in bursts (1 to 15 per epoch), and full-sweep phases separate them. The separator count jumps between epochs, for example 6 → 68 → 707 → 4718 for line 206. The jump ratios are erratic: 403 goes 55 → 146 → 714 → 10950 → 17313. This matches the erratic epoch ratios Wave 6 saw.
Per-line epoch lists come from the analysis snippet over runs/line*.txt. They are not needed for the verdict, because the halting question does not depend on them (next section).
The key question: what does the extra 1 do?
Locally. Compare X1 with X0 in each table. The write-1 exit produces the same glider at the same distance from the next separator as the write-0 exit, but one round trip later and with the wall run one unit longer:
| table | write-1 glider | write-0 glider |
|---|---|---|
| T1 | 01^2 _ 01^(b+2) S |
01^1 _ 01^(b+2) S |
| T2 | 01^3 _ 01^(b+1) S |
01^2 _ 01^(b+1) S |
| T3 | 01^4 _ 01^b S |
01^3 _ 01^b S |
The extra 1 is gone after two bounces. What it leaves behind is a timing offset: the separators behind the glider reach the wall one bounce later. The glider meanwhile moves one unit further, and that flips the parity of its later separator crossings.
Globally, to 10^10 steps (scripts/cb3track.c, scripts/cb3track2.c; data in runs/ and runs_parity/):
- every exit on all 12 lines happens at the wall;
- loose marks stay at 9 or fewer at every sampled visit, and they drop back to 0 to 2 at each epoch start;
- separator gaps of even length stay at 7 or fewer among thousands of separators;
- in the write-0 siblings (run the same way to 10^10), even gaps are transient: at most 2, present in 4-16% of samples, mean 0.04-0.16. In the holdouts they persist: present in 83-97% of samples, mean 1.5-4.9;
- the siblings also settle into a regular cycle, with 794-1,156 exits per 10^10 steps against 17-29 for the holdouts.
A small automaton can lean on "almost every gap is odd". That is a plausible reason the sibling-size FAR recipes fail on the holdouts, though not a proven one.
So the extra 1 does not accumulate. It makes a bounded number of parity defects in a stripe language that is otherwise the same as the siblings'.
Per line, to 10^10 steps. "Lone defects" counts adjacent equal cells that are not part of a separator, including the pair the exit leaves at the wall. Even gaps were sampled every 1,000 left-end visits (scripts/summarize.py):
| line | table | W start | exits to 1e10 | all exits at the wall | max lone defects | max even separator gaps (% of samples with any) | separators at 1e10 |
|---|---|---|---|---|---|---|---|
| 23 | T1 | D mirrored | 23 | yes | 9 | 3 (88%) | 4721 |
| 206 | T1 | A | 23 | yes | 9 | 4 (93%) | 4715 |
| 403 | T1 | C mirrored | 23 | yes | 6 | 3 (97%) | 17309 |
| 415 | T1 | B | 20 | yes | 6 | 7 (96%) | 923 |
| 69 | T2 | A | 29 | yes | 8 | 4 (91%) | 8433 |
| 245 | T2 | B | 28 | yes | 6 | 7 (83%) | 10270 |
| 330 | T2 | D mirrored | 26 | yes | 7 | 5 (93%) | 11236 |
| 668 | T2 | C mirrored | 17 | yes | 6 | 5 (92%) | 14870 |
| 696 | T2 | E | 25 | yes | 8 | 5 (96%) | 7378 |
| 178 | T3 | A | 26 | yes | 9 | 4 (95%) | 81 |
| 376 | T3 | C mirrored | 22 | yes | 4 | 3 (92%) | 20634 |
| 382 | T3 | B | 24 | yes | 7 | 3 (95%) | 2525 |
| S0LC | write-0 sibling | A | 986 | 7 | 1 (16%) | 22345 | |
| S0RD | write-0 sibling | A | 794 | 7 | 2 (11%) | 13168 | |
| S0RB | write-0 sibling | A | 1156 | 4 | 1 (4%) | 27155 |
Why this means "regular" and not "cryptid". On every test so far, halting does not depend on the arithmetic of the arrays. This is evidence, not proof:
- Random structured tapes never halt. I built configurations 0^inf <C (01)^x0 S (01)^x1 S ... with random gaps (0-20) and up to 10 random loose marks per tape. On all 3 tables, 0 of 5,100 halted within 2·10^6 steps (scripts/randcfg.py).
- The same holds for any tape whose runs of equal symbols are at most 2 long: 0 of 2,400 halted (scripts/randruns.py).
- Halts need dense junk. Fully random tapes do halt (5-7%), and so do structured tapes packed with 20 loose marks in 6 short gaps (11-14%). Halting needs runs like 0000 or 1111. The orbit never makes them: in 4,200 left-end tapes sampled to 10^9 across the 3 tables, the longest run of equal symbols is 3.
- The marks stay in a small alphabet. Starting from random structured tapes and running 60 round trips each (150 starts per table), the clusters of marks that appear (maximal groups between two 01 runs) stay at 4 tokens or fewer. There are about 20 kinds, all with no halts (scripts/closure_sample.py).
So the cryptid trigger (non-halting resting on pseudo-random arithmetic) is not met. The epoch map is chaotic, but on this evidence the halting question does not depend on it.
Regular-language attempt (this stage: no certificate)
| attempt | result |
|---|---|
| FAR grid around the sibling recipe (critic, 450 runs on 23/69/178) | 0 true |
RWL_mod sibling recipe 1001 1000000 1000000 16 320 3 1 4 0, 900 s cap |
out of memory (6 GB cap) on T1, T2 and T3; calibration: true on S0RB in 7 s (deciders/rwl.out) |
n-gram closed position set, plain cells n ≤ 10 and writer-state history n ≤ 6 (scripts/ngcps.py) |
fails on the FAR-proved sibling S0LC, so it is too weak for this core; not run on the holdouts |
The RWL blow-up fits the picture: its abstraction has to keep enumerating parity-mixed separator arrays, which the siblings produce only transiently.
The language that should close (stated for the next stage):
0^inf <C r0 c1 r1 c2 ... ck rk 0^inf
Here each ri = (01)^n with n >= 1 (or >= 0 next to the wall), and each ci comes from a finite set of mark clusters. The base clusters are S = 00110, 0 and 1; the observed composites include 110, 00, 10, 1 S, S 1 and 0 S.
Two properties make this language a good candidate:
- it puts no condition on gap lengths or parities, which is exactly what separates the holdouts from the siblings;
- it is symmetric enough that the run rules jump over every ri in one step.
A checker needs:
- a token-level closure explorer: shapes with (01)^{>=K} runs and a "rest of the tape" star token on each side, in both stripe phases;
- the 693 explorer (machines/1RB0LD_0RC---_0LD0RF_1LE1LD_0LA0RD_0RB1RA/scripts/ctl_explore3.py) as a template for the split and fold rules.
A closed shape set compiles into left and right NFAs over cells. That is the input format of Astra's gate-passing package (astra/autonomous-20261014/certificate-package/package.py: block NFAs plus an entry path).
Per-table verdicts
| table | lines | verdict |
|---|---|---|
| T1 (E0 = 1LC) | 23, 206, 403, 415 | Same mechanism. Extra 1 bounded (≤ 9 loose marks, ≤ 7 even gaps to 10^10). Regular route; no certificate yet. 23 and 206 run almost the same orbit. |
| T2 (E0 = 1RD) | 69, 245, 330, 668, 696 | Same mechanism; exit glider starts one unit closer to the next separator than in T1. Bounded (≤ 8 loose marks). Regular route; no certificate yet. |
| T3 (E0 = 1RB) | 178, 376, 382 | Same mechanism; exit glider two units closer. Bounded (≤ 9 loose marks). Regular route; no certificate yet. |
All three tables share G1, G2, Sw and the run rules exactly; only the exit offset differs. So one closed language with a per-table exit case should cover all 12 lines. Each line still needs its own startup from blank, which is routine.
Files
scripts/core.py,scripts/wlabel.py: the 12 lines, tables, labelling.scripts/cb3sim.c,scripts/cb3track.c,scripts/cb3track2.c: C trackers (exits, loose marks, gap parity);scripts/run1e10.sh,scripts/runpar.sh,scripts/runpar2.sh; outputsruns/line*.txt,runs_parity/*.txt.scripts/macro.py,scripts/tok.py: macro step from a left-end visit, and the token view.scripts/validate.py,scripts/rules.py: rule checks against tools/sim;rules_check.json.scripts/randcfg.py,scripts/randruns.py,scripts/randtape.py,scripts/cfgrun.c: random-configuration halting tests.scripts/closure_sample.py: sampled closure of the candidate language.scripts/ngcps.py,deciders/rwl.sh,deciders/rwl.out: certificate attempts.scripts/summarize.py: the per-line table above.