Skip to content

Phase 14: Eval Optimization#184

Merged
coeusyk merged 15 commits into
developfrom
phase/14-eval-optimization
Jul 7, 2026
Merged

Phase 14: Eval Optimization#184
coeusyk merged 15 commits into
developfrom
phase/14-eval-optimization

Conversation

@coeusyk

@coeusyk coeusyk commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Merges phase/14-eval-optimization into develop per Issue #175 pre-merge checklist (all SPRT verdicts recorded, quality gates green, NPS baseline re-established on native Windows, DEV_ENTRIES.md + CHANGELOG.md complete).

Closes #175 (pending release.yml run).

coeusyk and others added 15 commits April 30, 2026 14:50
…ase/14-eval-optimization

Why: The eval-asymmetry fix (#183) landed on develop (040239a) on top of this
     branch's HEAD (4c0d25c). Phase B tuning must run on the corrected eval
     perspective so tuning results are not contaminated by the asymmetry bug.
What: Merges 44aea1a, 261e201, 040239a (eval-asymmetry correctness patch) from
      develop into phase/14-eval-optimization ahead of B-1/B-2/B-3 tuning runs.
Left out: No new eval/search changes. Merge-only commit.
Phase: 14 — Eval Optimization
engine-uci shade plugin uses shadedArtifactAttached=false (default),
so the fat JAR is named engine-uci-0.5.7-SNAPSHOT.jar (no -shaded suffix).

Phase: 14 — Eval Optimization
WSL2 has measured single-threaded CPU overhead vs. native Windows on the
same hardware, so bench NPS numbers gathered in WSL sessions shouldn't be
treated as a regression signal.
…red)

Why: No GitHub MCP server exists in this environment; needed a documented,
repeatable way to fetch issue content for acceptance-criteria verification.
What: Added the gh CLI command to CLAUDE.md's Issue Workflow section.
Left out: Did not attempt to configure an actual GitHub MCP server.
Phase: 14 — eval-optimization
…ing-safety tuning

Why: phase-14.md's King Safety Retune Postmortem found the 18-entry
SAFETY_TABLE saturates at attacker weight >=17, giving zero Texel-tuning
gradient above that point — a documented mandatory prerequisite before any
further king-safety ATK-weight tuning (Issue #170, A-1).
What: Extended SAFETY_TABLE to 32 entries in KingSafety.java (engine-core),
TunerEvaluator.java and PositionFeatures.java (engine-tuner). Indices 0-17
are byte-for-byte unchanged (no behavior change at existing attacker-weight
levels); indices 18-31 continue the table's existing diff-growth pattern
(cap raised 50cp -> 160cp). Added KingSafetyTest.java asserting non-saturation
at w=17..31 and correct clamping beyond the table. Documented as a dated
entry in dev-entries/phase-14.md.
Left out: Did not touch ATK_WEIGHT_* defaults or run any tuning — this is
purely the architectural prerequisite fix. Also discarded (git checkout, not
committed) an unrelated abandoned uncommitted prior tuning attempt found in
the working tree (tuned_params.txt + EvalParams.java x2, ATK_WEIGHT_KNIGHT=29
vs committed baseline 6) before starting this fix.
Phase: 14 — eval-optimization
…ase 15

Why: 4th attempt at king-safety ATK-weight tuning (post-SAFETY_TABLE fix)
still produced worse val MSE than baseline (0.0620->0.0657), with
ATK_BISHOP/ATK_QUEEN gradient-dead for all 22 iterations before early-stop.
What: Documented all 4 attempts (3 prior H0 SPRTs + this run) under A-1.
Root cause is corpus coverage gap for bishop/queen king-zone attack
positions in tools/quiet-labeled.epd, not an optimizer or SAFETY_TABLE
issue (ATK_KNIGHT/ATK_ROOK did move, confirming the table fix works).
Reverted all uncommitted tuning artifacts (tuned_params.txt, both
EvalParams.java) via git checkout; no king-safety values changed on this
branch. SAFETY_TABLE extension (063bb1a) retained as a standalone fix.
Left out: No SPRT was run — the tuning result didn't clear the bar to
justify a Windows-PC SPRT run. King-safety ATK tuning deferred to Phase 15
pending corpus seed augmentation.
Phase: 14 — eval-optimization
…sis falsified

Why: Adam 300-iter run on mobility group (highest Fisher diagonal, no
coverage issues) still produced worse val MSE than baseline (0.0620->0.0642),
mirroring A-1's pattern despite mobility having no gradient-dead params.
What: Tested whether Adam's fixed LR=1.0 (shared, unscaled, between full and
group-restricted runs) causes early-iteration overshoot for small groups by
re-running at LR=0.25. Final val MSE was virtually identical (0.064203 vs
0.064203) and the "spike" was only delayed by integer-rounding lag, not
eliminated -- hypothesis falsified. Documented both attempts in
dev-entries/phase-14.md.
Left out: No SPRT was run; no mobility params applied to EvalParams.java.
Reverted the LR=0.25 experiment (git checkout) -- GradientDescent.java LR
remains at its default 1.0, no tuner hyperparameter changes committed.
Phase: 14 — eval-optimization
…deferred indefinitely

