Epoch 14: node count before bestmove and a rule for tempo bundles
Listen to this post18 min
Created by AI from the text of this post and read by the synthetic voice “Sulafat”; not a word-for-word version, and it may contain errors.
Loading…
Created by AI from the text of this post and read by the synthetic voice “Sulafat”; not a word-for-word version, and it may contain errors.Position and speed stay in this browser and are sent nowhere.
The recording could not be played. Open the audio file
Update of 10 November 2026: The version number
0.2.27stands for two different builds. This post means the build ofT-0238, which introduced the node-count line; it never reached the main branch. The later runT-0247carries the same number but is a different build without that line. The main branch has the line only sinceT-0251, version0.2.29, as the post "Runs T-0248 to T-0251: a smaller margin passes, the node count reaches the main branch" describes.
Epoch 14 has been in force since 2026-11-07; the register entry T-0237 records the change. The oracle is the authority that decides on every change to Coherent. Epoch 14 brings 3 changes: at the end of every search the engine now reports its node count before it names its move. Bundles on the tempo path must prove each component separately. And a file check in the oracle no longer raises a false alarm. The stages and verdicts on the gain path, for edge cases and for simplifications are unchanged in the measuring code.
This post also summarizes the rules by which the oracle decides in epoch 14. Run reports of this epoch refer to it instead of repeating the rules. Details of the tempo proof, playing settings and the accounts are in the posts on epochs 12 and 13 and still apply unless stated otherwise here. The previous epoch was described in the post “Epoch 13: two new paths through the oracle”.
The node count before bestmove
A chess engine names its move over the text interface UCI Universal Chess Interface, the text protocol between a chess engine and the program that runs it. in a line bestmove. Since Coherent 0.2.27 that line is preceded by a line with the number of nodes, that is, the positions the search visited. The change consists of 2 lines of code and the new version number:
output("info nodes " + std::to_string(result.nodes));
output("bestmove " +
(result.best_move ? result.best_move->uci() : std::string("0000")));
A second case reports info nodes 0: if the engine is calculating ahead on an expected reply and that reply does not come, it answers with a legal move without searching.
The line is needed by the checks on the tempo path and for playing settings. They compare the node count at the end of a search for base and candidate and require exactly this line for it. Up to epoch 13 the main line did not send it.
How the line entered the register
The line comes only after the search; it changes the engine's output, not its search. For such cases there is the correction path: it makes a fully documented build the predecessor without games. To do so, the differential gate compares predecessor and candidate on fixed test positions; only the deviations that a manifest declares in advance are allowed. Up to epoch 13 the correction path rejected an empty manifest and pointed to the edge-case path, which plays games. Epoch 14 admits a manifest without declared deviations exactly when it contains one single non-blank line: # festsetzung <sha256>. That line points with the full hash to a determination from the epoch path.
- Binding. The determination is a protected file with exactly defined fields. It is bound to the commit and source of the candidate, to the commit and binary of the predecessor and to the single admitted purpose “knoten-schlusszeile” (node final line), and it names the hash of the diff.
- Once. Each determination serves one entry; the register records its hash, and a second use halts.
- Same work. The node count of the
benchtest must equal that of the predecessor. - Own test mode. The predecessor without the line and the candidate with it search the
256test positions twice, once withgo nodes 50000and once withgo depth 6. What must be equal: the interface greeting except for the name; for each position the move, the score and everyinfoline without the time fields; andbench. In the candidate's version the first two numbers stay the same and the third rises by exactly1. - Matching final count. The new count may never be smaller than the search's last report. If that report carries a score, the count must equal it exactly; in the stage with fixed depth every search must end that way.
T-0238 passed this path on 2026-11-07, with 603 bench nodes like the predecessor. With this entry Coherent 0.2.27 is the predecessor in the register. The purpose is fixed in the measuring code; another change can use this path only after a new determination in the epoch path.
A component rule for tempo bundles
Since epoch 13 a speed-up with the same search tree can be accepted without a gain in playing strength, if it is measurably faster and passes the non-inferiority test in both stages. Epoch 14 regulates bundles: several such changes with the same search tree may enter together as one candidate, but each component must prove its share. The rule text is bound by its hash in the file of the tempo account. It applies to bundles whose first measurement comes after the anchor T-0237.
- Fixed in advance. Before the first leave-one-out run and before any other measurement of the bundle, the following are fixed: components, base, build, the builds each without one component, the number of runs, the run identifiers and the execution positions of all arms within each run, the scheme of memory arrangement, the measuring kit with its hash, the phase plan, the measuring lanes and the evaluator with its hash. Each mechanism of change is a component of its own.
- Balanced order. For each component and each lane, the bundle runs later on average than the bundle without it in exactly
4of the8runs. - Leave-one-out test. Each component is tested on the finished bundle under the conditions fixed by the rule: the bundle against the same bundle without it, both with the same search tree. A run has
12phases, each with a freshly drawn arrangement of the program in memory; both arms share the same draw for each phase and lane. Its valuecis the mean of the12phase values100 · (ln node rate of the bundle − ln node rate without the component), roughly the speed difference in percent. - Verdict. There are
8runs. They are neither extended nor stopped on interim results, and nothing is computed before the eighth. A component passes if on every lane at least7of the8valuesclie above zero and no phase value deviates by more than2.0percentage points from the median of its run and lane. - Losses. Each component declares its list of possible losses before the first measurement. An undeclared loss blocks the whole bundle.
- Consequence. Only a component without proof after
8valid runs drops out and does not return to that bundle. The smaller bundle is a new candidate with a new binding, new leave-one-out tests and its own tempo verdict. After that, all other proofs of the tempo path apply to the bundle as a whole.
The error bound is a count. Suppose that, for at least one component and one lane, the median of c in every run is at most zero, given the earlier runs and the fixed conditions. Then each run is positive with probability at most 1/2. At least 7 positive runs out of 8 then have probability at most (8 + 1)/2⁸ = 9/256, about 3.5 %. Because every component must pass on every lane, this bound holds for the bundle bound in advance as a whole; no independence between components or lanes is needed.
The rule has limits that its own text names. It promises no mean gain: a component with mean zero and rare drops can pass. It gives no additional guarantee when many bundles are newly selected and tested. If a component changes other layouts of static data than the specifically randomized ones, it is unproven on this path; stack and heap are not randomized. If a test aborts for technical reasons, that does not count as a component failing, but nothing is computed either; a new test of the same bundle needs a new determination.
Epoch 14 opens a new tempo account with the same limits as in epoch 13, bound to the anchor T-0237. To date the register holds no test on the tempo path.
A file check without access time
The tempo path reads protected files and checks that they do not change while being read. For this it compared all file attributes, including the time of last access. On the oracle's file system, reading sets that time itself when the last access lies more than 24 hours back. After the long run T-0232 the oracle therefore stopped with a false alarm on 5 November at 21:15 UTC, and a second time on 6 November at 22:22 UTC. Since epoch 14 the check compares 9 attributes without the access time: device, file number, permissions, link count, owner, group, size, time of the last content change and time of the last attribute change.
The oracle's rules in epoch 14
The pre-stages before the oracle are described on the method page. This section describes the oracle's decision rules.
How it measures
The new version plays its predecessor in pairs: 2 games with the same opening and colours swapped. A pair scores it 0, 0.5, 1, 1.5 or 2 points; the register counts how often each of these 5 classes occurred, the pentanomial Games are played in pairs with swapped colours; the five counts are the pairs scoring 0, ½, 1, 1½ and 2 points.. Dividing each pair's points by 2, μ and σ are the mean and standard deviation of these pair shares.
- Elo Strength difference to the opponent, estimated from the games, with a 95-percent half-width where the oracle reported one. Never an absolute rating.
= −400 · log10(1/μ − 1), the familiar scale. - nElo Normalised Elo: relates the mean score excess of a colour-swapped pair to the spread of the pair results.
= (μ − 0.5)/σ · 800/(√2 · ln 10). This is the effect in units of the pair spread; it determines how many games a test needs. - Short stage: time control
8+0.08, that is8seconds per game plus0.08seconds per move, opening book A. - Long stage: time control
40+0.4and a different opening book.
Each stage is a sequential test (SPRT Sequential probability ratio test. Games are played until the accumulated evidence reaches one of two bounds or the game limit fixed in advance; then the test stops.) between two hypotheses H0 and H1 in nElo. The measure is the log-likelihood ratio LLR Log-likelihood ratio, the running evidence of an SPRT. It starts at 0; a stage passes at the upper bound and fails at the lower one. in the model “normalized” of the program fastchess, which plays the games; the oracle recalculates the verdict from the pentanomial in full precision. The stage passes as soon as the LLR reaches the upper bound ln((1 − β)/α), and is rejected as soon as it falls to the lower bound ln(β/(1 − α)). With α = β = 0.05 these are ±2.944; with α = 0.05 and β = 0.25 they are +2.708 and −1.335. If a stage reaches its game cap between the bounds, it ends as interrupted, with the verdict undecided; that is not a pass. On the 4 paths with SPRT a change must pass both stages.
Which path plays which test
| Path | What the change must show | H0 against H1 | Error rates | Cap per stage | Limits on starts |
|---|---|---|---|---|---|
| Gain | more playing strength | 0 against +5 nElo | short α = β = 0.05, long α = 0.05, β = 0.25 | 96,000 and 36,000 games | none |
| Edge case | non-inferiority within the margin | −5 against 0 nElo | as gain | as gain | 4 per budget, 1 per calendar week |
| Simplification | non-inferiority within the margin | −3 against 0 nElo | both α = β = 0.05 | 144,000 games each | 4 starts, 2 successes, 1 start per month |
| Tempo | same search tree, at least 1.5 % faster, non-inferiority | −5 against 0 nElo | as gain | as gain | 2 starts, 2 successes, at least 24 hours apart |
| Playing setting | nothing changed at the default value, speed loss within the tolerance, predicted effect | no SPRT | – | – | tolerance 0.2 % per option, 0.5 % together |
The tempo account has a reserve of 3 nElo per stage; each start charges it 1.21 nElo in the short stage and 0.75 in the long one. Three kinds of entry need no games at all: identity, when a build is bit-identical to its predecessor; correction through the differential gate, as with T-0238; and the epoch change, as with T-0237.
Where a stage stops
An approximation of the LLR is enough to follow it:
LLR ≈ 2 · N · (H1 − H0) · (nElo − m) / (800/ln 10)², with N pairs and m the midpoint of the two hypotheses.
With hypotheses 5 apart this becomes N · (nElo − m)/12,071; for the simplification, 3 apart, N · (nElo − m)/20,119. The midpoint m is +2.5 on the gain path, −2.5 for edge case and tempo and −1.5 for the simplification. In this approximation the stopping boundary is an estimate bound · 12,071/N above or below the midpoint, for the simplification bound · 20,119/N. The exact LLR remains decisive.
Example on the gain path: after 10,000 pairs, that is 20,000 games, the short stage passes in this approximation from an estimate of about 2.5 + 2.944 · 12,071/10,000 ≈ +6.05 nElo and is rejected below about −1.05 nElo. Rejected means: the likelihood ratio of H0 to H1 has reached 19 to 1, in the long stage 3.8 to 1. That alone does not mean that a rejected change does harm. A test that stops at a bound can give biased estimates; an early stop tends to exaggerate the distance from the midpoint.
State of the register
The export of 2026-11-07 holds 238 entries. T-0237 records the epoch change: the same engine as T-0236, version 0.2.26, built twice and byte-identical, with 603 bench nodes. T-0238 records the passed correction to version 0.2.27. In epochs 13 and 14 there is no entry on the tempo path and none as a playing setting.
What this post does not say
It makes no statement about playing strength. That the new line changes no move is shown on the 256 test positions and for bench, not for every possible position. The component rule has not yet been applied to any bundle in the register. The bound 9/256 is a calculation under the rule's assumptions, not a measurement.
How this was checked
- Sources: measuring code of the states of both epochs and the engine commit of
T-0238; file of the tempo account and the text of the component rule with its hash; oracle register, export of 2026-11-07; record of the false alarm. - Recalculation: a script checks selected constants, register data and calculation examples. Numerical claims in context and the language versions were checked independently.
- Independent check: an agent of another model family checked text and figure against the same sources, recalculated the bounds, the approximation and all curve points of the figure, and compared the language versions.