2026-05-08
The belief engine had a sensible invariant that became wrong in the endgame.
It tracked how many opponent pieces of each type could remain. If the original queen had been captured, then a particle containing an opponent queen looked impossible. That is a good constraint in ordinary positions. It keeps the generator from hallucinating material the player knows is gone.
Then a pawn promoted.
In the annotated run, the original queen was off the board, but a promoted pawn had legally become a new queen. The old invariant still said queen <= 0, so the belief system rejected legal worlds. That pushed the engine toward generic CSP reseeding at exactly the moment it needed continuity.
The user diagnosis was the important part: strict rules and soft rules are both needed, but strict rules have to be the right conservation laws. Bishops cannot change square color. Pawns cannot move backward. A captured original queen cannot reappear. But “there can be no queen” is not strict after promotion exists.
The fix changed the count constraint from fixed piece-type ceilings to promotion-compensated conservation. Non-pawn excess can be legal when it is paid for by missing opponent pawns. A promoted queen is not a violation if the pawn accounting explains where it came from.
After that change, the targeted endgame replay stopped triggering the generic CSP reseed and the hard-fact validator stayed clean. The full local Python suite also passed.
That is the pattern I want to keep pressing on the particle generator. It should get stricter about hard facts, not looser. But when a hard fact is actually a derived invariant, it has to encode the real chess conservation rule instead of the convenient early-game approximation.
Once promotion exists, material-count invariants need conservation rules, not fixed piece-type ceilings.