Spectral lattice-fermion encoder for 2D and 4D chess (D4 / B4 symmetry, graph-Laplacian eigenbasis, 640-dim / 45 056-dim HDC)
Project description
chess_spectral (Python)
Python reference implementations of the 640-dim 2D and 45 056-dim 4D spectral chess encoders, plus the quantum-mechanical front-end (2D + 4D kinematics; 4D dynamics shipped in v1.5, 2D dynamics in v1.6.x), the v1.6 §16 search + tournament + sweep engine surface, the v5 unified wire format (three encoding modes — dense / per-channel replacement / XOR-stream — with empirical 7.23× compression on 4D fixtures vs dense gzipped), the v1.7 native bitboard fast-path
- time-budget mid-iteration honoring (cumulative ~125× speedup on
dense
legal_moves()calls vs v1.6), and the v1.8GameState4Dpush/pop + board accessors + check predicates consumer surface (chess4D-OC visualizer M11.40 unblocker).
Sibling of the C17 port in ../src/. Use the Python package for REPL /
LLM / notebook analysis, Pyodide-bridge consumers, and the §16
ship-gate matrix runner; use the C binaries for batch encoding
throughput.
The pieces ship under two top-level packages:
chess_spectral— 2D encoder + 4D encoder math + 4D phase operators + QM extension. Everything that's pure spectral / B_4 representation theory lives here.chess_spectral_4d— 4D game-state surface (move history, side-to-move, draw status, FEN4 round-trip, the Pyodidechess_spectral_4d.bridgemodule). Splits cleanly from the encoder so the 4D-rules concerns don't bleed into the spectral math.
What's new in v1.19 (May 2026)
srmech profile pattern — chess-spectral is now discoverable via
the srmech.profiles entry-point group (ADR-0001
§7 Step 1, Task #211). Two paths to the same encoder:
# Direct (unchanged; works as it always has):
from chess_spectral import encode_2d, fen_to_pos
enc = encode_2d(fen_to_pos(fen))
# Via srmech (new in 1.19.0):
import srmech
chess = srmech.profile("chess")
enc = chess.encode_2d(chess.fen_to_pos(fen))
Simple-tier profile
chess-spectral keeps its own ctypes binding to its C library internally — srmech only exposes the Python bridge surfaces. This is the canonical simple-tier pattern from ADR-0001 §5: the native binary belongs to chess-spectral, the discovery / introspection surface belongs to srmech.
Eight bridge surfaces declared
encode_2d,encode_4d— canonical 640-dim / 45 056-dim encoders.fen_to_pos— FEN parser.channel_energies— per-channel L² introspection.encode_2d_pure_phase— integer-arithmetic encoder.phase_only_pseudo_legal_moves— ALU-native move enumeration.encode_2d_bip_hybrid/decode_2d_bip_hybrid— sign × magnitude compression (~3.4× at 8-bit).
The same eight functions register as srmech.amsc.tool_schema
entries (owner=chess) for LLM-agent discovery.
New runtime dep: srmech>=0.3.1,<0.4
srmech v0.3.1 added the loader's package-only entry-point support and
[profile.tool_schema] extension loading. v0.3.0 would silently
enumerate the chess profile as invalid; v0.3.1 makes it work
end-to-end.
Workflow: TestPyPI auto-routing for rc tags
chess-spectral-publish.yml now matches the pattern srmech and
ephemerides-spectral use:
- Tag
chess-spectral-vX.Y.ZrcN→ TestPyPI (auto) - Tag
chess-spectral-vX.Y.Z(no rc) → PyPI (auto) workflow_dispatchw/targetinput remains as a manual override.
What's new in v1.18 (May 2026)
C port of encode_4d_pure_phase — the last deferred item from
the 1.14.0/1.15.0/1.17.0 amendment notes. Substantial multi-file
native shared library compiled with JPL Coding Standards (Power
of Ten) discipline throughout.
Empirical bench — C is 13-47× faster than Python
| n_pieces | Python pure-phase | C pure-phase | speedup |
|---|---|---|---|
| 4 | 1.5 ms | 118 µs | 13× |
| 24 | 2.9 ms | 162 µs | 18× |
| 64 | 5.4 ms | 175 µs | 31× |
| 128 | 10.2 ms | 215 µs | 47× |
vs the Python encode_4d float baseline at n=128 (~27 ms):
~125× faster end-to-end.
Bit-exact parity
500-position random 4D stress corpus: 0/500 mismatches between Python and C. Both sides do integer arithmetic only; tolerance is zero.
JPL discipline applied throughout
- No goto, no recursion, no setjmp/longjmp
- All loops compile-time-bounded
- No dynamic allocation (caller-provided buffers + static tables)
- Functions ≤ 60 lines (split where needed)
- ≥ 2 assertions per function
- Restricted variable scope; const where possible
- No function pointers (switch dispatch + data pointer arrays)
- Builds clean under MSVC
/W4and GCC-Wall -Wextra
API
include/cs_encoder_pure_phase_4d.h— C public APIchess_spectral._native_pure_phase_4d— Python ctypes wrapper withHAS_NATIVE_PURE_PHASEguard- Falls back gracefully to Python when shared library isn't loadable (sdist install, Pyodide WASM)
8 new C source files mirror the Python module's per-channel structure; codegen extension emits the integer tables alongside the existing float tables.
What's new in v1.17 (May 2026)
Vectorize the per-piece Python loop in the pure-phase encoders — the deferred item from 1.14.0/1.15.0 amendment notes. Result is much stronger than the original 30-50× estimate suggested for the fiber loop alone, but the integrated encoder speedup is dramatic: 2D pure-phase goes from 1.64× SLOWER on opening (1.14.0's mixed result) to 1.88× FASTER; 4D pure-phase wins 1.73-2.47× across all piece-count regimes vs the float baseline.
The 1.14.0 §20.21 framing of pure-phase as "mixed/positional, not a clean win" was an artifact of per-piece Python overhead masking the int-arithmetic architectural advantage. Vectorize lifts that mask.
2D pure-phase reversal
| Position | 1.14.0 (loop) | 1.17.0 (vectorized) |
|---|---|---|
| opening | 1.64× SLOWER | 1.88× faster |
| midgame | parity | 1.13× faster |
| endgame | 1.50× faster | 1.45× faster |
4D pure-phase across piece counts
| n_pieces | float | pure-phase | speedup |
|---|---|---|---|
| 4 | 2.8 ms | 1.6 ms | 1.73× |
| 24 | 7.1 ms | 2.9 ms | 2.47× |
| 64 | 14.4 ms | 6.0 ms | 2.40× |
| 128 | 27.4 ms | 12.1 ms | 2.25× |
Three vectorization patterns:
- Loop-swap + einsum batching (2D fiber-sym): group occupied squares by FIBER piece type (5 types: N/B/R/Q/K), batch all 3 d-channels via einsum.
- Loop-swap + broadcast (4D fiber-sym): per-piece outer + 3-d broadcast inner, eliminating the 3× redundant sparse-row gather.
- Group-by-piece-type aggregation (4D FD_DIAG): 6 piece-row buckets vs N pieces — 10× fewer 4096-vector adds.
Plus a minor STD4 axis-broadcast vectorize on the 4D side.
87 tests (immolation + stress) pass after the vectorize — bit-exact preserved on every position in the 1500-position random stress corpus.
This is a closed empirical chapter: the §20.15 5-phase BSHDC roadmap shipped 1.10-1.14, the 1.15 4D parity restoration closed the 2D/4D drift, and 1.17 surfaces the architectural win that 1.14's bench had hidden.
What's new in v1.16 (May 2026) — research tooling
Three diagnostic + analysis instruments addressing deferred items from 1.14.0's stress-test note. Not core encoder API; infrastructure for asking empirical questions and locking in answers.
- Tournament runner (
tests/run_evaluator_tournament.py) — round-robin between evaluator variants (material, spectral_float64, spectral_hybrid_8bit_lru) at configurable depth. Reports ELO + per-pair record + termination histogram as JSON. - Search-tree bench (
tests/bench_search_tree.py) — measures nodes/sec at depth, combining move-gen + eval + TT + ordering + quiescence. Complements the existing static-eval-only bench. - PGN-sourced phase classifier (
chess_spectral.phase_classifier) — k-means clustering of log-channel-energy fingerprints from real games. Replaces the hand-picked open/mid/end FEN corpus with data-driven phase labels.
33 immolation tests across the three modules; baseline JSON for
bench_search_tree.py at depth=4 captured in tests/bench_baselines/.
What's new in v1.15 (May 2026)
4D pure-phase encoder ships — completing the chess2d/chess4d parity restoration begun by 1.14.0's amendment 1. The 1.14.0 ship of B-spike-4 was 2D-only; the §20.15 4D pure-phase encoder was deferred to "1.15.0+" with the open question of how to integerize the B₄-driven 4D structure (no integer character formula analog to D₄'s ±1, ±2, 0 character table). 1.15.0 closes the gap.
-
encode_4d_pure_phase(pos4)— int32 output, integer arithmetic throughout.encode_4d_pure_phase_to_float(pos4)— same encoder with per-channel dequantization; drop-in forencode_4dcomparison. -
A_1 channel uses the scale-by-LCM integerization trick: every B_4 orbit size divides 384, so
P_A1 × 384has all-integer entries (specifically, divisors of 384). Lossless — bit-exact relative to the float baseline. -
STD4 channels (X/Y/Z/W) use scale-by-4 for the quarter-integer
coord_residtable (multiples of 0.25, range [-5.25, +5.25]). Lossless — bit-exact. -
Fiber / pawn / diag channels use the same int16-quantized approach as 2D, with per-table max-abs scale factors. Lossy at the int16 quantization level (≥ 99.999% cosine-sim).
-
Empirical speed verdict — uniformly equal or faster (the OPPOSITE of 2D's mixed result): bench at iters=100 on random positions, sparse / midgame / dense:
Position float (µs) pure_int (µs) pure/float sparse n=4 10 707 10 549 0.99× midgame n=24 21 805 21 095 0.97× dense n=128 88 996 70 283 0.79× The dense-position win comes from sparse matvec being integer-ALU friendly + STD4 elementwise being SIMD-friendly. Real chess4D-OC visualizer benefit at 28-king Oana-Chiru initial.
-
29 new tests lock the surface: 21 immolation tests (cosine-sim, bit-exactness for A_1 + STD4, channel-energy Spearman, edge cases) + 8 stress tests on 500 random 4D positions (per-position cosine ≥ 0.99, median ≥ 0.999, A_1 + STD4 bit-exact at scale, no NaN, int32 bounded, deterministic).
This closes the 2D/4D pure-phase parity gap. The remaining
encode_4d_pure_phase deferral from 1.14.0 amendment 1 is now
discharged.
What's new in v1.14 (May 2026)
The §20.15 fifth and final phase: pure-phase encoder rewrite
(B-spike-4). Integer arithmetic throughout the encoder hot path
— D₄ irrep projection is integer at the core, fiber tables are
int16-quantized at module load, dequantization happens at the
channel-output boundary. New encoder_pure_phase module.
Acceptance gate met (cosine-sim ≥ 99.998% vs float baseline; D₄
channels bit-exact). Speed result is mixed/positional, not a
clean win. All five §20.15 phases now shipped.
-
encode_2d_pure_phase(pos)— int32 output, integer arithmetic throughout.encode_2d_pure_phase_to_float(pos)— same encoder with per-channel dequantization; drop-in forencode_640comparison. -
D₄ channels (A1/A2/B1/B2/E) are bit-exact vs the float baseline — the character formula is integer at the core.
-
Fiber channels (F1/F2/F3/FA/FD) use int16-quantized tables with per-table scale factors; cosine-sim ≥ 99.998% agreement.
-
Empirical speed verdict — mixed: 1.64× SLOWER at opening (dense), parity at midgame, 1.50× FASTER at endgame (sparse). The runtime winner remains
spectral_hybrid_8bit_lru(1.13.0+) at ~50 µs across all corpora. Honest finding documented in §20.21. -
Half-integer bishop fix: VALS has
B=3.5; pure-phase scales the signal by 2 and absorbs the factor in the dequant scale. Documented as_VALS_INT_SCALE = 2. -
21 new immolation tests lock cosine-sim acceptance, D₄ bit-exactness, Spearman ρ ≥ 0.99, quantized-table contracts.
B-spike-4 in the §20.15 phasing — the fifth and final phase. 1a → 1b → 2 → 3 → 4, all shipped within ~5 days.
1.14.0 amendment (May 2026) — 4D parity restored + pedantic stress tests added.
The original 1.14.0 ship was 2D-only and 1.13.0's
spectral_hybrid evaluator family was 2D-only too — both
flagged as a parity regression. Amendment:
- 4D evaluator parity restored:
evaluate_from_hybrid_4d,channel_energies_from_hybrid_4d,evaluate_4d,make_cached_evaluator_4d— full parity with the 2D versions, using the 1.12.0SpectralBIPHybrid4Dstorage. - Pedantic stress testing: 1000 random 2D positions for the pure-phase encoder, 500 random 4D positions for the hybrid evaluator family. All 17 stress tests pass. Acceptance gates (cosine-sim ≥ 0.99 every position; D₄ bit- exactness; channel-energy Spearman ρ ≥ 0.99; no NaN; LRU semantics) hold at scale.
encode_4d_pure_phasedeferred to 1.15.0+. 2D's pure-phase encoder works because D₄ has an integer character formula; 4D's B₄ structure uses sparse-matrix arithmetic without the same convenience. The 4D hybrid encoder (1.12.0) already provides integer storage; this amendment closes the eval-side parity gap.
1.14.0 amendment 2 (May 2026) — chess4D-OC consumer wishlist surface. Late-cycle additions driven by the chess4D-OC pre-publish wishlist; all ship in 1.14.0 (no minor bump — public surface only grows):
- Tier 1: M14.4c entanglement-viz unblockers
qm_4d_bridge.get_qm_density_from_psi(psi)andqm_4d_bridge.get_probability_current_from_psi(psi)— ψ-direct variants of the existing state-driven functions, for the post-collapse render path. The current-from-psi variant returnsjflattened to(16384,)(cell-major) so consumers don't re-flatten in the worker.qm_4d_bridge.get_density_matrix_of(state, piece_id, *, neighborhood_radius=1)— partial implementation that replaces the previous unconditionalNotImplementedError. Computes a Manhattan-neighborhood channel reduced density giving per-piece purity for the M14.3 entanglement-halo viz to light up. Carries anisPartial: Trueflag; the full η-metric construction (ADR-005) ships later with the same signature.
- Tier 2: consumer ergonomics
HybridCache.clear()— drops cached entries + resets counters for the chess4D-OC reset path.qm_4d_bridge.channel_energies_2d/qm_4d_bridge.channel_energies_4d— Pyodide-friendly entry points (encode + channel-energy in one shot, JS-serializable dict). Saves consumers from importing the engine sub-package.
- 33 immolation tests lock the wishlist surface contracts; the existing 95-test bridge / hybrid-eval surface continues to pass.
What's new in v1.13 (May 2026)
The §20.15 fourth-tier ship (partial): encoder-eval speedup work.
A new spectral_hybrid evaluator computes channel energy directly
from a SpectralBIPHybrid2D (skipping the float decode step), an
LRU-cached wrapper makes that practical for the §16 search engine,
and a benchmark harness records before/after numbers for each path.
~15× speedup at the warm-LRU steady state vs spectral_float64.
-
spectral_hybridmodule —evaluate,evaluate_from_hybrid,channel_energies_from_hybrid. The mathematical identity:‖v_c‖² = Σ (sign × mag)² = Σ mag²(sign cancels in squared sum), so use uint8² sum + per-channel scale² multiply. Skips the float decode step entirely on the cache-hit path. -
spectral_hybrid_cachemodule —HybridCacheLRU plusmake_cached_evaluator(magnitude_bits=8, cache_size=10000)factory returning(evaluator_fn, cache). Drop the callable intoSearchOptions.evaluatorand inspectcache.stats()for hit/miss diagnostics. Models the §16 TT-cache-hit pattern. -
spectral_float32module — float32 downstream sibling mirroring the ephemerides two-stage architecture (their complex128 → complex64 is our float64 → float32). Shipped despite a null bench result on the standalone path; a build- block for future float32-native encoder work. -
tests/bench_spectral_eval.py— diagnostic benchmark harness with three corpora (opening / midgame / endgame). Variants registered as plug-ins; the discipline: no speedup claim ships in the CHANGELOG without measured numbers from this harness on a fixed corpus. Baselines saved attests/bench_baselines/before_1.13.0.json. -
§16.7 amendment — the Othello prior (Edax-spectral, +243 Elo at L6 / 0 Elo at L10+) is now flagged as ML-fork-contaminated; B-spike-3 is no longer gated on the depth-decay claim. The §16.5 design discipline (test multiple depths, audit training target, don't trust eval-task RMSE as Elo proxy) remains sound.
-
33 new immolation tests lock the algebraic identity (channel- energy from hybrid agrees with float64 within 5% relative on the corpus; sign agreement exact at 8-bit and 4-bit), the LRU cache semantics, and the float32 sign-agreement-within-1e-4 property.
This is B-spike-3 in the §20.15 phasing — 4 of 5 phases now shipped (1.10.0-1.13.0). B-spike-4 (pure-phase rewrite) shipped across the 1.14.0-1.18.0 sequence: 2D in 1.14.0, 4D in 1.15.0, vectorized in 1.17.0, C-ported in 1.18.0.
What's new in v1.12 (May 2026)
The §20.15 third-tier ship: encoder BIP-hybrid — sign × magnitude
factoring for the spectral encoder. Sign packs as 1 bit per dim
(algebraically exact); magnitude quantizes to 4 or 8 bits per dim
with per-channel scaling. Cosine-sim ≥ 99.99% at 8-bit on both 2D
and 4D acceptance corpora. No breaking changes vs 1.11.x; encode_640
/ encode_4d defaults unchanged.
-
Storage: 760 bytes (2D) / 50 KB (4D) at 8-bit, vs 2,560 / 180 KB float32 — about 3.4-3.6× compression with negligible cosine-sim loss. At 4-bit: 440 / 28 KB → 5.8-6.4× compression; passes acceptance for 2D, lands just under 99.5% for 4D (research finding documented in §20.18).
-
encode_2d_bip_hybrid/encode_4d_bip_hybrid— new public API. ReturnsSpectralBIPHybrid2D/SpectralBIPHybrid4Ddataclasses with three integer fields:sign_packed(bytes),magnitude_scales(per-channel float32 norms),magnitudes(uint8 — packed nibbles for 4-bit, plain bytes for 8-bit). -
decode_2d_bip_hybrid/decode_4d_bip_hybrid— reconstruct float64 vector. Lossy at the magnitude-quantization level; sign storage is exact. -
cosine_similarity_hybrid_*— pair-wise distance metric for hybrid vectors. Approximates the float32 baseline within 1% absolute deviation at 8-bit. -
Bridge surface —
chess_spectral_4d.bridge.{encode_position_2d_bip_hybrid, encode_position_4d_bip_hybrid}for chess4D-OC / Pyodide consumers. Returns plain Python int/list across the WASM boundary. -
62 immolation tests lock the §20.15 acceptance gate (8-bit on 2D + 4D), the sign-bit storage exactness, the per-channel magnitude bounds, the 4D 4-bit research finding (sim ∈ [0.99, 0.999]), the pair-wise cosine-sim approximation, and the 4-bit nibble packing round trip.
This is B-spike-2 in the §20.15 three-tier phasing. B-spike-1a (sheet-block BIP) shipped in 1.10.0; B-spike-1b (ALU-native phase engine) shipped in 1.11.0; B-spike-3 (search-engine integration) shipped in 1.13.0; B-spike-4 (pure-phase rewrite) shipped across 1.14.0-1.18.0 (2D → 4D → vectorize → C port).
What's new in v1.11 (May 2026)
The §20.15 second-tier ship: ALU-native phase-operator move
generator. The §11 phase-operator engine — already integer-
arithmetic at the core, already BIP-isomorphic at the group-
theoretic level over Z_640 — gains a public integration entry
point that doesn't require a python-chess.Board argument. Pure
ALU-native pseudo-legal move generation for Pyodide / WASM /
non-Python downstream consumers. No breaking changes vs 1.10.x.
-
phase_only_pseudo_legal_moves(pos, side_to_move_white, ep_file=...)— new integration entry point. Iterates the side-to-move's pieces, computes per-piece destination sets via Solution B's phase-arithmetic, returns a flat list of(from_sq, to_sq, promotion_char)tuples in encoder sq convention. Pseudo-legal in the python-chess sense (respects piece geometry, occupation, double-push, en passant, promotion expansion); caller filters check. -
occupation_field_from_pos_dict+ep_phase_from_ep_file— pure-phase adapters that skip python-chess entirely. Counterparts of the existingoccupation_field_from_boardandep_phase_from_board; consumers that have a position dict + side-to-move + ep_file (e.g., from a 1.10.0 BIP-encoded sheet block) can build the occupation field directly without reconstructing a Board. -
Acceptance gate: parity vs
board.pseudo_legal_moveson a representative 8-FEN corpus (opening, middlegame, endgame, EP-active, promotion-imminent). All move sets match exactly modulo castles (deferred to 1.12.0+). 26 tests, pass on first implementation. -
Documented
Z_640wire contract (notebook §20.17). The constantsMODULUS,ROW_GEN,COL_GEN,DIAG_NE_SW_GEN,DIAG_NW_SE_GEN,KNIGHT_SHIFTS,KING_SHIFTSare part of the public API and don't move without a major version bump. -
Diagnostic benchmark (
tests/bench_phase_operator_movegen.py) — ~190 µs at startpos for ALU-native vs ~73 µs for python-chess Cython (~2.5× ratio, expected). Structurally faster than Solution-B-per-piece-loop because the occupation field is built once per position instead of per-piece. Value is portability, not raw speed. -
Deferred to a 1.12.0+ follow-up: castling generation in the ALU-native path (needs attack map), check-filter refactor of
phasecast_is_check(currently takes a Board input). Consumers wanting check-filtered legal moves should pair the 1.11.0 pseudo-legal output with the existingphasecast_is_check.
This is B-spike-1b in the notebook §20.15 three-tier phasing. B-spike-1a (sheet-block BIP) shipped in 1.10.0; B-spike-2 (encoder BIP-hybrid) is the next ship and depends on the bit-packing patterns 1.10.0 established.
What's new in v1.10 (May 2026)
The §20 BSHDC spike's first ship: BIP-encoded sheet block. Integer-native form of the 1.9.0 non-Markovian aux block that packs the same content into 3 bytes (vs 88 bytes float64) with a bit-exact round trip on the legal state space. ALU-native operator fast paths for Pyodide / chess4D-OC / batch retrieval consumers. No breaking changes vs 1.9.x; both representations ride side-by-side.
-
SheetStateBIPdataclass —categorical: uint16+halfmove_clock: uint8. ~29× smaller than the 1.9.0 float64 path. Round-trip exact for all 87,264 legal sheet states (864 categorical × 101 half-move) — verified exhaustively intests/test_sheets_bip.py. The Z₁₀₁ half-move stays in its ownuint8slot per §19.4's "structural split" finding (no embedding into Z₁₂₈ that would introduce a wrap discontinuity). -
Operator fast paths — single-integer-op queries against the categorical portion:
castling_alive,kingside_castling_alive,ep_target_active,fifty_move_rule_triggered,threefold_claimable, etc. Each is a bit-mask + comparison, no FPU. -
Distance metrics —
hamming_distance_categorical(a, b)for corpus-similarity retrieval where binary state distinctions matter (sharper than float cosine-sim for the categorical portion).halfmove_distance(a, b)for the integer Z₁₀₁ slot. -
Bridge surface —
chess_spectral_4d.bridge.get_sheet_state_bip/encode_sheet_aux_bip/decode_sheet_state_from_bip. All numpy-free across the WASM boundary; integers cross the Pyodide bridge directly. -
Where BIP wins: Pyodide / WASM consumers (50-100×), batch retrieval over saved corpora (~3 orders of magnitude), Hamming-distance corpus filtering, future v5 mode-2 XOR-stream wire format compression. Where it doesn't: single-position depth-1 queries (per §19.10's bitboard floor — bit-shift + AND can't undercut python-chess's
int & maskeither). -
35 new immolation tests (
tests/test_sheets_bip.py) lock the 87,264-case exhaustive round trip, the 8-operator parity vs the 1.9.0 SheetState path, the Hamming-distance behavior (including the subtle case that rep=1 vs rep=2 differ in 2 bits, not 1, due to binary representation), the bridge round-trip, and the python-chess + GameState4D factory parities.
This is B-spike-1a in the notebook §20.15 three-tier phasing. B-spike-1b (promote §11 phase-operator engine to public API) remains independent and can ship separately. B-spike-2 (encoder BIP-hybrid) depends on the bit-packing patterns this 1.10.0 establishes.
What's new in v1.9 (May 2026)
The §19 spike's Phase-1 sheet block ships as a
representation-completeness feature alongside a new
legal-moves CLI command for both 2D and 4D. No API breaks vs.
1.8.x; every addition is opt-in surface.
-
Non-Markovian sheet aux block (
from chess_spectral import SheetState, encode_aux_block) — the 11-dim aux block carries castling rights, en-passant target, side-to-move, half-move clock, and repetition count alongside the base encoder vector. Opt in via the newsheets=kwarg onencode_640(pos, sheets=...)andencode_4d(pos4, sheets=...); output dimension grows from 640 → 651 (2D) and 45056 → 45067 (4D), with the base dims byte-identical to legacy / C encoder output. Lift state frompython-chessviaSheetState.from_chess_board(board)or from a 4DGameState4DviaSheetState.from_game_state_4d(state). Half-move clock uses aZ_101Fourier carrier preserving clock-distance fidelity; round-trip exact for every integer[0, 100]. -
Representation only — no speed claim. Notebook §19.10 documents the depth-1 bitboard floor:
python-chess'shas_castling_rightsis one int-AND, and float→int conversion from a numpy slice can't undercut it. The same logic holds forBoard4D.halfmove_clock >= 100and the hash-table threefold- repetition lookup. The sheet block's value is making encoder vectors self-sufficient for downstream consumers of saved / transmitted vectors (chess4D-OC, Pyodide pipelines, batch retrieval over saved corpora) — not raw runtime speed. -
legal-movesCLI command (2D) —chess-spectral legal-moves --fen "<fen>" [--format uci|san|json] [--with-sheets]enumerates the side-to-move's legal moves. Default UCI output, one move per line; JSON format includes per-move flags (capture / castling / en-passant / promotion) plus optional sheet block. Stdin support via--fen -. Usespython-chessfor legal-move generation. -
legal-movesCLI command (4D) —chess-spectral-4d legal-moves --fen4 "<fen4>" [--format compact|json] [--with-sheets] [--side-to-move white|black] [--halfmove-clock N] [--fullmove-number N]enumerates legal moves at a 4D-OC position. Default compact formatx,y,z,w->x,y,z,wwithDP(double push),EP(en-passant capture), and=Q(promotion) tags; JSON format structured. UsesBoard4D.legal_moves()(the native 4D move-gen via graph-Laplacian-derived primitives). -
Pyodide-bridge surface for sheets —
chess_spectral_4d.bridgegainsget_sheet_state,encode_sheet_aux, anddecode_sheet_aux_from_vector. The bridge contract holds ("plain dict, no numpy across the WASM boundary"); aux blocks cross aslist[float].chess4D-OCand any other browser / Pyodide consumer can now reason about castling rights / EP / halfmove / repetition without reconstructing apython-chess.Boardor aGameState4Dworker-side. -
encode_2dfuture-proof alias —from chess_spectral import encode_2d(1.9.0+) is the recommended name going forward, mirroring the 4D path'sencode_4d.encode_640remains as a permanent alias, but the dim count is not a stable contract — sheets already bumped 640 → 651, and future channel enrichment (per the §20 BSHDC spike's antikythera-spectral reference) or further non-Markov state extensions may move it again. QueryENCODING_DIM(or checkenc.shape) and iterate channels viaCHANNELSrather than hardcoding 640. See notebook §19.11 for the full future-work note. -
53 new immolation tests lock the sheet round-trip (every legal halfmove value, every castling combination, every EP file), the encoder integration (base preservation + aux at correct offset), the factory lifts (
from_chess_board,from_game_state_4d), the CLI smoke surface for both 2D and 4D legal-move enumeration, and the bridge round-trip (state → get → encode → decode) for both dimensions.
1.9.1 update — README polish + v5 wire format design decision.
Quick-start example switched from encode_640 to the
future-proof encode_2d alias (the 640-dim count is no longer a
stable contract — see §19.11). PyPI project links gain a
Roadmap entry pointing at
ROADMAP.md.
v5 wire format officially documented as not carrying the sheet
aux block — sheets ride alongside in-memory vectors, and on-disk
the source PGN / NDJSON / FEN sidecar already carries the
non-Markov state. See frame_v5.py
header note + notebook §19.12 for full rationale and the future-
extension path (223 reserved bytes in the v5 header give plenty
of room when a consumer eventually needs persisted sheet frames).
What's new in v1.8 (May 2026)
The chess4D-OC visualizer's M11.40 unblocker release. Tier-1
of the upstream wishlist ships in 1.8.0 — GameState4D graduates
from a position+history snapshot to a persistent mutation type,
mirroring python-chess.Board's push/pop ergonomics so the
chess4D-OC worker can drop the python-chess4d-oana-chiru
runtime dep. No API breaks vs. 1.7.x — every addition is opt-in
surface.
-
GameState4D.push(move)/GameState4D.pop()— apply / undo a ply, mutating in place.pushaccepts aMove4Dor a((from_xyzw), (to_xyzw)[, promote_to])tuple.popraisesIndexErroron an empty history (parallel tochess.Board.pop()'s contract). Returns the recorded / poppedMove4Dso callers can recover capture / promotion metadata. -
GameState4D.boardview — read-only proxy over the live position dict. Exposesoccupant(sq)andpieces_of(side)accessors plus__contains__and__len__.sqaccepts both the linearintand the(x,y,z,w)Coord4Dtuple. The view does not copy — push / pop mutations are reflected immediately. -
GameState4D.to_fen()/GameState4D.from_fen(fen4)— symmetric aliases forto_fen4/from_fen4(the 1.7.1 slash-tolerant FEN4 form is accepted on both names). -
GameState4D.iter_pieces()— yields(sq_idx, piece_value)tuples in the formatchess_spectral.encoder_4d.encode_4dconsumes directly.dict(state.iter_pieces())is a one-liner replacement for the chess4D-OC worker's previous_state_to_pos4helper. -
chess_spectral_4d.engine.search.search()acceptsGameState4D— sameSearchResultshape as before; the engine constructs a transientBoard4Dinternally. Drops theBoard4D.from_fen(state.to_fen4())hop chess4D-OC was previously paying per search call. -
GameState4D.is_check()/is_checkmate()/is_stalemate()— wrapsBoard4D.is_check()plus a short-circuit legal-moves probe for mate / stalemate.is_checkmate/is_stalematebail on the first legal move vianext(iter(...), None), so the dense-position cost isO(legal-move generation)worst case — about 2s at the dense 28-king start with the 1.7.0 native bitboard fast-path active. -
16 new immolation tests in
tests/test_gamestate4d_consumer_surface.pylock down the contract shape and at least one concrete behaviour per wishlist item. Hard gate — chess4D-OC's M11.40 PR will fail loudly if any of these regress.
1.8.1 update — canonical 4D initial position landed.
chess_spectral_4d.initial_position() returns a fresh
GameState4D at the Oana-Chiru §3.3 4D starting layout (896
pieces total: 448 white + 448 black, 28 kings per side).
STARTING_FEN4 exposes the same layout as a FEN4 v1 string for
consumers that want a literal. Slice helpers
(central_slices(), white_only_slices(), black_only_slices(),
empty_slices()) expose the §3.3 (z, w) classification with
|C| = 4, |W_only| = 24, |B_only| = 24, |E| = 12. 24 new
immolation tests including a SHA-256 hash lock on the canonical
FEN4 string.
Tier-2 (ψ-driven density / current, partial-trace density matrices) is still deferred — needs the η-metric machinery from ADR-005.
What's new in v1.7 (May 2026)
The chess4D-OC visualizer wishlist release. Headline pieces:
-
SearchOptions.time_budget_mshonored mid-iteration (chess_spectral_4d.engine.search). Previously the deadline was checked only between iterative-deepening iterations — a 5-second budget on the dense 28-king starting position could overrun by ~100× before depth-1 alone completed. v1.7 threads the deadline into the alpha-beta inner loop and returns the deepest-completed- so-far best move on deadline exit. NewSearchResult.timed_out: boolfield distinguishes deadline-exit from natural completion. -
Native bitboard fast-path (
chess_spectral.spatial_4d,cs_bitboard4dshared library). Pure-C primitives for the 4096-bitBitboard4D— popcount, bitwise AND/OR/XOR/NOT/sub, per-square set/clear/toggle/test, predicates, and the load-bearingcs_bb4_to_squaresiteration helper (per-bit LSB extraction in C plusb &= b - 1clear, all without crossing the ctypes boundary per square). Ships in the wheel underchess_spectral/_native/; loaded via ctypes at import. Pure-PythonBitboard4Dcontinues to work as fallback (sdist install, Pyodide / micropip) — verified by a dedicatedfallback-testCI job.Bitboard4D.to_squares()/.squares()route through the native helper whenchess_spectral.HAS_NATIVE_BITBOARDis True; ~16× faster iteration on dense bitboards. -
Board4D.legal_moves()algorithmic refactor. The legal-move filter at the dense 28-king start position previously called_is_attackedonce per own king (K=28 calls, each iterating all N opponent attackers from scratch). v1.7 iterates attackers once and testsking_bb.intersects(attack_set)per attacker, short- circuiting on the first hit — same per-op cost (O(1) bitboard test) but one call replaces K. ~12.7× faster on the representative non-in-check 264-piece position. -
Cumulative wishlist outcome. The chess4D-OC visualizer's reported
legal_moves()~250s pain point at the standard 28-king start is now ~2s on the same hardware (~125× faster) with no API changes. Time-budget-checked search now respects user budgets within ~0.5s grace regardless of position density. -
Downstream consumer flag.
HAS_NATIVE_BITBOARDis exposed at the top-levelchess_spectralpackage — consumers can dofrom chess_spectral import HAS_NATIVE_BITBOARDto badge "native fast-path active" or fall back cleanly when the native lib isn't present.
For the full release history see CHANGELOG.md.
What's new in v1.6 (April 2026)
The §16 ship-gate release. Headline pieces:
-
Search core, tournament harness, and sweep ship-gate runner ship as CLI commands at both 2D and 4D. Per-side symmetric agent specs let white and black be configured independently in the same single-process tournament loop:
spectral_py sweep \ --evaluators material,spectral,qm \ --depths 1,2,3,4 \ --n-games-per-pair 10 \ --time-budget-ms 5000 \ -o sweep.json
-
Three §16.1 evaluator families (
material,spectral,qm) ship at both 2D and 4D with a uniformevaluate(position, side_to_move) -> floatcontract — drop in any of them as the search heuristic. -
Three independent in-house move-rule oracles — each encodes the same legality predicate ("is move m legal in position p?") through a different mathematical lens, validated head-to-head against the
python-chess[4d]reference and against each other. Not because one is more correct — they all agree on the same legal set — but because each lens is a standalone artifact for studying how spatial motion can be encoded:- Bitboard / attack-tables (
chess_spectral.spatial_4d) — the engineering lens. Bitboard4D primitive, per-piece attack tables (knight, king, rook, bishop, queen via magic-bitboard- style ray casting), axis-typed pawn moves (Pw/Py per Oana-Chiru §3 Def 11), Board4D game state, and draw rules. Same idea as a classic chess engine, lifted to Z_8^4. - Phase-space operators (
chess_spectral.phase_operators,chess_spectral.phase_operators_4d) — the algebraic lens. Per-piece move generation as group actions on a phase-space representation; legality is "the candidate move is in the orbit of the piece operator, intersected with the occupation oracle." 2D ships under §11; 4D under §13. - Discrete-Laplacian eigenbasis oracle (2D + 4D) — the spectral lens. The lattice's discrete Laplacian (Kron-sum of P_8 path-graph Laplacians; eigenvectors form a DCT-style basis) doubles as a structural lookup table for move legality — the same eigenbasis the spectral encoder uses to embed positions also tells you which moves are reachable. Concrete demonstration that "encode the geometry" and "encode the rules" share one foundation.
- Bitboard / attack-tables (
-
v5 unified
.spectral[z]/.spectralz4wire format (chess_spectral.frame_v5) — single 256-byte header serves both 2D and 4D via explicitn_dimensionsfield. Three encoding modes selected byencoding_mode: dense (= legacy v2/v4 frame body), per-channel replacement (variable-size, ~2.84× compression on 4D stable workloads), and XOR-stream (fixed-size, 7.23× compression on 4D vs dense gzipped). Seedocs/WIRE_FORMAT.mdfor the byte-level spec covering all four shipped versions (v2/v3/v4/v5) and the reader-dispatch convention. -
CI gate: the 15-cell
verify-wheelsmatrix is now opt-in via thewheel-checkPR label (was running on every PR; saves ~150 runner-min/PR while keeping the publish-time matrix as the load-bearing wheel-correctness gate).
For the full release history see
CHANGELOG.md.
Both packages share a single dist version derived from
importlib.metadata; see Install below.
Install
From PyPI (recommended):
pip install chess-spectral
The base install pulls only numpy and scipy — sufficient for
encoding, the 4D phase operators, the kinematic QM layer, and the full
§17.1 bridge surface.
Optional extras:
# PGN ingest via chess_spectral.corpus (adds python-chess)
pip install "chess-spectral[corpus]"
# 4D phase-operator validation gates against the Oana & Chiru oracle
pip install "chess-spectral[test]" # adds python-chess4d-oana-chiru
Package page: https://pypi.org/project/chess-spectral/
From source
Editable install from a local checkout:
pip install -e docs/chess-maths/chess-spectral/python/
From a git URL (pin a commit in production):
pip install "git+https://github.com/lemonforest/mlehaptics.git@COMMIT#subdirectory=docs/chess-maths/chess-spectral/python"
After install, two console scripts are on your $PATH:
chess-spectral --help # 2D CLI
chess-spectral-4d --help # 4D CLI
Both packages also expose __version__, derived dynamically from the
installed dist:
>>> import chess_spectral, chess_spectral_4d
>>> chess_spectral.__version__ == chess_spectral_4d.__version__
True # both derive from importlib.metadata.version("chess-spectral");
# they cannot drift from each other or from the wheel.
In-place (no install)
The legacy workflow still works: every test and analysis script uses
sys.path.insert to bootstrap off the python/ directory, so
pytest docs/chess-maths/chess-spectral/python/tests/ runs without any
install.
Quick start (2D)
>>> from chess_spectral import (
... encode_2d, channel_energies, read_encodings, fen_to_pos,
... ENCODING_DIM, CHANNELS,
... )
>>> pos = fen_to_pos("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
>>> enc = encode_2d(pos)
>>> enc.shape
(640,)
>>> ENCODING_DIM # don't hardcode 640; the dim count may grow (see §19.11)
640
>>> channel_energies(enc)
{'A1': 0.0, 'A2': 19.845, 'B1': 45.2825, 'B2': 45.2825,
'E': 322.57, 'F1': 88.77, 'F2': 1851.01, 'F3': 1507.65,
'FA': 19.92, 'FD': 0.0}
# Read a whole game that was encoded by either C or Python
>>> hdr, arr = read_encodings("game.spectralz") # transparent gzip
>>> arr.shape
(161, 640)
Quick start (4D, 45 056-dim)
The 4D encoder runs on the Z_8^4 hypercubic lattice with B_4
hyperoctahedral symmetry adaptation (per Oana & Chiru, AppliedMath
6(3):48, 2026). Output is a 45 056-dim float32 vector partitioned into
11 channels of 4096 modes each: A1, STD4_X/Y/Z/W,
FIB_SYM_1/2/3, FA_PAWN_W, FA_PAWN_Y, FD_DIAG.
>>> from chess_spectral.fen_4d import parse
>>> from chess_spectral.encoder_4d import (
... encode_4d, channel_energies_4d, CHANNELS_4D,
... )
>>> pos = parse("4d-fen v1: K@4,0,0,0; k@4,7,7,7")
>>> v = encode_4d(pos)
>>> v.shape, v.dtype
((45056,), dtype('float32'))
>>> energies = channel_energies_4d(v) # per-channel L2 energies
>>> sorted(energies)
['A1', 'FA_PAWN_W', 'FA_PAWN_Y', 'FD_DIAG',
'FIB_SYM_1', 'FIB_SYM_2', 'FIB_SYM_3',
'STD4_W', 'STD4_X', 'STD4_Y', 'STD4_Z']
The 4D game-state surface (move history, draw detection, FEN4
round-trip, promotion-piece argument) lives in chess_spectral_4d:
>>> from chess_spectral_4d import GameState4D, apply_move, MoveHistory4D
>>> from chess_spectral_4d import bridge
# Load a placement from a FEN4 string (white-to-move by default)
>>> result = bridge.load_state("4d-fen v1: K@4,0,0,0; k@4,7,7,7")
>>> state = result['state']
>>> isinstance(state, GameState4D)
True
# apply_move(state, from_sq, to_sq, *, promote_to='Q') is the v1.4 API
>>> # state2 = apply_move(state, from_sq=4, to_sq=5, promote_to='Q')
# Draw status: priority threefold > 50-move > insufficient > stalemate
>>> bridge.get_draw_status(state, has_legal_moves=True)
{'ok': True, 'status': 'none'}
For raw move-rule logic (legal-move generation, check detection) on
Z_8^4, see chess_spectral.phase_operators_4d below.
Quick start (QM extension, v1.5+)
The QM extension ships in two layers, mirroring the standard physics split:
- Kinematics —
chess_spectral.qm_4d. What states and operators look like: state space, observables, measurement structure, theB_4group action. Lifts encoder output toψ ∈ ℂ^{45056}, exposes the 11-channel decomposition as a built-in projection-valued measure (PVM), builds five Hermitian piece-reach observables (rook / bishop / queen / king / knight) on the per-channelℂ^{4096}factor, and ships the 384-elementB_4unitary representation as a cached LUT. - Dynamics —
chess_spectral.qm_4d_dynamics. How states change: the 11 per-channelu_move_*builders for move-as-unitary transitions (discrete) plusevolve_under_h0for Zeno-style continuous time evolution between move boundaries.
Consumers that want a Pyodide-JSON-shaped surface use the
chess_spectral.qm_4d_bridge dispatch layer described in the next
section.
>>> from chess_spectral.fen_4d import parse
>>> from chess_spectral.qm_4d import (
... state_to_psi,
... prob_channel, measure_channel_distribution,
... channel_projector,
... H_rook_4, H_bishop_4, H_queen_4, H_king_4, H_knight_4,
... measure_observable_distribution,
... b4_unitary_rep_4096, b4_unitary_rep_full,
... expectation, is_normalized, is_hermitian, is_unitary,
... )
>>> pos = parse("4d-fen v1: K@4,0,0,0; k@4,7,7,7; R@0,0,0,0")
>>> psi = state_to_psi(pos, side_to_move=True)
>>> psi.shape, psi.dtype
((45056,), dtype('complex128'))
>>> is_normalized(psi)
True
# Born-rule channel measurement: probability mass per channel
>>> prob_channel(psi, c=0) # A1 channel
3.3e-08
>>> probs = measure_channel_distribution(psi) # all 11 channels
>>> abs(probs.sum() - 1.0) < 1e-10
True
# ⟨ψ|H_rook|ψ⟩ on the rook channel block
>>> # expectation(H_rook_4, psi[0:4096]) # H_piece_4 is sparse 4096x4096
# Born-rule eigenbasis distribution: |⟨φ_k|ψ⟩|² grouped by eigenvalue
>>> # eigvals, probs = measure_observable_distribution(H_rook_4, psi[0:4096])
# B_4 group action (384 elements). 4096-dim per-channel block, or the
# I_11 ⊗ U_4096(g) Kronecker extension to the full 45 056-dim space.
>>> # U = b4_unitary_rep_full(g) # cached; sparse 45056x45056
The Hermitian piece-reach observables H_rook_4, H_bishop_4,
H_queen_4, H_king_4, H_knight_4 are built on demand and cached.
They are real-symmetric on ℂ^{4096} with integer / near-integer
spectra (Hermiticity verified at floating residual ~5e-15; Pre-flight
2 in qm_4d.py). Pawn observables break
Hermiticity under the standard inner product (directed push) — the
pseudo-Hermitian η-metric construction is deferred to v1.8+ per
ADR-005.
b4_unitary_rep_4096(g) and b4_unitary_rep_full(g) realize the
order-384 hyperoctahedral group as sparse unitaries on ℂ^{4096} and
ℂ^{45056} respectively (the latter is I_{11} ⊗ U_{4096}(g) — same
B_4 action applied independently to each of the 11 channels). Both are
cached per group element. measure_observable_distribution(H, ψ)
diagonalizes any Hermitian observable on ℂ^{4096} and returns the
Born-rule probability distribution over distinct eigenvalues.
Move-as-unitary dynamics (Phase 4, Track B) live in
chess_spectral.qm_4d_dynamics. The module ships per-channel builders
for all 11 channels and both non-capture and capture moves:
u_move_a1— A_1 channel via projector-sandwich (B1).u_move_std4— STD4_X/Y/Z/W via similarity-transform; same-orbit is strict-unitary, cross-orbit returns a measurement-only marker (B3a, ADR-003 amendment).u_move_fa_pawn— FA_PAWN_W/Y via axis-parity-odd projector sandwich (B3b).u_move_fib_meas— FIB_SYM_1/2/3 via measurement-only re-encode (B3c, per the Phase 3.5 amendment to ADR-003 §3.3).u_move_fd_diag— FD_DIAG via rank-1 update + renormalization (B3d/e).evolve_under_h0+H_FREE_4D— Zeno-style continuous evolution between move boundaries, whereH_0 = -Δis the lattice Laplacian (B2, ADR-002).
§17.1 Pyodide bridge surface (v1.5)
chess_spectral.qm_4d_bridge is the consumer-facing bridge —
the 7 §17.1 QM-extension methods plus 6 §17.5 dev/debug methods —
designed for Pyodide consumers (e.g., the chess4D-OC visualizer)
that need Pyodide-JSON-serializable returns and Float32 ψ-amplitudes
ready for Float32Array shader uploads.
>>> from chess_spectral.qm_4d_bridge import (
... # §17.1 (QM-extension surface)
... get_qm_state, get_qm_density, apply_move_qm, apply_move_qm_full,
... measure_at, get_density_matrix_of, get_probability_current,
... get_qm_expectation,
... # §17.5 (dev / debug surface)
... get_version, get_encoder_shape, get_fen4_state, load_fen4,
... load_jsonl_fixture, has_legal_moves,
... )
# Round-trip: load a FEN4, get ψ as Float32 interleaved, apply a move,
# get the updated ψ.
>>> r = load_fen4("4d-fen v1: K@0,0,0,0; k@7,7,7,7; R@1,0,0,0")
>>> state = r['state']
>>> r = get_qm_state(state, side_to_move=True)
>>> r['basisDim'], r['psi'].dtype, r['psi'].shape
(45056, dtype('float32'), (90112,)) # 2 × 45 056 — real+imag interleaved
>>> abs(r['normSq'] - 1.0) < 1e-6
True
# Per-cell density: |ψ|² summed across the 11 channels per cell
>>> r = get_qm_density(state)
>>> r['density'].shape, abs(r['density'].sum() - 1.0) < 1e-6
((4096,), True)
# Apply a move and get the assembled ψ_post (Float32 interleaved).
# move format: (from_sq, to_sq) as ints OR ((x,y,z,w), (x,y,z,w))
>>> # r = apply_move_qm_full(state, move=(1, 2))
>>> # r['ok'], r['psi'].shape
>>> # (True, (90112,))
# §17.5 debug surface
>>> get_version()['version'] # e.g., '1.5.0'
>>> get_encoder_shape()['totalDim'] # 45056
>>> get_encoder_shape()['channels'] # [{'name': 'A1', 'offset': 0, 'dim': 4096}, ...]
Wire format (ComplexArray, Float32Array-friendly): every ψ
return is a 1-D Float32 array of length 2 * 45056 = 90112, where
psi[2k] is Re(ψ_k) and psi[2k+1] is Im(ψ_k). This matches the
§17.1 contract documented in the
research notebook §17.1.
apply_move_qm vs apply_move_qm_full. The low-level
apply_move_qm returns a per-channel dispatch dict (mixed csr_matrix
- marker dict values) for consumers that want to reason about per-
channel structure. The high-level
apply_move_qm_fulldoes the block-by-block assembly (csr_matrix→U_chan @ ψ_pre[block]; marker dict →psi_post_blocksplice) and returns the assembledψ_postas Float32 interleaved. Most consumers want the_fullvariant.
The B5 milestone (April 2026) closed the last unshipped channels, so
the bridge no longer raises for any move type — non-captures and
captures both succeed via the channels' B5 capture-path branches. See
qm_4d_bridge.py for per-method
docstrings and qm_4d_dynamics.py
for the per-channel construction details.
Deferred to v1.8+:
get_density_matrix_of(reduced density matrix; needs partial- trace machinery on channel labels).get_qm_density(piece_id=...)(per-piece marginal; same blocker).
Both raise NotImplementedError with a pointer to the v1.8+ milestone.
(v1.7.0 shipped the D1 / D2 native fast-path workstream — see the
"What's new in v1.7" section below — and rolled the partial-trace
work to a follow-up.)
CLI
The 2D CLI (chess-spectral, entry point chess_spectral.cli:main)
mirrors the C spectral CLI subcommand-for-subcommand. Output is
byte-identical to the C binary on the same input — the
spectral csv command produces the same bytes on either side.
chess-spectral csv game.spectralz -o game.csv
chess-spectral encode -i game.ndjson -o game.spectralz -z
chess-spectral encode-fen --fen "..." -o single.spectral
chess-spectral compare a.spectralz b.spectralz
chess-spectral query game.spectralz --ply 30
chess-spectral heatmap game.spectralz --ply 30 --channel A1
chess-spectral analyze game.spectralz
chess-spectral export game.spectralz -o game.json
chess-spectral version
The 4D CLI (chess-spectral-4d):
chess-spectral-4d tables-verify --phase all
chess-spectral-4d encode-fen4 --fen4 "4d-fen v1: K@0,0,0,0; ..."
chess-spectral-4d encode-moves4 --moves game.ndjson4 -o game.spectralz4 -z
chess-spectral-4d corpus-gen --games game1.ndjson4 game2.ndjson4 ...
chess-spectral-4d version
Both CLIs follow the --help discipline: every subcommand and every
argument has non-empty help text. Run <cmd> --help (or
<cmd> <subcommand> --help) before invoking; the immolation suite
gates this in CI.
Layout
chess_spectral/ # 2D + 4D encoder math + QM extension
__init__.py # __version__ via importlib.metadata
encoder.py # encode_2d(pos) → np.ndarray (encode_640 = legacy alias)
frame.py # v2 .spectral[z] binary I/O + transparent gzip
csv_export.py # dist_prev / cos_prev / energies CSV
cli.py # `chess-spectral` (2D CLI)
phase_operators/ # 2D §11 phase-space move generator (1.2.0+)
encoder_4d.py # encode_4d(pos4) → float32(45056,)
frame_4d.py # v3/v4 .spectralz4 binary I/O (legacy reader)
frame_v5.py # v5 unified wire format (2D + 4D, 3 encoding modes; default for new writes from v1.6)
tables_4d.py # B_4 group, lattice tables, eigenmodes
fen_4d.py # FEN4 v1 placement-literal parser + serialize
phase_operators_4d/ # 4D §13 phase-operator move engine (1.3.0+)
qm_4d.py # Track A kinematic QM front-end (1.5.0+)
qm_4d_dynamics.py # Track B per-channel U_move builders (1.5.0+)
qm_4d_bridge.py # §17.1 + §17.5 Pyodide bridge surface (1.5.0+)
chess_spectral_4d/ # 4D game-state surface (1.4.0+)
__init__.py # GameState4D, Move4D, MoveHistory4D, apply_move, bridge
move_history.py # ply log, side-to-move, 50-move clock, repetition hash
apply_move.py # apply_move(state, from_sq, to_sq, *, promote_to='Q')
bridge.py # load_state, get_draw_status, get_move_history,
# is_insufficient_material_2d
cli.py # `chess-spectral-4d` (4D CLI)
pyproject.toml # PEP 621 packaging metadata
tests/ # pytest suite (see test count below)
Test count (post-v1.5): 45 895 tests collected. Breakdown:
~44 876 parametric 4D phase-operator tests (the bulk), 81-test
end-to-end immolation suite (test_smoke_e2e.py, expanded from 41
for v1.5 surface coverage), 272 v1.5 QM tests across the kinematic
front-end (test_qm_4d.py, test_qm_4d_z2_grading.py), the Track B
B1..B5 dynamics gates (test_qm_4d_dynamics_b{1,2,3a,3b,3c,3d,5}.py),
and the §17.1/§17.5 bridge surface (test_qm_4d_bridge_v15.py),
plus 102 fast tests, 260 pawn-axis / phase-4d-check / phase-4d-
unobstructed tests, 92 2D phase_operators tests, and 210 v1.4
game-state tests. Run via
pytest docs/chess-maths/chess-spectral/python/tests/.
Phase operators (2D, §11)
chess_spectral.phase_operators ships a phase-space move generator
and check detector (added in 1.2.0). The primitives compute all moves
and check relationships as modular arithmetic on a single integer per
square — phi(r, c) = r·67 + c·7 mod 640 — rather than geometric
coordinates. They are a drop-in equivalent to python-chess's
pseudo_legal_moves + is_check, validated at 100% on the reference
corpus, and compose naturally with the spectral encoder's coprime
phase structure.
import chess
from chess_spectral.phase_operators import (
occupation_aware_moves_c, # pseudo-legal dests from a square
available_castles, # legal castles for side-to-move
phasecast_is_check, # is the mover's king attacked?
move_leaves_king_in_check, # would this move expose our king?
)
board = chess.Board()
dests = occupation_aware_moves_c(board, "N", 0, 1, +1)
# -> frozenset({(2, 0), (2, 2)}) (a3 and c3)
phasecast_is_check(board) # False on the starting position
Validation coverage and rationale: see
PHASE_OPERATOR_SUPPLEMENT.md.
Phase operators (4D, §13)
chess_spectral.phase_operators_4d (1.3.0+) is the 4D analogue —
mixed-radix tower with modulus 145451 and ladder coefficient 14
(vs the 2D framework's 8). Validated against
python-chess4d-oana-chiru
at 44 803 (state, origin, piece) cases for occupation-aware moves
and 232 cases for check detection.
from chess_spectral.phase_operators_4d import (
phi4,
P_rook4, P_bishop4, P_queen4, P_king4, P_knight4,
P_pawn4_white, P_pawn4_black,
occupation_aware_moves_a_4d, # phase-op candidates ∩ chess4d oracle
phasecast_is_check_4d,
move_leaves_king_in_check_4d,
)
Full design + experimental record:
PHASE_OPERATOR_SUPPLEMENT_4D.md.
When to use what
The 2D and 4D encoders are independent build targets that share table generation discipline. Pick by what you're encoding; the QM extension sits on top of the 4D encoder.
2D (chess_spectral) |
4D (chess_spectral + chess_spectral_4d) |
|
|---|---|---|
| Encoding dim | 640 | 45 056 |
| Lattice | Z_8 × Z_8 |
Z_8^4 |
| Symmetry group | D_4 (order 8) |
B_4 hyperoctahedral (order 384) |
| Game rules | python-chess (fen_to_pos) |
Oana & Chiru (python-chess4d-oana-chiru) |
| Channels | 10 (A1, A2, B1, B2, E, F1, F2, F3, FA, FD) |
11 (A1, STD4_X/Y/Z/W, FIB_SYM_1/2/3, FA_PAWN_W/Y, FD_DIAG) |
| Phase operators | phase_operators (1.2.0+) |
phase_operators_4d (1.3.0+) |
| QM extension | not yet shipped | qm_4d + qm_4d_dynamics + qm_4d_bridge (1.5.0+) |
Python vs C — same encoders on either side, byte-identical output:
C (../src/) |
Python (this package) | |
|---|---|---|
| Throughput | µs/encode | ms/encode |
| REPL / notebooks | ✗ | ✓ |
| LLM-pasteable | binary | code |
scipy.linalg exploration |
✗ | ✓ |
| Embeds in mobile / web (Pyodide) | ✓ | ✓ (Pyodide) |
| Exact numerical reference | tables baked at build | rebuilt from primitives |
Develop new channels in Python first (faster iteration, scipy.linalg
at hand, no rebuild loop). Once the math is frozen, port to C and
verify parity via the test suite — the critical test is
test_csv_matches_c_byte_for_byte (2D) /
test_e2e_spectralz4_parity.py (4D), which assert the C-produced
encoded bytes equal the Python-produced bytes.
See also
- Cross-disciplinary applications — research notebook §15
(
chess_spectral_research_notebook.md) for the framing of chess-spectral as aH(4, 8)Hamming-scheme toolkit withB_4-equivariant frozen featurizer and Born-rule loss hooks. - §17 bridge contracts — same notebook, §17.1 / §17.5 for the consumer-facing method specs that this package implements.
- 4D notebook —
chess_spectral_4d_notebook.mdfor the 4D-specific research record (encoder injectivity, B_4 spectral identity, qm_4d pre-flight findings). - Track B ADRs —
docs/adr/qm_4d/for the design record of the v1.5 QM extension:- ADR-001 phase convention for unitary moves
- ADR-002 time-evolution semantics (continuous H_0 between move
boundaries;
evolve_under_h0) - ADR-003 per-channel move transformation (+ Phase 3.5 orbit-restriction amendment for cross-orbit STD4 / FIB_SYM measurement-only re-encode)
- ADR-004 Z_2 superselection structure (side-to-move sign multiplier, resolves the 8-collision encoder hash issue)
- ADR-005 pawn pseudo-Hermitian η-metric (deferred to v1.8+)
PHASE_3_5_PROBE_RESULTS.md— empirical probe record that drove the ADR-003 amendment.
- Pawn-axis split (v1.1.1) — Oana & Chiru Definition 11; the
encoder splits the pawn antisymmetric channel into W-axis and
Y-axis sub-channels (
FA_PAWN_W,FA_PAWN_Y) and grew from 40 960-dim to 45 056-dim. Seeencoder_4d.pyheader for the rationale.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chess_spectral-1.19.0.tar.gz.
File metadata
- Download URL: chess_spectral-1.19.0.tar.gz
- Upload date:
- Size: 4.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b632093a9cd9dd4a6549c18394f211efbb68171080fe67d7bcd3742e72928bb
|
|
| MD5 |
9dff4b303a1559479e8b3ed4f821ac6b
|
|
| BLAKE2b-256 |
3fc4d11cb49e4d8c893a415c5085e0fc43b7eaf17b02f2a287d6c3ff34c2553b
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0.tar.gz:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0.tar.gz -
Subject digest:
8b632093a9cd9dd4a6549c18394f211efbb68171080fe67d7bcd3742e72928bb - Sigstore transparency entry: 1535907725
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-py3-none-any.whl.
File metadata
- Download URL: chess_spectral-1.19.0-py3-none-any.whl
- Upload date:
- Size: 2.0 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
239e7d5b1065c99660dfaaa74df93cc6705a4959a64804eb288b323911a13564
|
|
| MD5 |
b148a9c2a10bc0492a1a3b6da44d9c9e
|
|
| BLAKE2b-256 |
f1d6d7e8c0238297f1ee5010e389bae1b56803966505198e53c0e15e062dc510
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-py3-none-any.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-py3-none-any.whl -
Subject digest:
239e7d5b1065c99660dfaaa74df93cc6705a4959a64804eb288b323911a13564 - Sigstore transparency entry: 1535908871
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c309d1abc7d1f8709584e928c32769f0fc2f2aa1a88aa81ff22e9ce7e486a68
|
|
| MD5 |
17a1614235a70eb52540298ba23cfdfe
|
|
| BLAKE2b-256 |
b136654b91d5d196bdb2f5e26c9d93dcf7e1e7da3fbe1f1831d478868325d8c3
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp314-cp314-win_amd64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp314-cp314-win_amd64.whl -
Subject digest:
6c309d1abc7d1f8709584e928c32769f0fc2f2aa1a88aa81ff22e9ce7e486a68 - Sigstore transparency entry: 1535908308
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.6 MB
- Tags: CPython 3.14, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e141617f088d6a803ced1dc8e48114f2e5ab61fcab7ffb26fc9969baeef5adb
|
|
| MD5 |
953bbbad3a5ebbe4806aabc780181e9b
|
|
| BLAKE2b-256 |
2b18f59e139927fb131749f4a58d5b56a2169cd89043496846d9776e3033b4ea
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
9e141617f088d6a803ced1dc8e48114f2e5ab61fcab7ffb26fc9969baeef5adb - Sigstore transparency entry: 1535907822
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp314-cp314-macosx_11_0_arm64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp314-cp314-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.14, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
caf078705b3d8482d584e48ad8de9b86f2a280ab32ae0f151f727198fdf4e051
|
|
| MD5 |
f01a288cc91773b18a068e0c5d12f1a9
|
|
| BLAKE2b-256 |
12becdbbd3c06d2c6b5bf183d4ad7ffd8b2af9fc5eff95eb2f339d0c89ce6410
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp314-cp314-macosx_11_0_arm64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp314-cp314-macosx_11_0_arm64.whl -
Subject digest:
caf078705b3d8482d584e48ad8de9b86f2a280ab32ae0f151f727198fdf4e051 - Sigstore transparency entry: 1535908657
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f257fbfffcc6aee1a1315b5674995d54cb8442306e3b17d6cd54509bb6e0944b
|
|
| MD5 |
98c6270bd00a762dab6e89cd42403d09
|
|
| BLAKE2b-256 |
cbd65706de00f121f44c502ecae37caf8aa3f58c492954adb6072fa3c75d5536
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp313-cp313-win_amd64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp313-cp313-win_amd64.whl -
Subject digest:
f257fbfffcc6aee1a1315b5674995d54cb8442306e3b17d6cd54509bb6e0944b - Sigstore transparency entry: 1535908247
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.6 MB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cb87508e6597e2dfa937ef73b4c6760049f09d792317baceb347ff7af2959ac
|
|
| MD5 |
2916a302544532d89ae0513a67fe8b55
|
|
| BLAKE2b-256 |
89224f9676263755c6f215fe04d62010ecf77d2386e422cf23d1741fbff48f24
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
3cb87508e6597e2dfa937ef73b4c6760049f09d792317baceb347ff7af2959ac - Sigstore transparency entry: 1535907952
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af9a87e3b94775fc95e045fa0de364e68218b32354baa3e7bca152a0ff00ff69
|
|
| MD5 |
b30fc65e95c68e7739e45524b9edb88a
|
|
| BLAKE2b-256 |
9d49beea2519d97c375ebdaf076b05c74f6d1a458020ccfb8e1622be79cb20fd
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp313-cp313-macosx_11_0_arm64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp313-cp313-macosx_11_0_arm64.whl -
Subject digest:
af9a87e3b94775fc95e045fa0de364e68218b32354baa3e7bca152a0ff00ff69 - Sigstore transparency entry: 1535908171
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdc8c4c47ecfd5b045786cfe5586a38f8e9b7f444dc7800446423cacff2e3332
|
|
| MD5 |
df0211313df063e80cd871a857c47c66
|
|
| BLAKE2b-256 |
99e1ee4081dbc1a48e740f73ca2ac43e08a182e89ea0d8ddc25b27fb4db97767
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp312-cp312-win_amd64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp312-cp312-win_amd64.whl -
Subject digest:
cdc8c4c47ecfd5b045786cfe5586a38f8e9b7f444dc7800446423cacff2e3332 - Sigstore transparency entry: 1535908802
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.6 MB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
815da6b2a9cfcca9684ed356644a57744322edd233717c8b69531012d627e6bc
|
|
| MD5 |
38df9f663cf088ef6ef717549fdeb573
|
|
| BLAKE2b-256 |
87cae89adc0b2b9743a58fb244c3a18ff6f09a5636c3593da7ea841c1ad2e2b3
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
815da6b2a9cfcca9684ed356644a57744322edd233717c8b69531012d627e6bc - Sigstore transparency entry: 1535908739
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cda90138907cb509aacc86500a13131b67a83cbb1f94db3df8a74c0a59b011d
|
|
| MD5 |
f57c06f6e542c0bde604a0bb66a23e21
|
|
| BLAKE2b-256 |
b9a759070a16dd68640ea1067823adb82aadf5e5a3053d9eee98e00f994420f4
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp312-cp312-macosx_11_0_arm64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp312-cp312-macosx_11_0_arm64.whl -
Subject digest:
3cda90138907cb509aacc86500a13131b67a83cbb1f94db3df8a74c0a59b011d - Sigstore transparency entry: 1535908012
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50488a3189ae38d0f24b386bdc1d456701b15273de1aca9ab8b1bbd0f327db36
|
|
| MD5 |
ca009b21f940468a62a2a73e53bcf30e
|
|
| BLAKE2b-256 |
8cd3d50b4cf6163753d0b1301464c360e5187df3375c8679452d12d789ac6dd1
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp311-cp311-win_amd64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp311-cp311-win_amd64.whl -
Subject digest:
50488a3189ae38d0f24b386bdc1d456701b15273de1aca9ab8b1bbd0f327db36 - Sigstore transparency entry: 1535908478
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.6 MB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87b2321763f13d2ab94421ea866071442b7d6e79bc921187c4be24fe20194908
|
|
| MD5 |
a03d9f701433d3e23655af41c4d4c2c8
|
|
| BLAKE2b-256 |
79016ea0ce5d735db88c41183c7a6a4f5219d3bc113a27d87728d4faf34feb98
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
87b2321763f13d2ab94421ea866071442b7d6e79bc921187c4be24fe20194908 - Sigstore transparency entry: 1535908394
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b52cc09480ecc86473cb5435ce3bcd71096fb95208565e73d3b82456c9a7276d
|
|
| MD5 |
3ef67f8de240bf78e09bc1f8ff798a73
|
|
| BLAKE2b-256 |
1e033c733c05c104a38e042002323c3c091728fc98ed15baf1f8eff4495d3db8
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp311-cp311-macosx_11_0_arm64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp311-cp311-macosx_11_0_arm64.whl -
Subject digest:
b52cc09480ecc86473cb5435ce3bcd71096fb95208565e73d3b82456c9a7276d - Sigstore transparency entry: 1535908088
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a3a47fdb4502eeaddccc00c00bff94128ddfd72b5957723ec898a180966a992
|
|
| MD5 |
acc94f14ee6852caf2113cf76e568f8a
|
|
| BLAKE2b-256 |
f68abc63c1e8ea0f9f33ea34bb2c6a51434f00c0ba4436784dc826c6146a5255
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp310-cp310-win_amd64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp310-cp310-win_amd64.whl -
Subject digest:
1a3a47fdb4502eeaddccc00c00bff94128ddfd72b5957723ec898a180966a992 - Sigstore transparency entry: 1535908934
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.6 MB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17cb6582fe42d2797580db4c310a56c5292621c0587859854ebe463677994f2f
|
|
| MD5 |
c6c53a2edf437008cbc13d95da4aedc6
|
|
| BLAKE2b-256 |
b920d93b592740f7c6fef40e83aee2023dae4c0b6e97f11b7ee53f3112b1a1d4
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl -
Subject digest:
17cb6582fe42d2797580db4c310a56c5292621c0587859854ebe463677994f2f - Sigstore transparency entry: 1535907882
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file chess_spectral-1.19.0-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: chess_spectral-1.19.0-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8692bc66f210eca8e1c56e484ea9bf12a9427e9d270067c9838eb77a0435ab09
|
|
| MD5 |
74572f5f5896c7875e0442bdbde62db2
|
|
| BLAKE2b-256 |
8c0babbf17a56ea0542b04e5c1bc3494abb98a772abe3986c4a96b309f87d596
|
Provenance
The following attestation bundles were made for chess_spectral-1.19.0-cp310-cp310-macosx_11_0_arm64.whl:
Publisher:
chess-spectral-publish.yml on lemonforest/mlehaptics
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chess_spectral-1.19.0-cp310-cp310-macosx_11_0_arm64.whl -
Subject digest:
8692bc66f210eca8e1c56e484ea9bf12a9427e9d270067c9838eb77a0435ab09 - Sigstore transparency entry: 1535908570
- Sigstore integration time:
-
Permalink:
lemonforest/mlehaptics@0489f0fc8609bff2b367d28f42dad86f40923fca -
Branch / Tag:
refs/tags/chess-spectral-v1.19.0 - Owner: https://github.com/lemonforest
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
chess-spectral-publish.yml@0489f0fc8609bff2b367d28f42dad86f40923fca -
Trigger Event:
workflow_dispatch
-
Statement type: