refactor(perft): code-review polish for the perft rig + MCP server#95
Merged
Conversation
Six review findings from the merged perft/MCP work, no behavior change to the green gate: 1. Fix stale path in the divergence report an agent reads: point at chess-core/src/.../Move.kt, not the pre-move app/src path. 2. Split DivergenceReport.render() (now pure) from a new persist() so producing the report text has no hidden filesystem side effect; call sites persist then fail explicitly instead of writing inside an assert message. 3. Distinguish a Stockfish timeout from a real divergence: the rig (StockfishPerft) now throws instead of returning a partial divide, and the MCP tool (StockfishDivider) reports a new DivideResult.timedOut and withholds the partial map so a slow engine can't masquerade as a mismatch. 4. Bound the run_perft_gate subprocess (15m default / 45m deep) with a background stdout drainer, so a wedged gradle can't hang the agent forever. 5. De-duplicate the depth cap / timeout: tool descriptions now interpolate StockfishDivider.MAX_DEPTH / DEFAULT_TIMEOUT_MS instead of a separate constant that could drift from the real clamp. 6. Remove unused imports (kotlin.io.path.pathString, java.io.File). Verified: :perft-mcp:test green, :chess-core:desktopTest --tests "*Perft*" green with Stockfish present (Oracle 2 ran). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- run_perft_gate / stockfish_divide rows now match the new contract (gate subprocess timeout; stockfish_divide's timedOut field + partial- result withholding). - Future work: note The Grand Chess Tree's ~28k-position corpus as an Oracle 1 breadth extension, and why a no-divide speed counter (perft_cpu_2026) is the wrong tool for the localizer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Applies six code-review findings from the merged perft/MCP work (#49). No behavior change to the green gate — all fixes are correctness/robustness/clarity polish. The shipped move generator is untouched; these fixes are to the rig and the MCP adapter, not the engine.
Findings addressed
PerftVsStockfishTestwrote "Inspect the corresponding rule inapp/src/commonMain/.../Move.kt", but the file moved tochess-corein the perft-tests migration. An agent readingbuild/perft-divergence.txtwas pointed at a non-existent path (the exact "stale path after a module move" failure the docs hold up as the meta-lesson). Now points atchess-core/src/commonMain/.../Move.kt.render()hid a filesystem write — splitDivergenceReport.render()(now pure) from a newpersist(rendered); call sitespersist(...)thenfail(...)explicitly instead of writing to disk as a side effect of building anassertNullmessage.StockfishPerft) now throws instead of returning a partial divide, and the MCP adapter (StockfishDivider) reports a newDivideResult.timedOutand withholds the partial map. A slow engine can no longer look like a real mismatch.run_perft_gatenow bounds gradle (15 min default / 45 mindeep) via a daemon stdout drainer +waitFor(timeout)+destroyForcibly(), so a wedged build can't hang the MCP tool call (and the agent) forever.StockfishDivider.MAX_DEPTH/DEFAULT_TIMEOUT_MSinstead of a separateMAX_DEPTH_CAPconstant that could drift from the real clamp.kotlin.io.path.pathString.Plus a docs commit: syncs the
docs/perft.mdMCP tool table with the new contract (gate timeout;stockfish_divide'stimedOut), and adds a Future work note on using The Grand Chess Tree's ~28k-position corpus to broaden Oracle 1.Verification (ran locally, this branch, Stockfish present)
./gradlew :perft-mcp:test --rerun-tasks— green after a fresh recompile. Covers the description assertions that require the literals "clamped to 6" / "120s" (now produced by interpolating the real constants) andformatDivideResult../gradlew :chess-core:desktopTest --tests "*Perft*" --rerun-tasks— green after a fresh recompile. Oracle 2 (PerftVsStockfishTest) actually ran (2 tests, 0 skipped, 0 failures) against/opt/homebrew/bin/stockfish; noperft-divergence.txtwas written, consistent with a green gate.render/persistsplit) are compile-verified and unit-covered, but not runtime-triggered by this green run — correctly, since nothing diverged or timed out.🤖 Generated with Claude Code