Apply a checked Move without checking it again, so the Puzzle sample loads fast #448

Open
opened 2026-10-18 11:22:53 +00:00 by root · 1 comment
root commented 2026-10-18 11:22:53 +00:00 (Migrated from gitlab.core-project.space)

Problem

Loading the committed Puzzle sample (53,187 Puzzles, #442) takes about a minute of CPU. Almost all of it is the engine checking each line: checkLine in apps/api/src/puzzles/puzzle-set.ts calls game.isLegal(move) and then game.apply(move), and apply checks legality again. Each Move's legality is computed twice, about 35 s of the load.

It costs us twice:

  • every stack's deploy runs db:puzzles after the migrations, so each deploy waits that long;
  • the whole-sample test had to leave pnpm test for test:slow (it starved the other tests in the commit hook), so it no longer runs on every commit.

What to build

A way for the engine to apply a Move already known to be legal without checking it again, used by the Puzzle loader (and anywhere else that checks first, then applies). It stays behind the engine facade (ADR 0001); the shape is the implementer's call, for example apply returning a Result so callers drop their separate isLegal, or an apply that trusts a Move taken from legalMoves().

Acceptance criteria

  • Applying a checked Move does not compute its legality a second time.
  • The engine's public behaviour is unchanged: an illegal Move is still refused wherever it was before.
  • Loading the whole sample (pnpm turbo run test:slow --filter=@chess/api) is measurably faster; before and after timings in the merge request.
  • If the load gets back under a few seconds, the whole-sample test moves back into pnpm test.
  • The gate is green (CONTRIBUTING.md, "The five commands").
## Problem Loading the committed Puzzle sample (53,187 Puzzles, #442) takes about a minute of CPU. Almost all of it is the engine checking each line: `checkLine` in `apps/api/src/puzzles/puzzle-set.ts` calls `game.isLegal(move)` and then `game.apply(move)`, and `apply` checks legality again. Each Move's legality is computed twice, about 35 s of the load. It costs us twice: - every stack's deploy runs `db:puzzles` after the migrations, so each deploy waits that long; - the whole-sample test had to leave `pnpm test` for `test:slow` (it starved the other tests in the commit hook), so it no longer runs on every commit. ## What to build A way for the engine to apply a Move already known to be legal without checking it again, used by the Puzzle loader (and anywhere else that checks first, then applies). It stays behind the engine facade (ADR 0001); the shape is the implementer's call, for example `apply` returning a `Result` so callers drop their separate `isLegal`, or an apply that trusts a Move taken from `legalMoves()`. ## Acceptance criteria - [ ] Applying a checked Move does not compute its legality a second time. - [ ] The engine's public behaviour is unchanged: an illegal Move is still refused wherever it was before. - [ ] Loading the whole sample (`pnpm turbo run test:slow --filter=@chess/api`) is measurably faster; before and after timings in the merge request. - [ ] If the load gets back under a few seconds, the whole-sample test moves back into `pnpm test`. - [ ] The gate is green (`CONTRIBUTING.md`, "The five commands").
root commented 2026-10-18 13:02:27 +00:00 (Migrated from gitlab.core-project.space)

mentioned in merge request !554

mentioned in merge request !554
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amaurycoudr/chess-project#448
No description provided.