Why: A-3 coverage audit confirmed CONNECTED_PAWN/BACKWARD_PAWN scalars are
not STARVED, ruling out corpus-coverage-gap as the explanation; single Adam
pass still regressed val MSE +4.29% vs baseline, matching A-1/A-2. Task 14.7
(WDL self-play pilot) was proposed to test the distribution-mismatch
hypothesis directly, but investigation found this project already has two
documented self-play-WDL failure precedents (Phase 12/13): a -465 Elo
material-collapse regression and a silently-broken WDL loader that produced
a fake "tuned" result now sitting in tools/wdl_tuned_params.txt.

What: Ran fresh --coverage-audit + single 200-iter Adam pass (K frozen at
2.773456) on pawn-structure group; documented val MSE regression and
deferred per Issue #172's own acceptance-criteria escape hatch. Reverted
generated artifacts (coverage-audit-report.csv, tuned_params.txt,
validator-report.txt) per the established A-1 pattern for deferred runs.
Investigated data/wdl-selfplay.epd (100k positions, unused since Phase 13)
as a free pilot corpus for Task 14.7, confirmed it loads cleanly today, but
did not use it: it predates the Phase 14 eval-asymmetry fix and SAFETY_TABLE
extension, so its labels are stale relative to current eval.

Left out: No self-play games generated, no Windows-PC time spent. No
parameter changes applied to EvalParams.java for A-3. Task 14.7 closed
without running any tuning pass against real data.

Closes #172 Phase: 14 — eval-optimization
…ed baseline

Why: WSL2 --bench run this session produced 77,265,370 nodes over the
31-position/depth-13 suite, vs the documented deterministic baseline of
101,771,086 nodes (bit-for-bit identical across 5 runs when it was
established 2026-04-29). Search node counts are deterministic for a fixed
eval+search config, so this delta means the search tree shape has changed,
not that the measurement is noisy.

What: Root-caused to accumulated eval changes since the baseline was set
(SAFETY_TABLE 18->32, eval-asymmetry fix, PIECE_ATTACKED_BY_PAWN_MG becoming
colour-relative) — all legitimately shift move ordering/pruning. Marked the
301,116/228,490 NPS gate floors suspended until a fresh native-Windows
5-run baseline exists against current HEAD. Updated #175's pre-merge
checklist to reflect verified test suite results (engine-core 177/0/2,
engine-tuner 131/0/1) and the still-open A-5/#174 blocker.

Left out: No WSL2 re-baseline performed (per explicit instruction — WSL2
NPS is never a valid gate input). No native-Windows bench run — deferred to
the same session as the #174 isolated SPRT.

Phase: 14 — eval-optimization
… by #140)

