v0.9.0 — theme detection round 2
Six new composition themes, and the structural change that lets two of them exist.
needs — the actual deliverable
A theme detector now receives a ThemeInput (the diagram, the sibling side-to-move plane's value, the solutions) instead of a bare Solution, and each declares needs: Position, Plane or Solutions.
mine previously enumerated a position's optimal solutions for every theme filter. Enumeration is impossible for positions whose stored solution count saturates at 255 — those were skipped and counted, so a theme query silently never saw them. mine now enumerates only when a requested theme actually needs the solutions.
So a Needs::Plane theme answers on saturated positions. Measured: --theme set-play reports 0 skipped where --theme model on the identical query skips 19.
This is a capability difference, not a speed-up, and the docs say so. An earlier draft claimed diagram-only themes would run at "scan speed" — withdrawn. Evaluating one requires materialising the position, so its floor is decode speed: 51 s → 26 s on KRvkbn --dtm 8 (31.5M candidates) once fen construction was made lazy, against >100 hours to enumerate the same candidates.
New themes
set-play, kniest, zajic, phoenix, schnoebelen, pendulum. Registry 16 → 22. helpmate themes now prints each theme's needs, as do /v1/themes and helpmate.themes().
set-play is cheap for a reason specific to this project: a cell index is independent of side to move, so the sibling plane's value is the same cell in the other plane — one extra byte from a read the scan already performs.
homebase was designed, implemented, reviewed — and cut
It shipped through nine tasks before the whole-branch review removed it. It cannot be meaningfully mined, and not merely because the canonical index confines the White king to files a–d. A tablebase cell stores an equivalence class, and homebase is not invariant under the symmetry group the index quotients by — the file mirror maps king e↔d and queen d↔e. The question is ill-posed, not just unanswerable.
All 22 remaining themes were tested for invariance across 525 transform pairs; none is affected. The spec now records the constraint: a Needs::Position theme must be invariant under the index's symmetry group.
Also
/v1/probe?themes=true and the Python bindings now disclose solution-set truncation, which previously only the CLI did — two mirror-image FENs could return different theme lists at count=255.
Verification
Catch2 3,867,093 assertions / 208 cases; ctest 270/270; lint, typecheck and format-check clean; api 85, bindings 17, web 16, repo 14, JS 38. Every worked example in the README, docs/USAGE.md and CHANGELOG.md was reproduced byte-for-byte against a real 30 GB corpus.
Upgrade note: no table format change. Existing v1/v2/v3 tables read exactly as before; no corpus reconversion is needed.
What's Changed
Full Changelog: v0.8.2...v0.9.0