Skip to content

RDC - Give chess voters chess.js facts and label every vote with them - #58

Merged
rchasman merged 5 commits into
masterfrom
feat/chess-voter-facts
Sep 21, 2026
Merged

rchasman merged 5 commits into
masterfrom
feat/chess-voter-facts

Conversation

@rchasman

Copy link
Copy Markdown
Owner

One thing

Chess voters get facts from chess.js instead of an ASCII grid to squint at, and every vote is labelled with what the move actually does. This is the fix for the report of a voter claiming it "took its own piece", and for a vote that argued about a Black queen several moves after the queen had been captured: the models were fed the live position, but they misread the grid and the recent SAN list.

What changed

  • src/chess/facts.ts, one module (absorbs describe-move.ts and material.ts): per move, the piece, squares, capture and its value, check or mate, castling, promotion, en passant; then one move ahead: legal attackers and legal recapturers of the landing square, the cheapest attacker, and the opponent's best capture in reply. Position facts: material per side, castling rights, every piece of each side by square, the mover's pieces attacked and undefended, and the opponent's best capture if the mover did nothing. Pinned pieces no longer count as attackers or defenders; en passant capturers do.
  • src/chess/prompt.ts: a POSITION section from those facts (with a PIECES inventory so the board never has to be inferred), fact columns in LEGAL MOVES, recent moves marked as already played, guidance that explains the columns instead of proverbs. FEN and ASCII board kept.
  • describeMove now takes the state and returns SAN plus the proven facts, so the vote panes and the log show "Nxe5 takes Pawn 1; attacked 1 (Knight 3) / defended 0; reply takes Knight 3 on e5" next to the model's prose. moveKey stays SAN. Dominion and Go labels unchanged.
  • src/chess/jev.ts consumes the same facts.
  • Eval runner src/chess/evals/vs-bot.ts (model versus the rules bot through the real API) reporting material margin, hung pieces, pieces lost for free, captures and checkmates; shared plumbing with the Go runner in src/evals/vs-bot.ts.

Measurement, 3 games each as White versus the rules bot, cap 80 plies

model before after
gemini-3.5-flash-lite margin +4.7, hung 4.0 per game, 0 wins margin +13.0, hung 2.7, 1 win by mate
claude-haiku margin -10.3, hung 7.7, 0 wins margin -6.7, hung 5.3, 1 win by mate

Three games is a smoke check, not a study; both models still hang pieces.

Dead code

Removed describe-move.ts, material.ts, ChessMove.captured (written, never read), a duplicated isCheckmate and a duplicated mean. Exports with no production importer in touched files: 0.

Evidence

  • bun run check green.
  • Facts tests on hanging, pinned, defended and en passant pieces, castling, promotion and mate; prompt and label tests; eval stats tests; every one mutation-checked.
  • Adversarial review (fact correctness; prompt, DRY and conventions; 3 skeptics per finding); confirmed findings fixed here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RsVBKyqGXWMTpBTiB8WMws

rchasman and others added 3 commits September 21, 2026 22:18
… them

Models misread the ASCII grid and the recent SAN list: one vote argued
about a queen captured moves earlier. The prompt now lists every piece
by square, marks recent moves as history and puts the facts in columns;
describeMove takes the state so the vote panes show what a move does
next to the model's prose.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RsVBKyqGXWMTpBTiB8WMws
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RsVBKyqGXWMTpBTiB8WMws
@vercel

vercel Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
dominion-maker Ready Ready Preview Sep 21, 2026 12:28pm UTC

Attackers and defenders are legal captures and recaptures, so a pinned
piece counts for nothing and an en passant capturer counts. Material,
castling rights, every piece by square, unguarded pieces and the
opponent's best capture come from the same module.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RsVBKyqGXWMTpBTiB8WMws
@rchasman
rchasman merged commit 8301eb0 into master Sep 21, 2026
4 checks passed
@rchasman
rchasman deleted the feat/chess-voter-facts branch September 21, 2026 12:29

This branch was successfully deployed

1 active deployment
Preview — e5bc41b2 Deployed Sep 21, 2026 by vercel[bot]
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