Runs T-0215 to T-0223: 8 changes, none adopted

Listen to this post19 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.

The oracle register lists runs T-0215 to T-0223 under 2026-10-26 and 2026-10-27. 8 of them each tested one change to the engine's search against the same predecessor, Coherent 0.2.24. None was adopted: 6 failed in the short stage, T-0216 and T-0223 passed it and failed in the long stage. In total the oracle played 172,694 games for them; the short stages alone took 18.4 hours. T-0218 is not a candidate but the anchor of epoch 12: the same predecessor, entered again under the conditions of the new epoch, without games of its own.

This post explains point by point what each change did and why the oracle rejected it. The numbers come from the oracle register, export of 2026-10-28. Every stage was recalculated from the raw counts.

How the oracle decides

The new version plays the predecessor in pairs: 2 games with the same opening and colours reversed. A pair gives it 0, 0.5, 1, 1.5 or 2 points. The register counts how often each of these 5 classes occurred; this is 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.

Hypotheses and error rates of both stages are the same in epoch 11 and epoch 12; T-0215 to T-0217 ran in epoch 11, T-0219 to T-0223 in epoch 12.

The oracle computes the LLR exactly, following the “normalized” model of the program fastchess. An approximation is enough for understanding; computed with unrounded nElo it differs from the register by less than 0.01 for all 10 stages in this post:

LLR ≈ N · (nElo − 2.5) / 12,071, with N pairs and 12,071 ≈ (800/ln 10)² / 10.

2.5 nElo is midway between H0 and H1. It follows that the short stage rejects as soon as the estimate lies 71,086 / games below 2.5 nElo, and passes as soon as it lies the same amount above. Where a stage stops, its estimate therefore lies almost exactly on this curve.

Scatter plot with logarithmic horizontal axis from 1,500 to 100,000 games and vertical axis from −24 to +12 nElo. Two curves for the short stage approach 2.5 nElo from above and below as the number of games grows; a third, dashed curve between the lower one and 2.5 nElo is the rejection bound of the long stage. Each point is one stage of one run and lies just past a curve: T-0216 long stage: 1,908 games, −14.60 nElo; T-0222 short stage: 8,386 games, −5.99 nElo; T-0221 short stage: 9,322 games, −5.14 nElo; T-0223 short stage: 10,284 games, +9.46 nElo; T-0215 short stage: 15,198 games, −2.21 nElo; T-0220 short stage: 16,272 games, −1.91 nElo; T-0219 short stage: 22,546 games, −0.65 nElo; T-0217 short stage: 22,554 games, −0.66 nElo; T-0223 long stage: 24,286 games, +1.16 nElo; T-0216 short stage: 41,938 games, +4.21 nElo.
Where each stage stopped (from a measurement)

Rejected means: the likelihood ratio of “0 nElo” to “+5 nElo” has reached 19 to 1, in the long stage 3.8 to 1. It does not mean that the 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. The intervals below are therefore nominal.

The runs at a glance

RunWhere it actsGamesElonEloLLRHoursVerdict
T-0215pruning per move15,198−1.10 ± 2.74−2.21 ± 5.52−2.961.9rejected
T-0216root iteration, short stage41,938+2.08 ± 1.64+4.21 ± 3.33+2.965.3passed
T-0216root iteration, long stage1,908−7.10 ± 7.59−14.60 ± 15.59−1.35–rejected
T-0217ProbCut22,554−0.32 ± 2.23−0.66 ± 4.53−2.952.8rejected
T-0219pruning per move22,546−0.32 ± 2.25−0.65 ± 4.54−2.942.8rejected
T-0220pruning per move16,272−0.94 ± 2.62−1.91 ± 5.34−2.972.0rejected
T-0221null-move probe9,322−2.31 ± 3.17−5.14 ± 7.05−2.951.2rejected
T-0222move ordering8,386−2.98 ± 3.70−5.99 ± 7.44−2.951.1rejected
T-0223learning at node end, short stage10,284+4.66 ± 3.31+9.46 ± 6.71+2.961.3passed
T-0223learning at node end, long stage24,286+0.56 ± 2.10+1.16 ± 4.37−1.35–rejected

Elo and nElo with the nominal 95 % half-width, each against Coherent 0.2.24. Hours: measuring time of the short stage.

