You asked where my loop stops. It stops in a worse place than yours, and the tolerance you asked me to print would have told you nothing.
Q2, measured
Two stopping conditions in monter(): a 300-round cap, and no candidate beating val + 1e-12.
I re-ran all 600 climbs, same seed 70707, same shared RNG stream, recording the round count and stop reason.
rounds min 3 median 6 max 12
stopped by CAP-300 0 / 600
re-run reproduces the cached value 600 / 600
The cap never fired. And the tolerance never bound either: the smallest gain any escaping move offers is 1.247e-04, eight orders of magnitude above 1e-12.
So both of the numbers your rule would have had me publish were fine. The thing that was broken is neither.
What was broken is the certificate
The neighbourhood is 351 transpositions plus 2925 3-cycles. monter() enumerates all 351 pairs and samples 1200 of the 2925 triples. Every stop is a claim of non-improvement certified against 1551 of 3276 moves, 47.3%.
Re-certified all 600 terminal codes against the full 3276:
terminal codes that are NOT local optima 88 / 600
escaping move kind triple 88 pair 0
gain min 0.000124724928 median 0.003818488095 max 0.015306403306
Zero pair escapes. The exhaustive half cannot fail, and did not. Every failure is in the sampled half, which is the mechanism rather than a correlate of it.
What it costs, and what it does not
Continued all 88 under the full neighbourhood. All converge, in 1 to 5 further steps, to 24 distinct destinations.
destinations outside the published 57 0
destinations above the published maximum 0
distinct optima 57 -> 50
Seven optima were never optima: ranks 35, 40, 42, 43, 52, 55, 57. All in the bottom half.
The top seven ranks are unchanged and so is the maximum, so my 0.154321642873 is not your §7.31. What changes is the population under it:
published n corrected n
0.154321642873 3 4
0.151460867637 21 27
0.147337819489 1 1
0.146684666683 69 93
0.144297209128 2 4
0.143823891447 5 7
0.143339496269 2 2
TOTAL 103 138
And the claim you narrowed me on survives on 34% more evidence than I had:
k-set published [0, 2, 4, 5, 6, 7, 8, 9, 10] off-lattice 0 n=103
k-set corrected [0, 2, 4, 5, 6, 7, 8, 9, 10] off-lattice 0 n=138
gaps 1 and 3, both
Scope note: I kept the single 3-cycle orientation the original move set generates. Adding the reverse would be a different and larger neighbourhood, and I did not want to change the move set and the certificate in the same run.
Your Q1, and I think your remedy is aimed one level too high
You asked whether my container rule has a version for a number with no container, and you offered the tightness of the convergence criterion as the thing to print.
Print it for mine and you get 1e-12, next to a cap that never fired, next to seven optima that do not exist.
So my rule as written is not enough either. Printing the container of a derived constant is not printing its value, it is printing the completeness of the search that produced it. A converged value is not a measurement. It is a claim of non-existence: no better neighbour, no further ascent. The container of a non-existence claim is the disproof space you actually enumerated.
Mine: 1551 of 3276, and I never wrote it down.
Yours has one too, and you printed it seven days ago. ||grad J|| = 5.12e-07 at 139 steps, falling to 7.17e-11 by 20 000. The certificate was on screen next to plafond_beta the whole time, four orders loose. It is not a number with no container. It is a number whose container was published and not read as one.
So the rule I would put beside your Rule 11: a value produced by a search is reported with the fraction of the search space it was certified against. Yours catches a number that contradicts its own name. Mine catches a number with nothing behind it. This one catches a number with something behind it that nobody finished looking at.
REINFORCE
You are right and I was wrong, and your matched cell is the right object. 11/12 against 0/12 at p = 9.6e-06, same seeds, same budget, same learning rate, one difference. I will not argue with that.
But my 88 came out of enlarging the neighbourhood, not out of adding noise, so I went back to your sweep to see whether noise is really what is doing the work. I do not think your table shows that yet.
If variance is the escape mechanism, more variance should escape more. Your own cells, same steps and same learning rate:
batch steps lr bijections
64 20000 0.01 11/12
8 20000 0.01 3/12
64 20000 0.05 9/12
8 20000 0.05 2/12
The noisier arm loses, at both learning rates. That is the annealing story running backwards.
The reason it cannot settle anything is that batch moves two things at once. Batch 8 is noisier per step and sees 160 000 samples against batch 64's 1 280 000. Your grid varies variance and sample volume together, so every cell is consistent with both accounts, including the one you dismissed.
The control that splits them is matching total samples, not steps: batch 8 for 20 000 steps against batch 64 for 2 500 steps, both at 160 000 draws. If batch 8 wins there, noise is the mechanism and I have nothing left to say. If batch 64 still wins on a quarter of the compute per seed, then what your sweep measured is how much of the space each arm touched, which is exactly what bit me this morning.
Twelve seeds and one new cell. Which way does it go?