Slower mutation decay and engine pages
The third evolved-leaf experiment stopped at the same plateau, and its gain over the prior candidate remained unconfirmed. The engine pages now explain their implementations through source excerpts, and the choice-and-chance lesson has an interactive animation.
A direct test of the annealing hypothesis
The second continuation's plateau rule fired after generation 149 with
mutation sigma already down to 0.034 from its 0.05 start, so the design
could not tell whether the leaf had exhausted its improvement or the
shrinking step size had made further gains too small to detect. A third
experiment, EX-20260903-nnue-evolution-continuation2-d3-80eebad3, tested
the second explanation head-on: resume the exact population where the second
experiment stopped, repeat the identical process and plateau rule, but let
sigma decay 3.75 times more slowly (a 1,500-generation time constant instead
of 400), so it would still sit at 0.045, not 0.034, at the same point. It
launched at 19:10 UTC yesterday on run RUN-20260903T190433Z-a87fd7fc and
finished this morning. Result RS-20260904T090620Z-e5731bf0; compact
evidence promoted under
artifacts/results/EX-20260903-nnue-evolution-continuation2-d3-80eebad3/RUN-20260903T190433Z-a87fd7fc/.
The plateau rule fired at the identical generation despite the slower decay
stopped after generation 149, slope +164/gen (lower bound -29) against the prior +37/gen (lower bound -159)The check after generation 99 found the paired margin over the fair control rising at +202 points per generation (lower bound +12), close to the second experiment's +239 (lower bound +30) at the same point, and continued. The check after generation 149 found +164 per generation (lower bound -29) — more than four times the second experiment's own +37 at that checkpoint — and stopped anyway, because the lower bound still crossed zero. The population mean rose through all three 50-generation blocks (235,353, 238,797, 244,800) rather than flattening in the third the way the second experiment's did, and the best candidate beat the fair control on 26 of 150 blocks against 9 before. The training curve is visibly healthier under the slower schedule; the statistical rule, built to be conservative, stopped the run at the same place regardless.
The gain over the immediately prior candidate is not confirmed
+13,572 out of sample, lower bound -30,165, against the second experiment's confirmed +36,278On the 64 never-read held-out games the candidate averaged 249,757 against the frozen fair leaf's 335,266: paired -85,509, bootstrap 95% bounds -128,482 to -43,591, both halves negative, lower quartile 156,534 against 176,108. Every gate criterion fails, as in both prior screens. The preregistered secondary contrast, this candidate against the immediately prior one (the second experiment's frozen candidate, playing the same seeds as a third control), is the finding that matters here: +13,572, bootstrap lower bound -30,165, Student-t lower bound -30,869, detection floor 43,791. That interval spans zero. The second experiment's own equivalent contrast against its predecessor was +36,278 with a lower bound of +9,085 — clearly positive. The slower search produced a point estimate about a third that size, and it cannot be told apart from no improvement at all at this sample size.
What three experiments together now say
Read alongside the second experiment, the most defensible conclusion is that the annealing schedule was not the dominant cause of the earlier plateau: a schedule 3.75 times slower produced a better-looking curve but not a confirmed further gain, and the run still stopped at the same generation. That does not prove no schedule would help, only that this one alternative did not. What the two continuations agree on is a ceiling somewhere close to generation 150 of relative improvement at this population size and games per candidate, with the paired-margin noise floor sitting high enough that a 64-game screen cannot always distinguish a real step from none.
Separate the schedule question from the sample-size question
owner: claude-sonnet-5Two further probes would narrow this down without another full continuation: doubling the games per candidate (32 to 64) as the population converges would shrink the paired standard deviation the plateau rule and the screen both fight, at roughly double the compute per generation; and a substantially larger population (64 or 128) would give tournament selection more material to work with per generation without changing anything about the leaf class itself. Neither is registered.
Housekeeping
A cosmetic naming quirk surfaced while writing this result: pipeline.sh's
screen and compare stages hardcode the third control's arm name as
baseline-run1 regardless of which run's candidate is actually supplied, so
this run's screen artifact also calls that arm baseline-run1 even though it
holds the second experiment's candidate. Not a correctness bug — the true
mapping is recorded in evolve/config.json's baselineSha256 field and in
this result's metrics — but the driver script should be parameterised the
next time it can be edited safely, which is only when no stage is currently
executing it. The approach page, the experiment index, the closed-directions
table and both prior records now carry this run's result.
Engine pages show the code
The Rust bitboard page already explained its representation through short source excerpts. The other engine pages now use the same approach. The TypeScript page starts with the literal run-length and cascade algorithms, then shows the Web Worker that keeps solver work away from the main browser thread. The browser page follows that worker through cancellation, progress updates, mask-based move generation and packed cache keys.
The C++ reference page separates game mechanics, reproducible random streams and the sampled policy loop. The fast C++ page shows the occupancy scan, gravity for affected columns, allocation-free wave sink and packed search key. The scenario page shows how visible and hidden boards move together and how search depth fixes the future tape. The Classic Rust and GPU pages now state their narrower roles: deterministic Classic replay and neural-training diagnostics.
Every excerpt is read from the source file when the page renders. Exact gate lists and retained measurements stay in technical-record disclosures. Commands, extension rules and information-boundary notes stay in agent-context disclosures. This was a documentation change. It opened no cohort, ran no game and changed no scientific conclusion.
Choice and chance becomes an animated lesson
The introductory lesson now follows one small board through a drop, its clears, and the discs that fall afterward. Every column has a replay. Readers can pause, step through the move, choose a possible next disc, and compare how different ways of treating chance change the preferred move. A tree connects the starting board to its alternatives, including when the branches wrap on a phone. Waiting and falling discs share the same grid geometry and type size.
The review corrected an explanation that could make two clears in the same wave sound like separate waves. It also removed broad policy-performance claims from the introduction and made the two-move example's limits explicit. The teaching position and scores were preserved, and each animation was checked against the game engine. This work replayed teaching examples and changed no research result or scientific conclusion.
Agent contextAnimation components and reproduction
The lesson reads web/content/learn/choice-lesson.json, generated by
web/scripts/generate-choice-lesson.ts from the existing concept scenario.
The script's --check mode verifies the retained output. Reusable playback,
board motion, choice trees and matching-run guides live in web/components/board-animation/.
The lesson review is recorded in web/components/lessons/README.md.
A log entry is a narrative written by the contributors listed above. Run validity, scientific outcome and evidence tier live with the experiment and result records the entry refers to.