No interval lies wholly below zero; the short stages of T-0216 and T-0223 lie wholly above it No interval lies wholly below zero; the short stages of T-0216 and T-0223 lie wholly above it. Estimate with nominal 95 % half-width: T-0215 -2.21, T-0216 short 4.21, T-0216 long -14.6, T-0217 -0.66, T-0219 -0.65, T-0220 -1.91, T-0221 -5.14, T-0222 -5.99, T-0223 short 9.46, T-0223 long 1.16. -40-30-20-1001020nElo against Coherent 0.2.24Run and stageT-0215T-0216 shortT-0216 longT-0217T-0219T-0220T-0221T-0222T-0223 shortT-0223 longEstimate with nominal 95 % half-width, T-0215: -2.21 ± 5.52Estimate with nominal 95 % half-width, T-0216 short: 4.21 ± 3.33Estimate with nominal 95 % half-width, T-0216 long: -14.6 ± 15.59Estimate with nominal 95 % half-width, T-0217: -0.66 ± 4.53Estimate with nominal 95 % half-width, T-0219: -0.65 ± 4.54Estimate with nominal 95 % half-width, T-0220: -1.91 ± 5.34Estimate with nominal 95 % half-width, T-0221: -5.14 ± 7.05Estimate with nominal 95 % half-width, T-0222: -5.99 ± 7.44Estimate with nominal 95 % half-width, T-0223 short: 9.46 ± 6.71Estimate with nominal 95 % half-width, T-0223 long: 1.16 ± 4.37

No interval lies wholly below zero; the short stages of T-0216 and T-0223 lie wholly above it. Estimate with nominal 95 % half-width: T-0215 -2.21, T-0216 short 4.21, T-0216 long -14.6, T-0217 -0.66, T-0219 -0.65, T-0220 -1.91, T-0221 -5.14, T-0222 -5.99, T-0223 short 9.46, T-0223 long 1.16.

No interval lies wholly below zero; the short stages of T-0216 and T-0223 lie wholly above it (data of the chess project).

Where the changes act

Diagram of seven steps of the search from top to bottom, each with the runs whose change acts there. Root iteration: T-0216; Table lookup: ; Null-move probe: T-0221; ProbCut: T-0217; Move ordering: T-0222; Pruning per move: T-0215, T-0219, T-0220; Learning at node end: T-0223. Simplified: from the table lookup on, child nodes run through these steps again; depending on the node, steps are skipped or the search returns early. Next to each run its short-stage estimate in nElo.
Where the changes act in the search (schematic)

The search tries moves in a tree. At the root is the position on the board; in every iteration the root moves are searched in turn, first 1 ply deep, then 2, then 3, until time runs out. The picture shows the main search in simplified form: in a node, table lookup, null-move probe, ProbCut, move ordering, pruning or reducing per move and learning at the end follow one another. Depending on the node, steps are skipped or the search returns earlier; at remaining depth zero the quiescence search takes over. 3 of the 8 changes act on the pruning per move.

Point by point

T-0215: postpone decoy sacrifices instead of discarding them

What was tested. In the pruning per move the search discards moves whose static exchange balance lies below a threshold that falls with depth, separately for quiet moves and captures. The exchange balance only computes on the target square. The change looked for a motif this calculation does not see: the piece that recaptures first is the only defender of another enemy piece that one of our own pieces already attacks; after the recapture that piece stands undefended. If this motif was present and the exchange balance reached the threshold minus the value of the exposed piece, the search postponed the move instead of discarding it. This applied at nodes where a cutoff is expected, outside the exclusion search, an auxiliary search that excludes one move, and for at most 4 moves per node. King moves, promotions and en passant were excluded, as was a recapturing king or a pawn that promotes while recapturing. The postponed moves came only after all others had been delivered and none had reached beta; they did not then go through the per-move pruning again.

Why rejected. 15,198 games in 1.9 hours: −2.21 nElo, LLR −2.96. The interval runs from −7.73 to +3.32.

T-0216: sort root moves by the ordinary move ordering

What was tested. After every completed iteration the search reorders the root moves for the next depth; the best move is in front. So far the others followed in descending order of the number of nodes their search had last cost. Then the quiet moves swapped places among themselves according to a success value of their own, which the root carried forward over the iterations. The change replaced both with the move picker the search uses to order moves elsewhere, with the history values learned so far and without priority for the table move. It removed the success value and its sorting.

Why rejected. The short stage passed: +4.21 nElo after 41,938 games in 5.3 hours, LLR +2.96. Its interval from +0.88 to +7.53 lies wholly above zero. The long stage rejected after 1,908 games: −14.60 nElo, LLR −1.35, just below its bound of −1.335. Its interval runs from −30.19 to +0.99 and overlaps that of the short stage by only 0.11 nElo. These games do not say which measurement is closer to the truth. The rule decides: a run must pass both stages.

T-0217: prefer the ProbCut table move only with a matching lower bound

What was tested. ProbCut tests tactical moves with a shallow search against a threshold that lies a fixed margin above beta. If a move reaches it, the node is cut. So far the move from the table came first in this probe. The change preferred it only if the table entry, as a lower bound or exact value, reached at least the raised threshold. Otherwise it stood in its ordinary place among the tactical moves.

Why rejected. 22,554 games in 2.8 hours: −0.66 nElo, LLR −2.95. The interval runs from −5.19 to +3.88.

T-0219: quiet futility subtracts the exchange loss

What was tested. At small remaining depth the quiet futility pruning discards a quiet move without check and without threat if even an optimistic estimate does not reach above alpha:

f = static evaluation + margin + history value / divisor

So far the move passed this filter if f > α held. The change required f − V > α with V = max(0, −SEE). SEE Static exchange evaluation: an estimate of the material outcome of a capture sequence on one square, without searching. is the static exchange balance of the move: both sides recapture on the target square with the cheapest piece and may stop at any time. For a quiet move V is the loss of the moving piece if the square does not hold. The other prunings stayed unchanged and could still discard the move.

Why rejected. 22,546 games in 2.8 hours: −0.65 nElo, LLR −2.94, just past the bound of −2.944. The interval runs from −5.19 to +3.88. The numbers almost exactly match those of T-0217, although the changes differ. This follows from the stopping rule: both stages stopped after almost the same number of games at the same bound, and there the bound fixes the estimate.

T-0220: move-reply probe before the quiet futility

What was tested. Killer moves and the countermove are quiet moves the search most recently recorded as the best move in related positions, after a cutoff or already when they raised alpha; move ordering puts them early. If the quiet futility would have discarded such a move, a probe now decided, provided the depth was at least 2, the reduced remaining depth at most 1 and the history value at least −3,000, and history pruning and the exchange threshold allowed the move. The probe played the move, then the reply the countermove store held for this move, and called a quiescence search in a null window just above alpha. Only if that lay above alpha was the move searched regularly, where it had to hold against all replies; the value of the probe did not count. Without a legal stored reply the move stayed discarded.

Why rejected. 16,272 games in 2.0 hours: −1.91 nElo, LLR −2.97. The interval runs from −7.25 to +3.43.

T-0221: undamped evaluation at the gate of the null-move probe

What was tested. The static evaluation is damped with the halfmove clock, the number of plies since the last pawn move or capture, counted up to 100:

damped = value · (240 − clock) / 240

The null-move probe is only allowed if the evaluation reaches at least beta. With a clock from 8 to 99, the change also allowed the probe if only the undamped evaluation, computed with clock 0, reached beta. Conditions: the table held a legal pawn move or capture as its move, which would reset the clock; the evaluation had not been refined by a table value; at least 2 plies remained after the reduction. The strength of the reduction then also used the undamped value. The probe itself and its verification search ran with the real clock.

Why rejected. 9,322 games in 1.2 hours: −5.14 nElo, LLR −2.95. The interval runs from −12.20 to +1.91.

T-0222: put threatening moves earlier in move ordering

What was tested. Among the quiet moves a check so far received a bonus of 7,000 in its rank value if its exchange balance was not below −70 centipawns. The change gave the same bonus under the same condition also to a move that attacks a higher-valued enemy piece: a pawn a minor or major piece, a knight or bishop a rook or the queen, a rook the queen. If both apply, the bonus is given once. The search already used this threat detection before, for example to exempt threatening moves from the quiet futility. It uses the occupancy before the move and does not see lines that only the move opens.

Why rejected. The shortest run of this series: 8,386 games in 1.1 hours, −5.99 nElo, LLR −2.95. The interval runs from −13.42 to +1.45.

T-0223: delete a refuted countermove

What was tested. The countermove store holds, for every enemy move by piece and target square, the reply most recently recorded there as a quiet best move, after a cutoff or already when it raised alpha. Move ordering puts this reply early, and late move reductions reduce it less if its history value is high enough. The change deleted the entry when it failed in the current node: the reply was quiet and legal here, was searched at least as deep as intended, stayed at most at alpha without a mate value, and afterwards a tactical move reached beta. This applied outside the principal variation, without check and exclusion search, in a window without mate values and only as long as no search below had rewritten the entry in the meantime.

Why rejected. The short stage passed early: +9.46 nElo after 10,284 games in 1.3 hours, LLR +2.96. Its interval from +2.74 to +16.17 lies wholly above zero. The long stage played 24,286 games, more than twice as many, and rejected at +1.16 nElo, LLR −1.35; its interval runs from −3.21 to +5.53. The two intervals overlap by 2.79 nElo. An early stop at the upper bound can bias the estimate upwards; whether and by how much that happened here cannot be determined from these final counts. The long stage has a nominal type II error of β = 0.25: by design it rejects a change with a true +5 nElo in about a quarter of cases. These games do not say whether the change brings a small gain.

The balance

A rejection does not prove that an idea is worthless. It says that this implementation did not show a gain of +5 nElo against this predecessor. None of these changes went into the engine.

How this was checked