Chronological record of changes, test runs, failures, and limitations.
- Initial repository skeleton with Podman-first workflow.
- Engine: original Rust UCI implementation with full movegen, negamax search, and verifier tooling.
./scripts/podman/ci: PASS (fmt, clippy, tests, verify-smoke, tournament-smoke).
- Result: FAIL
- Failures: cargo fmt --check cargo clippy
- Command:
./scripts/podman/ci
- Result: PASS
- Command:
./scripts/podman/ci
- Result: FAIL
- Failures: cargo fmt --check
- Command:
./scripts/podman/ci
- Result: PASS
- Command:
./scripts/podman/ci
- Result: PASS
- Command:
./scripts/podman/verify-deep - Perft depth 1–6 (startpos, kiwipete, all EPD fixtures)
- 200-game random fuzz (seed=42)
- Legality oracle: 26 positions
- cozy_crosscheck + shakmaty_crosscheck depths 1–4 on startpos
- Smoke: PASS —
./scripts/podman/gauntlet --smoke(8 games, 0 illegal moves) - Full: PASS —
./scripts/podman/gauntlet --games 100— 200 games aggregate (4×50), 0 illegal moves/crashes; log:docs/gauntlet/gauntlet_20260620T105634Z.log
- Docs: user_manual.md, human_play_checklist.md, play-uci.sh
- UCI:
id version 0.2.0in handshake - Automated protocol QA: PASS (uci_protocol_tester, gauntlet TC)
- Manual 10-game GUI checklist: pending operator (see human_play_checklist.md)
- Result: PASS
- Command:
./scripts/podman/release - Version: 0.2.0
- SHA256:
63b8173f183aaf0bfa1080216a8ebd0b5f68b4ed71a217e51665c50849f6167e - CHANGELOG.md, submission_package.md, panic logging to stderr
- Bridge (live): lichess-bot + host
target/release/labzero - Dev stub:
lichess_bot/bot.py,./scripts/podman/bot --dry-run - Dry-run: PASS — 20 plies, zero illegal moves
- Live 5+ games: pending — see lichess_bot_setup.md
- GHA:
.github/workflows/ci.yml— smoke on push/PR; verify-deep + gauntlet-smoke weekly - README: badges, quickstart, links to user manual + submission pack
- Submission pack: docs/submission_package.md (reviewer-ready except live Lichess URL)
- Binary:
.cargo-target/release/labzero - SHA256:
63b8173f183aaf0bfa1080216a8ebd0b5f68b4ed71a217e51665c50849f6167e - Version: 0.2.0
- Binary:
.cargo-target/release/labzero - SHA256:
63b8173f183aaf0bfa1080216a8ebd0b5f68b4ed71a217e51665c50849f6167e - Version: 0.2.0
- Result: PASS
- Command:
./scripts/podman/ci
- SF UCI Elo: 2000, 1+0, 32 games
- Score (labzero): 2–23–7 (17.2%)
- Performance Elo (approx): 1727
- Illegal / errors: 0
- Artifacts:
docs/strength/benchmark_20260620T192641Z.txt,.pgn
- Engine: qsearch, TT, null move, LMR, SEE, tapered eval
- 1320: 28–0–4 (93.8%) —
benchmark_20260620T214301Z - 1800: 14–13–5 (51.6%) —
benchmark_20260620T221648Z - 2000: 10–20–2 (34.4%) —
benchmark_20260620T230310Z - Gauntlet smoke: PASS, 0 illegal
- Result: FAIL
- Failures: cargo fmt --check cargo clippy
- Command:
./scripts/podman/ci
- Result: FAIL
- Failures: cargo clippy cargo test build engine verify smoke tournament smoke
- Command:
./scripts/podman/ci
- Result: FAIL
- Failures: cargo clippy cargo test build engine verify smoke tournament smoke
- Command:
./scripts/podman/ci
- Result: PASS
- Command:
./scripts/podman/ci
- Result: FAIL
- Failures: cargo clippy
- Command:
./scripts/podman/ci
- Result: PASS
- Command:
./scripts/podman/ci
- Result: FAIL
- Failures: cargo fmt --check cargo clippy
- Command:
./scripts/podman/ci
- Result: PASS
- Command:
./scripts/podman/ci
- Search: depth cap 64, aspiration, PV ordering, root make/unmake, check qsearch evasions; TT ordering-only under movetime (score cutoffs reverted after ladder blunders)
- Time: soft stop before new ID, panic reserve, wtime/increment allocation
- UCI:
info depth score cp nodes nps time, optionsHash,Threads,OwnBook/BookFile - Eval: pawn structure, rook files, king safety enabled
- SMP: Lazy SMP (Threads 1–8, shared thread-safe TT)
- Book: optional opening lines (
OwnBookoff by default) - CI:
./scripts/podman/ciPASS (13 unit tests) - Ladder: anchor rows recorded in
docs/strength/ladder.md(superseded by v0.5.0 re-measure)
- D1a:
verifier/positions/tactical.epd(10 positions); fixed-depth tactical tests insearch.rs - D1b: TT
completeflag; score cutoffs enabled forgo depthonly — movetime remains ordering-only (complete-guard cutoffs still regressed SF@1320 under 1s) - D1c: LMR reduction
move_idx/10(was/8); aspiration windows from depth 5 (was 4) - D2: UCI protocol matrix;
ucinewgameclears stop flag; wtime benchmark fix inhost-benchmark.sh - D3: eval weight tune — doubled pawn penalty 10→8, isolated 8→6, rook file 12→10
- CI:
./scripts/podman/ciPASS (16 unit tests); gauntlet smoke 0 illegal - Ladder (1+0 anchor): SF@1320 14–0–2 (93.8%); SF@2000 9–17–6 (37.5%, 32-game confirm, ≈1911 perf) — 0 illegal; see
docs/strength/ladder.md - Spot wtime 3+2 @ SF2000 (8 games, pre-harness-fix): 0–8–0 — superseded; see below (
benchmark_20260621T063138Z)
Post–TT-fix v0.5.0, TC_MODE=movetime TC_SEC=1 THREADS=1, 16 games each:
| SF_ELO | Score | % | Artifact |
|---|---|---|---|
| 1320 | 15–1–0 | 93.8% | benchmark_20260621T063529Z |
| 1900 | 5–6–5 | 46.9% | benchmark_20260621T064836Z |
| 2000 | 5–8–3 | 40.6% | benchmark_20260621T071050Z |
| 2100 | 3–10–3 | 28.1% | benchmark_20260621T073101Z |
Invalidated: benchmark_20260621T062854Z (1–15 @ 1320) — TT score cutoffs under movetime (pre-fix).
- Result: FAIL
- Failures: cargo fmt --check cargo clippy verify smoke
- Command:
./scripts/podman/ci
- Result: PASS
- Command:
./scripts/podman/ci
- Result: PASS
- Command:
./scripts/podman/ci
Post–TT-fix v0.5.0, TC_MODE=movetime TC_SEC=1 THREADS=1:
| Phase | SF_ELO | Score | % | Perf Elo | Artifact |
|---|---|---|---|---|---|
| Regression | 1320 | 14–0–2 | 93.8% | — | benchmark_20260621T084207Z |
| Confirm | 2000 | 9–17–6 | 37.5% | ≈ 1911 (95% CI ≈ 1790–2030) | benchmark_20260621T091006Z |
0 illegal, 0 errors on both runs.
Prior 16-game probes (same protocol): SF@1900 46.9%, SF@2100 28.1% — see docs/strength/ladder.md.
Next: SMP spot THREADS=8 @ SF@2000 — 2–9–5 (28.1%, perf ≈ 1837); no gain vs T=1 confirm (benchmark_20260621T095930Z).
TC_MODE=movetime TC_SEC=1 THREADS=8, 16 games vs SF@2000:
| Score | % | Perf Elo (approx) | vs T=1 confirm | Artifact |
|---|---|---|---|---|
| 2–9–5 | 28.1% | ≈ 1837 (CI ≈ 1660–2020) | −9.4 pp / ≈ −74 Elo | benchmark_20260621T095930Z |
0 illegal, 0 errors. CIs overlap — treat as negative spot result, not proven SMP regression.
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=1, vs SF@2000:
| Games | Score | % | Perf Elo (approx) | Artifact | Notes |
|---|---|---|---|---|---|
| 16 (probe) | 7–6–3 | 53.1% | ≈ 2022 | benchmark_20260621T132942Z |
superseded by 32-game confirm |
| 32 (confirm) | 10–11–11 | 48.4% | ≈ 1989 (95% CI ≈ 1860–2115) | benchmark_20260621T140403Z |
paper-grade blitz row |
0 illegal, 0 errors on both runs. Supersedes pre–host-benchmark.sh clock fix 0–8–0 (benchmark_20260621T063138Z). Not comparable to 1+0 anchor (37.5%, ≈1911).
Change: engine/src/tt.rs — global Mutex<Vec<_>> replaced with 64-shard table (per-shard mutex); API unchanged.
TC_MODE=wtime TC_SEC=3 TC_INC=2, 16 games vs SF@2000:
| Threads | Score | % | Perf Elo (approx) | vs 32g blitz confirm | Artifact |
|---|---|---|---|---|---|
| 1 | 5–8–3 | 40.6% | ≈ 1934 | −7.8 pp (noise) | benchmark_20260621T151817Z |
| 4 | 2–9–5 | 28.1% | ≈ 1837 | −20.3 pp | benchmark_20260621T154803Z |
0 illegal, 0 errors. T=1 in line with 48.4% confirm; T=4 still regressed (same score band as pre-shard THREADS=8 @ 1+0). Conclusion: lock contention was not the sole bottleneck.
Change: engine/src/zobrist.rs — deterministic Zobrist tables; make_unmake.rs incremental XOR on make (no full-board recompute); compute_hash() kept as oracle.
TC_MODE=wtime TC_SEC=3 TC_INC=2, 16 games vs SF@2000:
| Threads | Score | % | Perf Elo (approx) | vs post-shard T=4 | Artifact |
|---|---|---|---|---|---|
| 1 | 10–6–0 | 62.5% | ≈ 2089 | +21.9 pp vs shard T=1 | benchmark_20260621T162932Z |
| 4 | 7–7–2 | 50.0% | ≈ 2000 | +21.9 pp vs shard T=4 | benchmark_20260621T165748Z |
0 illegal, 0 errors. Decision: keep Zobrist hash; T=4 now even on 3+2 (was 28.1%). Next SMP work: helper depth offset / split diversification for further gain.
Change: search_with_info_from_depth(start_depth) in search.rs — helpers skip shallow ID plies; aspiration gated on prior completed score (fixes cold-start when helper begins at depth 5). smp.rs — helpers cycle start depths 3, 4, 5; main thread unchanged at depth 1.
TC_MODE=wtime TC_SEC=3 TC_INC=2, 16 games vs SF@2000:
| Threads | Score | % | Perf Elo (approx) | vs post-Zobrist | Artifact |
|---|---|---|---|---|---|
| 1 | 3–8–5 | 34.4% | ≈ 1888 | −28.1 pp (noise; main path unchanged) | benchmark_20260621T181146Z |
| 4 | 7–5–4 | 56.2% | ≈ 2044 | +6.2 pp vs post-Zobrist T=4 | benchmark_20260621T184359Z |
0 illegal, 0 errors. Decision: keep Lazy SMP v2 — T=4 9/16 W-equivalent (≥ keep threshold); beats post-Zobrist 7–7–2.
TC_MODE=wtime TC_SEC=3 TC_INC=2, vs SF@2000:
| Threads | Score | % | Perf Elo (approx) | Notes | Artifact |
|---|---|---|---|---|---|
| 4 | 13–12–7 | 51.6% | ≈ 2011 | paper-grade T=4 confirm; ~even vs SF@2000 | benchmark_20260622T120949Z |
| 8 | 11–15–6 | 43.8% | ≈ 1956 | diagnostic; worse than T=4 | benchmark_20260622T131945Z |
0 illegal, 0 errors. Headline: ≈2010 on this protocol (32g T=4 confirm); 16g T=4 spot ≈ 2044 was high-variance.
Change: NullUndo in board.rs — null move clears ep_square and EP hash XOR; unnull_move restores prior EP state. Fixes stale EP rights / wrong Zobrist key in null-move subtrees.
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4, 32 games vs SF@2000:
| Score | % | Perf Elo (approx) | vs SMP v2 anchor | Artifact |
|---|---|---|---|---|
| 15–9–8 | 59.4% | ≈ 2066 | +7.8 pp vs 13–12–7 | benchmark_20260622T144847Z |
0 illegal, 0 errors. Decision: keep — correctness fix; tests + smoke pass.
Change: search.rs — remove is_timed() gate around tt_cutoff; safeguards unchanged (complete, depth, mate exclusion, partial-node no-store).
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4, 32 games vs SF@2000:
| Score | % | Perf Elo (approx) | vs SMP v2 anchor (13–12–7) | Artifact |
|---|---|---|---|---|
| 18–9–5 | 64.1% | ≈ 2100 | +12.5 pp | benchmark_20260622T160120Z |
0 illegal, 0 errors. Decision: keep — 20.5/32 W-equivalent (≥ 16/32 threshold).
Protocol: TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4, vs limited Stockfish:
| SF_ELO | Games | Score | % | Perf Elo (approx) | Decision | Artifact |
|---|---|---|---|---|---|---|
| 2100 | 32 | 19–11–2 | 62.5% | ≈ 2189 | Keep headline ≈2100 (>60%) | benchmark_20260622T172332Z |
| 2200 | 16 | 4–8–4 | 37.5% | ≈ 2111 | probe (below 50% vs SF@2200) | benchmark_20260622T181751Z |
0 illegal, 0 errors on both runs.
Change: search.rs qsearch — compute in_check before stand-pat; skip stand-pat in check; search all legal evasions (not noisy-only) until QSEARCH_MAX.
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4, 32 games vs SF@2000:
| Score | % | Perf Elo (approx) | vs anchor (18–9–5) | Artifact |
|---|---|---|---|---|
| 16–7–9 | 64.1% | ≈ 2100 | 20.5/32 W-equiv (≥ 18/32) | benchmark_20260622T185217Z |
0 illegal, 0 errors. Decision: keep.
Change: engine/src/see.rs — see_capture_value returns positive for materially favorable captures and negative for losing ones (early return when no recapture; invert defender-stop path). Move-ordering callers unchanged. No qsearch pruning in this patch.
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4:
| SF_ELO | Games | Score | % | Perf Elo (approx) | vs anchor | Artifact |
|---|---|---|---|---|---|---|
| 2000 | 32 | 18–9–5 | 64.1% | ≈ 2100 | 20.5/32 W-equiv (keep) | benchmark_20260623T044106Z |
| 2200 | 16 | 5–3–8 | 56.2% | ≈ 2245 | probe (≥ 7.5/16) | benchmark_20260623T055140Z |
| 2200 | 32 | 15–14–3 | 51.6% | ≈ 2211 | ~even vs SF@2200 | benchmark_20260623T062210Z |
0 illegal, 0 errors. Decision: keep — SF@2000 gate passed; SF@2200 improved vs pre-fix probe (4–8–4). README headline stays ≈2100.
Deferred: qsearch SEE pruning — prior attempt regressed to 5–22–5 (benchmark_20260622T205652Z, rolled back) because pre-fix SEE sign was inverted.
Change (rolled back): conservative qsearch SEE prune — margin -250, skip first qsearch ply (qs_depth == 0) and all in-check evasions; promotions/EP always kept.
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4, 32 games vs SF@2000: 15–11–6 (56.2%, 18/32 W-equiv). 0 illegal, 0 errors. Rollback — below 19/32 gate (anchor 20.5/32, benchmark_20260623T044106Z). Artifact: benchmark_20260623T073759Z.
Change: search.rs — bounded history updates (HISTORY_MAX=16384, history_bonus(depth) capped at 2048, gravity formula); on quiet beta cutoffs, positive gravity on cutoff move and negative gravity on earlier quiet non-cutoffs in the same ordered list. Killers unchanged.
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4:
| SF_ELO | Games | Score | % | Perf Elo (approx) | W-equiv | Artifact |
|---|---|---|---|---|---|---|
| 2000 | 32 | 20–6–6 | 71.9% | ≈ 2163 | 23/32 (keep) | benchmark_20260623T090318Z |
| 2200 | 16 | 7–7–2 | 50.0% | ≈ 2200 | 8/16 (probe) | benchmark_20260623T100753Z |
| 2200 | 32 | 12–7–13 | 57.8% | ≈ 2257 | 18.5/32 (strong keep) | benchmark_20260623T104424Z |
0 illegal, 0 errors. Decision: keep — SF@2000 +2.5 W-equiv vs SEE-fix anchor; SF@2200 32g 18.5/32 (≥ 17/32 strong tier). Headline revised to ≈2200 (README, ladder) from SF@2200 32g perf ≈ 2257.
Change: engine/src/eval.rs — original passed-pawn bonuses by relative rank (MG/EG tables), protected-passer bonus, and pseudo-attack mobility for knights/bishops/rooks/queens; phase-tapered. Four unit tests in eval.rs.
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4:
| SF_ELO | Games | Score | % | W-equiv | Artifact |
|---|---|---|---|---|---|
| 2300 | 16 | 8–4–4 | 62.5% | 10/16 (probe) | benchmark_20260623T131324Z |
| 2200 | 16 | 12–1–3 | 84.4% | 13.5/16 (keep) | benchmark_20260623T134940Z |
| 2300 | 32 | 19–5–8 | 71.9% | 23/32 (headline) | benchmark_20260623T150655Z |
0 illegal, 0 errors. Decision: keep — SF@2200 keep gate passed (≥ 8/16); SF@2300 32g 23/32 (≥ 16/32 headline gate). Headline revised to ≈2300 (README, ladder).
Change: none (measurement-only on eval v2 baseline).
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4:
| SF_ELO | Games | Score | % | W-equiv | Artifact |
|---|---|---|---|---|---|
| 2400 | 16 | 5–4–7 | 53.1% | 8.5/16 (probe) | benchmark_20260623T163900Z |
| 2500 | 16 | 3–3–10 | 50.0% | 8/16 (probe) | benchmark_20260623T171507Z |
| 2400 | 32 | 11–9–12 | 53.1% | 17/32 (headline) | benchmark_20260623T175115Z |
0 illegal, 0 errors. Decision: SF@2400 32g ≥ 16/32 headline gate → ≈2400 (README, ladder). No SF@2500 32g (2400 32g 17/32 < 18/32 trigger).
Change: eval.rs — king-pressure ring attackers + hanging-piece threat penalties (reverted).
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4:
| SF_ELO | Games | Score | % | W-equiv | Artifact |
|---|---|---|---|---|---|
| 2300 | 16 | 5–3–8 | 56.2% | 9/16 (keep) | benchmark_20260623T191448Z |
0 illegal, 0 errors. Rollback — below 10/16 SF@2300 keep gate. Full revert on codex/eval-v3-king-pressure.
Change: none (measurement-only on eval v2 baseline).
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4:
| SF_ELO | Games | Score | % | W-equiv | Artifact |
|---|---|---|---|---|---|
| 2500 | 32 | 8–12–12 | 43.8% | 14/32 (baseline) | benchmark_20260624T035947Z |
0 illegal, 0 errors. Decision: below 16/32 headline gate — keep ≈2400; row is PVS baseline.
Change: search.rs — PVS for non-first quiet moves at depth >= 2, skip in check (reverted).
TC_MODE=wtime TC_SEC=3 TC_INC=2 THREADS=4:
| SF_ELO | Games | Score | % | W-equiv | Artifact |
|---|---|---|---|---|---|
| 2400 | 16 | 7–7–2 | 50.0% | 8/16 (keep) | benchmark_20260624T052632Z |
| 2500 | 32 | 11–14–7 | 45.3% | 14.5/32 (headline) | benchmark_20260624T055916Z |
Startpos depth-8 nodes: 198070 pre-PVS → 292922 post-PVS (+48%). 0 illegal, 0 errors. Rollback — headline gate miss (14.5/32 < 16/32) and node regression; SF@2500 vs baseline within noise only.
- Result: PASS
- Command:
./scripts/podman/ci
- Result: complete — 18-7-7 (67.2%), perf ≈ 2624
- Opponent: SF UCI_Elo=2500, TC 3+2, 32 games
- Artifact:
docs/strength/baseline_sf2500.txt
- Result: complete — 6-3-7 (59.4%), perf ≈ 2666
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2500_smoke.txt
- Result: complete — 10-12-10 (46.9%), perf ≈ 2578
- Opponent: SF UCI_Elo=2600, TC 3+2, 32 games
- Artifact:
docs/strength/confirm_sf2600_32g.txt
- Result: complete — 11-10-11 (51.6%), perf ≈ 2511
- Opponent: SF UCI_Elo=2500, TC 3+2, 32 games
- Artifact:
docs/strength/gate_sf2500_32g.txt - SPSA s2 rollback: worse than baseline_sf2500 (67.2%); do not ship tuned params in v0.6.0
- Branch:
codex/superhuman-bandmerged tomain - Keep: magic bitboards, mailbox, movegen speed, gauntlet/SPSA/NNUE tooling (NNUE off by default)
- Headline: ≈2600 —
baseline_sf250032g @ SF@2500 3+2 T=4 → 18–7–7 (67.2%, perf ≈2624) - Rollback: SPSA smoke + s2 eval params (failed 32g keep gates vs baseline)
- Next: NNUE sprint on branch or v0.7.0 bet
- Result: complete — 6-3-7 (59.4%), perf ≈ 2566
- Opponent: SF UCI_Elo=2500, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2500_v060_16g.txt
- Result: complete — 15-8-9 (60.9%), perf ≈ 2577
- Opponent: SF UCI_Elo=2500, TC 3+2, 32 games
- Artifact:
docs/strength/gate_sf2500_v060_32g.txt
Change: search.rs — last_iter_ms is now per-iteration wall time for TimeBudget::should_start_depth (was cumulative elapsed). Branch codex/id-time-depth from 731af6d.
Gate SF@2600: 16g 7–5–4 (56.2%, 9/16 W-equiv); 32g 13–9–10 (56.2%, 18/32 W-equiv — KEEP), perf ≈ 2644, 0 illegal/errors. Direct ≈2600 claim validated (gate_sf2600_idtime_32g).
- Result: complete — 7-5-4 (56.2%), perf ≈ 2644
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2600_idtime_16g.txt
- Result: complete — 13-9-10 (56.2%), perf ≈ 2644
- Opponent: SF UCI_Elo=2600, TC 3+2, 32 games
- Artifact:
docs/strength/gate_sf2600_idtime_32g.txt
- Result: complete — 2-4-10 (43.8%), perf ≈ 2656
- Opponent: SF UCI_Elo=2700, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2700_baseline_16g.txt
- Result: complete — 7-6-3 (53.1%), perf ≈ 2622
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2600_lmrhist_16g.txt
- Result: complete — 2-5-9 (40.6%), perf ≈ 2634
- Opponent: SF UCI_Elo=2700, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2700_lmrhist_16g.txt
- Result: complete — 4-6-6 (43.8%), perf ≈ 2556
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2600_cm_16g.txt
- Result: complete — 4-5-7 (46.9%), perf ≈ 2578
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2600_tt2_16g.txt
- Result: complete — 1-11-4 (18.8%), perf ≈ 2345
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2600_policy_16g.txt - Note: policy v1 with move-ordering bug (TT/killer quiets demoted into policy band); invalid for strength claims
- Result: complete — 7-3-6 (62.5%), perf ≈ 2689
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2600_policy_fix_16g.txt
- Result: complete — 2-11-3 (21.9%), perf ≈ 2479
- Opponent: SF UCI_Elo=2700, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2700_policy_fix_16g.txt
- Result: complete — 9-4-3 (65.6%), perf ≈ 2712
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2600_policy_soft_16g.txt
- Result: complete — 2-7-7 (34.4%), perf ≈ 2588
- Opponent: SF UCI_Elo=2700, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2700_policy_soft_16g.txt - Note: below 8/16 bar; policy sprint paused, keep policy off by default
- Policy ordering infrastructure kept on
codex/policy-train-v1; off by default. - Soft gates are diagnostic only (SF2600 9-4-3, SF2700 2-7-7); no further policy retrains.
data/policy/policy.lzpis experimental — not recommended for play.- Next bet: residual NNUE on
codex/residual-nnue-v1(classical + scaled correction).
- Branch
codex/residual-nnue-v1:NnueModereplace/residual viaLABZERO_NNUE_MODE, scale viaLABZERO_NNUE_SCALE(default 50). search_eval: classical-only TLS for data gen; residual blendclassical + clamp(net,±300)*scale/100.- CLI:
clasieval,nnueforward,residualdata(10k games play d4 label d8, resumable). - Scripts:
host-nnue-residual-train.py,host-sprint-residual-nnue.sh, residual parity inhost-nnue-verify.sh. - Verify: cargo test 59 pass, podman smokes pass, replace + residual parity OK.
- NPS (movetime 3s): off ~1.69M; replace ~771k; residual ~724k (~6% slower than replace; any loaded NNUE ~2× slower vs classical).
- Data gen in tmux
resnnue→data/nnue/residual.txt; train + gates pending completion.
- Result: complete — 4-8-4 (37.5%), perf ≈ 2511
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2600_resnnue_s50_16g.txt
- v0.6.2 draw fix (on
codex/v0.6.2-draw-fix): search returns draw0onis_draw()before TT cutoff innegamax/qsearch;board.repetition_count_current(); UCI clearsstopat eachgo. - Root rank helpers land in
search.rs(tested) but are not wired insearch_root— enabling them caused UCI opening blunders; follow-up branch. - Gate passed:
gate_sf2600_v062_draw_16g— 8-6-2 (56.2%, 9 W-equiv, perf ≈2644), illegal=0. - INVALID gates (do not record in superhuman-band):
gate_sf2600_rep_patch_16g— interrupted 0-11-2 @ 13/16; move-1 blunders (h3/g5); polluted by policy branch + broken rep patch.benchmark_rep_patch_16g.log— 0-15-0 (first run hadLABZERO_NNUEleak; restart also failed).benchmark_root_rank_32g.run.log/benchmark_root_rank_fix_32g— wired root rank; 0-16 then 0-3-1; reset to v0.6.2.gate_candidate_sf2500_wtime_16g— interrupted @ 1-5-3/9; real-clock miss vs ≥8/16 bar.
- Symptom: wiring
pick_root_moveintosearch_rootmade the engine play move-1 flank junk (a2a4,h2h4) and lose 0-16 vs SF2600 (benchmark_root_rank_32g.run.log, INVALID), despite all unit tests + the single-threadstartpos_depth_twelvetest passing. - Root cause: old
search_rootselected best withif score > best_score(keeps the first / best-ordered move on ties).pick_root_moveusedmax_by_key/max_by, which return the last element on ties. Aspiration narrowing makes trailing root moves fail low and return fail-soft bounds that tie the PV score, so last-on-tie handed the pick to a late, badly-ordered move. At startposroot_static≈0 < ROOT_AHEAD_THRESHOLD, so ranking is bypassed and only this tie-break mattered. - Fix:
pick_root_movenow keeps the first candidate on ties in both the raw-best and ranked paths (strict>replacement), matching the original semantics. Post-fix UCI: startpos →e2e4,e7e5reply; 60 tests pass; clippy clean. - Follow-up run INVALID:
benchmark_root_rank_fix_32g— stopped @ 0-3-1/4; openings OK but middlegame king-side collapses when ahead (g3?? hxg5). LikelyROOT_PROGRESS_BONUSwhenroot_static >= 150. Reset to v0.6.2 tag (root rank unwired); wired ranking deferred tocodex/root-rank-v2.
- Result: complete — 8-6-2 (56.2%), perf ≈ 2644
- Opponent: SF UCI_Elo=2600, TC 3+2, 16 games
- Artifact:
docs/strength/gate_sf2600_v062_draw_16g.txt - Release: tagged v0.6.2 on main after merge.
- Harness:
TC_MODE=wtimereal decreasing clocks;freshclockpreserves old synthetic protocol;DEBUG_MOVESTSV telemetry;MAX_PLIEStruncation; SIGINT →status: interruptedfooter;scripts/host-benchmark-analyze.py. - Search (v3 root rank, wired): first-on-tie
pick_root_move; immediate-draw penalty even when not ahead; repeat/progress bonuses only whenroot_static >= 150; progress = quiet passed-pawn pushes only;lichess_draw_fen_avoids_queen_shuffletest. - Gold standard: SF@2600 32g wtime real-clock (production); legacy
gate_sf2600_idtime_32grelabeled freshclock synthetic in superhuman-band. - Obsolete branch:
codex/root-rank-v2(progress bonus disabled) superseded by v3 on main. - No v0.6.2 retag: real-clock confirm gates below ≥8/16 bar; harness + root-rank v3 remain on main @
6b390cd. - v0.6.2 retag (2026-06-28): public ≈2600/≈2400 headline withdrawn; legacy gauntlet = freshclock synthetic; real-clock INVALID rows tracked in superhuman-band + ladder.
- Smoke PASS:
benchmark_20260628T080455Z— SF2400 4g → 1-0-3 (2.5/4 W-equiv); 0 illegal/errors; 0 threefold; openings OK. - Candidate INVALID:
gate_candidate_sf2500_wtime_16g— stopped @ 1-5-3/9 (3.5/9 W-equiv); cannot reach ≥8/16 bar; do not run SF2600 gold. - SF2400 16g INVALID:
gate_sf2400_wtime_16g— stopped @ 0-4-1/5 (0.5/5 W-equiv); real-clock collapse at same elo smoke was 1-0-3/4.
- Default release profile: workspace
Cargo.tomlnow uses thin LTO, one codegen unit, and panic abort. Package-local release profiles are avoided because Cargo ignores them inside this workspace. - Native opt-in:
LABZERO_NATIVE=1 ./scripts/build-host-engine.shadds-C target-cpu=nativefor local host binaries only. - NPS tool:
scripts/host-nps-bench.shruns a fixed FEN suite with NNUE/policy env cleared andLABZERO_ROOT_POLICY=raw, recording TSV artifacts underdocs/perf/. - A/B evidence: generic vs optimized release at same commit:
nps_20260628T174048Zvsnps_20260628T174058Z: Threads=1 depth=8 optimized median NPS ≈ +30%.nps_20260628T174330Zvsnps_20260628T174338Z: Threads=4 depth=9 optimized median NPS ≈ +3.4% with stable bestmoves.
- Decision: keep optimized profile as default production polish. Do not present it as a strength claim; use host benchmarks for strength and NPS probes for speed only.