Why: Phase 12.2 (#130) self-play PGN->SF corpus generator. Phase 13 (#140)
removed the self-play PGN extraction pipeline entirely; the current
generate_texel_corpus.ps1 samples from quiet-labeled.epd instead. The debug
fork (29KB) has no runtime/CI reference — only a historical dev-entry mention.

Left out: everything else. Repo is disciplined; see audit report for the
few remaining candidates, none safe to apply without SPRT or user sign-off.
Why: Isolated phase14-a5-contempt SPRT (871 games, TC 60+0.6, native
Windows) showed contempt=50 loses -16.8 +/- 16.8 Elo vs contempt=0
(LOS 2.5%, LLR -2.97 crossed lbound -2.94) -- a clean H0, not the earlier
inconclusive bundled eval-features run. Asymmetric contempt measurably
hurts play at this TC.

What: Reverted UciApplication.contempt default and the advertised UCI
option default from 50 to 0, matching the A-1/A-2/A-3 pattern (revert
value, keep infrastructure). setoption Contempt <cp> still works for
opponent-specific tuning. EvalParams.CONTEMPT_THRESHOLD/CONTEMPT_VALUE
scalars unchanged. SearchRegressionTest's contempt regression test calls
setContempt() explicitly and is unaffected; re-verified passing.

Left out: No change to EvalParams scalars or the asymmetric contemptScore()
logic itself -- both stay available for future CLOP/opponent-specific
tuning, just not enabled by default.

Closes #174 Phase: 14 — eval-optimization
…nd gate

Why: 2026-04-29 baseline (316,964 NPS / 101,771,086 nodes) was suspended
2026-07-01 after a WSL2 run showed a 24% node-count drop. Native-Windows
re-run (same session as the #174 SPRT, current HEAD) confirms the drop is
real -- node count matches the WSL2 run exactly (77,265,370, deterministic
across all 5 runs) -- not WSL2 measurement noise.

What: 5-run middle-3 protocol: mean 328,623 NPS +/-6,286 (CV 1.91%, tighter
than the original 3.97%), new gate floor 312,192 NPS. This baseline
supersedes 2026-04-29 for all future Phase 14/15 regression checks. Updated
#175's pre-merge checklist: all A-1..A-5 verdicts recorded, both test
suites verified, NPS gate satisfied by construction (this run is the new
baseline). Remaining before merge: CHANGELOG.md Phase 14 entry.

Left out: No merge to develop, no release.yml trigger, no pom.xml edit --
all pending explicit confirmation per CLAUDE.md and prior agreement.

Phase: 14 — eval-optimization
Why: Last unchecked item on Issue #175's pre-merge checklist. Summarizes
the phase's outcomes for the release notes: A-4 aspiration +156 Elo (only
confirmed gain), A-5 contempt H0 with default reverted, six correctness
fixes shipped independent of Elo (eval-asymmetry, backwardPawnCount,
SAFETY_TABLE extension, KING_SAFETY_SCALE gradient wiring, opposite-flank
shield scale, passed-pawn wiring), three deferred Texel tuning attempts
(A-1/A-2/A-3, all val-MSE regressions), Task 14.7 deferred to NNUE, and the
NPS baseline re-establishment.

What: Inserted [0.5.7] entry above the existing [0.5.6] Phase 13 entry in
CHANGELOG.md, matching its section structure (Search gains/no-change,
Evaluation fixes/tuning, Tuner infra). Marked #175's dev-entries + CHANGELOG
checklist item complete.

Left out: No merge to develop, no release.yml trigger -- every item on
#175's checklist is now satisfied, but the merge itself still needs
explicit confirmation per our agreement.

Phase: 14 — eval-optimization
@coeusyk coeusyk merged commit 30f8a78 into develop Jul 7, 2026
1 check passed
@coeusyk coeusyk self-assigned this Jul 7, 2026
@coeusyk coeusyk deleted the phase/14-eval-optimization branch July 8, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant