/machines/1RB0LE_1RC---_0RD0RB_1RE0LA_1RF0LF_1LD1RF/rocq/plan-check.md · raw

W6-1 planning stage: independent check (2026-10-14)

This is a check of the formal-planning stage (W61Exit.v, W61Plan.v, plan.md). It was made from a fresh compile in a separate directory. None of the author's files were edited.

Verdict

1. Recompilation

Setup:

SOBCv10.v was compiled from scratch rather than reusing the author's .vo.

file sha256 (first 8) result time memory
SOBCv10.v (vendor 0940bb9) 227009dd exit 0, only funext 88 s 0.80 GB
W61Exit.v a1ace5ad exit 0 2.0 s 0.45 GB
W61Plan.v d0b31e60 exit 0, 4 Admitted 1.6 s 0.45 GB
reviewer's W61Check.v e0341aef exit 0 5.4 s 0.47 GB

The vendor SOBCv10.v, upstream cdaf693:verify/SOBCv10.v and rocq/build/SOBCv10.v have the same sha256. The rocq files and their build/ copies are identical. git status in vendor shows only the untracked .coq-native/ from 2026-10-09. Nothing in vendor/ is newer than proof.md.

2. Assumptions, lemma by lemma

Print Assumptions on every lemma in the report's "proved" list:

lemma assumptions
raw_tail_base, raw_tail_column, raw_tail_columns none
cycler_step, cycler_nonhalt none
overflow_base, overflow_column, overflow_columns, exit_nonhalt none
pre_rotate_list, nested_pre_left, launch_far, relaunch_far, relaunches_far none
nested_launch funext
E_to_B, digits_word_repeat_BB, digits_value_repeat_BB, nested_counter none
nested_exit funext
entry_last_value, entry_level, perm none
sobc_D_nonhalt, nonhalt tail_round, tail_round_trigger, opening, entry_pre, funext

A grep of W61Exit.v finds no Admitted, admit, Axiom, Parameter, Hypothesis, Conjecture, Abort or guard switches.

tm61 prints the 12 transitions of 1RB0LE_1RC---_0RD0RB_1RE0LA_1RF0LF_1LD1RF, the string at line 10 of the 740 list. perm and nonhalt are a correct mirror-and-rename bridge (A..F to D,E,F,A,B,C, our start = SOBCv10's state D).

3. Do the statements say what plan.md and proof.md claim?

C (cycler). Busycoq's notation l {{q}}> r puts the head on the first cell of r, in state q. So (rev Yw *> L) {{B}}> 0inf is "L, then Y, then the head in state B on the first blank cell". Yw is proof.md's 70-cell Y, cell for cell.

So C really is nonhalting from the cycler entry. Lemma O ends exactly in that form: overflow_base ends in (rev Yw *> [0;1;0;1] *> l) {{B}}> 0inf.

O (overflow). overflow_base is proof.md's Lemma O with w = 1: B U^13 B t becomes 1010 Y B>, with l never read. overflow_column and overflow_columns extend it to any all-B layout through SOBCv10's raw_B_forward and raw_Us_to_Xs. This matches proof.md section 5.4.

T2 (raw pass). It matches proof.md section 3 and opening family (c):

"Any column layout" means any widths with every digit B. That is the only case that occurs, because the raw pass starts at a trigger, when the counter is all B.

E′ and E″.

What remains open is that exception 9 actually reaches nested_exit's configuration (exception_call_left c f, then B>, then an all-B layout, then U^11 B t). That is tail_round_trigger's job, as plan.md says.

Two small slips in plan.md, neither of which matters:

4. Problems in the open statements (W61Plan.v)

4.1 tail_round is false as stated (proved)

Both lemmas below compile, and Print Assumptions lists only tail_round.

(a) k = 4 without a trigger. Take current = 100, previous = 10, zs = [], last = [SB;SA;SA] (value 1, length 3), k = 4, lv = 5.

This is tail_round_false_k4 : False.

(b) A last column of length 2. Take last = [SD;SD] (value −3), k = 1, lv = 4.

This is tail_round_false_len2 : False.

The chain in sobc_D_nonhalt uses only k = 1, 2, 3 and lengths 29 to 26, so the statement fix is two hypotheses: k <= 3 (or tp_k : k <= 5 in the conclusion) and 3 <= length last. Until then, the four Admitted are inconsistent.

Proof skeleton of (a), from W61Check.v:

Definition cx_last4 : list SDigit := [SB; SA; SA].
Lemma cx_pre4 : tail_round_pre 100 10 [] cx_last4 4 5.  (* constructor; lia / vm_compute *)
Lemma cx_not_trig4 : ~ tail_triggers 4 cx_last4 5.      (* vm_compute *)
Lemma tail_round_false_k4 : False.
Proof.
  destruct (tail_round _ _ _ _ _ _ cx_pre4 cx_not_trig4)
    as [zs' [last' [lv' [_ [P _]]]]].
  destruct P as [_ _ _ _ _ Hk _]. lia.
Qed.

4.2 The draft precondition is not inductive

Forall column_safe zs does not survive a step. SOBCv10's own column step breaks it. A width-4 column of value 3 whose right neighbour is even steps to 2^4 − 1 = 15 > 2^4 − 6. This is safe_not_preserved, which is closed.

SOBCv10 carries columns_schedule, the abstract schedule theory at lines 3345-3790, for exactly this reason. With a tail, the rightmost z-column steps with the last column's parity, not with the constant true of SOBCv10's abstract_columns_next. So that theory is not reusable unchanged, although plan.md lists it as reused unchanged.

Only 4 rounds are needed, so SOBCv10's lineage_inputs_safe (line 942, which takes arbitrary input parities) looks like the right tool. That is new glue, and the plan does not include it.

tp_last_window does not survive a step either. The last column's law v → 2^(w−1) − ⌊v/2⌋ keeps the upper bound only when v ≥ 12. The window also admits small and negative v.

It does hold on the real trajectory. I recomputed proof.md section 4, deficits included:

Suggestion. The last column is concrete in all four rounds (29 to 26 digits, known values). Pin it in the precondition, or state four round lemmas with the concrete last column. That avoids a general signed-digit invariant, and it is also the plan's own fallback for the T3 risk.

5. Is the estimate honest?

It is optimistic by about 40%. The plan's top value (12) is at the bottom of my range.

item plan check why
R1: statements and invariant 1 1.5-2 tail_round must be restated (4.1). Z-column safety needs a schedule or lineage argument with the last column's parity (4.2). The window must be tied to the trajectory.
R2-R5: the tail-aware round 4 5-6 The T3 decode with D/E deficit digits needs new signed odometer lemmas. SOBCv10's frontier, raw-pass, decode and odometer part (about lines 1373-3310) all gain a column plus a tail.
R6: trigger round 1 1-2 Closed form of nested_required against h_t on a symbolic layout.
R7-R8: opening 2 3-5 See the note below this table.
R9: kill file 1 1-1.5 check_kill accepts exactly one top-level Definition tm and flags any re-binding of tm. The inlined SOBCv10 defines its own tm (its own table string), so it must be renamed throughout the 4,234 lines. The other route is to build SOBCv10.vo in vendor and import it through check_kill's framework_build path. The plan does not mention this.
contingency 0 1-2 Exceptions 6-9 are model-only, and never simulated at real size. An off-by-one moves the exit (proof.md section 6), which changes the k that triggers and the number of rounds. tail_round_trigger is specific to k = 4.
total 10 (9-12) about 14 (12-18)

Why the opening costs more than 2 stages:

Plan.md's own line counts point the same way: 800-1,200 generalized lines plus 600-900 new opening lines is about 1,400-2,100 hard lines. That is more than any kill in this repo so far, and those took 500-1,800 lines, mostly adapted from a close template.

The re-ask after R4 is a good control, but by then about 8-10 h are spent and the opening, the other big unknown, has not started. A cheaper order would be:

  1. the statement repair (4.1) and the invariant design (4.2), half a stage;
  2. a spike proving family (b)'s closed form, the least checked claim;
  3. then R2 onward.

6. What the decision card should say

Reviewer's files (scratch, not part of the machine folder)