Better understanding of stuff like KRKRB == drawish, Q's come off = !drawish Pawnhash size tunable from cmdline again Think about when to avoid nullmove pruning based on checks in the line r2r4/p4pk1/2p3p1/1p1nPR2/5p1Q/2N5/PPPq4/1K4R1 w - - 0 0 -- check extension crazy 2026-09-18: sharded ASSERT-fuzzing harness -- the technique that found the CommonSearchInit PV-staleness bug (DEBUG binary + gdb, batch mode, `script .ep_` at a shallow sd, let it run until either an ASSERT/SIGSEGV or clean exit) generalizes well and should be run routinely, not just once ad hoc. Shard tests/cross_sectional_200k.ep_ (or any large stratified pool) into N pieces and run N concurrent DEBUG-build _typhoon processes under gdb, one per shard, each logging to its own file; investigate any hit (assert message + gdb backtrace) the same way this session did. Needs a full core budget (N cores) so it collides with self-play match runs -- schedule it for whenever the box isn't already saturated by match_play.py workers, not concurrently with them. 2026-09-18: blunders.pgn review (typhoon vs Crafty losses). 2026-09-18: consider adding cLikelyUnstoppablePasser to the POSITION structure and using it to extend searches. Just like we already do with cTrapped and cEnprise -- signals from eval.c to affect search. 2026-10-01: It seems like a Q vs RR in a pawnful endgame... Q dominates. In general, we should work on encouraging the engine to maintain a good pawn structure -- read more of that pawn power in chess book. Work on the pawn eval specifically. Maybe do eval learning on only the pawn hashed eval terms. 2026-10-04: We need to go faster. - Can we get rid of rgSquares[] completely and use bitboards everywhere? - Eliminate SEE calls? - profile a super-lazy-always (material-only Eval() exit, forced unconditionally, throwaway diagnostic build a la the zero- selection-budget move-ordering trick -- never commit it) binary against Crafty at matched depth/positions to find out where our nps actually goes once eval is ~free. Scott's educated guess is SEE and the is-this-move-a-check / legal-reply-to-check generators dominate once eval is out of the way, not eval itself -- also suspect given the earlier `<=`-to-`<` SEE-skip experiment on line ~4178 (skip SEE on same-piece- for-same-piece captures) barely changed speed but made trees fatter (more nodes needed), i.e. that SEE call was doing real pruning work, not just costing time. Before assuming check-detection costs are irreducible, confirm "is this move a check" is answered via O(1) bitboard AND against the enemy king square from the post-move attack bitboard, not via a generate-and-filter pass -- Scott believes he already does this "cheaply" but isn't sure it's the fastest available method. Single-legal-reply-to- check detection is likely the genuinely unavoidable cost of the three (needs a real legal-move count in the child position) -- worth checking whether it early-exits as soon as a 2nd legal move is found rather than generating the full list. 2026-10-04: Modify self-play harness to record eval score / PVs per move in the PGN output. Make self-play harness able to play crafty and then test the HEAD/candidate against crafty. Eval term for connected passers vs. rooks. Or 2+ passers vs. rooks. Poor king play -- tell it to support own passers or blockade enemy passers once king activity phase starts. Self-play lite and heavy. Valgrind in debug_smoke_test.sh. Remove all line-ending whitespace in one commit. Fix the input queue --batch mode one thing after the script; like this breaks it. Add nullmoves skipped to the output. Redo the output in general. Remove "pure Newton's square root method" stuff and get math.h loaded.