Solve a rated Puzzle: served near the Puzzle rating, Moves checked by the server #443

Closed
opened 2026-10-16 08:20:02 +00:00 by root · 11 comments
root commented 2026-10-16 08:20:02 +00:00 (Migrated from gitlab.core-project.space)

Parent

#440

What to build

The tracer bullet: a signed-in Player solves or fails a rated Puzzle, end to end.

  • Access. A Puzzles entry in the navigation. /puzzles needs an Account Session, with the same beforeLoad guard as the account page (#409), remembering the destination. A Guest is asked to sign in or sign up.
  • Serving. "Next" returns the Account's pending Attempt if there is one. Otherwise it picks a random Puzzle with no Attempt by this Account within ±100 of the Puzzle rating, widening in steps until one is found, and creates the pending Attempt in the same transaction. Randomness comes from a root-provided source, like the clock and minters (ADR 0044). No unseen Puzzle left is a contract error the page shows.
  • The board. The existing board and click resolver. It shows the Puzzle's FEN, plays the opponent's first Move after a short beat, is oriented with the Player's Color at the bottom, and lets only the Player's pieces move. It says whose Turn it is.
  • Server-checked Moves. The client never holds the line beyond the Moves played. A Move is correct if it is the next Player Move of the line, or if it delivers Checkmate (which solves the Puzzle). A correct Move gets the opponent's reply, or solves the Puzzle at the end of the line. Any other legal Move is wrong, and the right Move is shown. Promotion works. Themes are not sent before resolution.
  • Rating. Solving or a wrong Move resolves the Attempt and applies the Glicko-2 update (#441) in one transaction. The page shows the Puzzle rating, and the change after the result. The provisional flag is sent (shown in a later ticket). A failed Attempt then shows the right Move and "Next"; retrying comes later.
  • Schema. The Puzzle rating row (one per Account; defaults read until the first Attempt) and the Attempt row (Account, Puzzle, state, Moves played, rating before, rating change, served at, resolved at, last replayed at). Unique on (Account, Puzzle), at most one pending per Account. Both are deleted with the Account.
  • Contract. A puzzle router with next, move and rating, Account-only, its errors in REFUSAL_STATUS. Moves over the wire as UCI (ADR 0021). Copy in English and French (ADR 0025).

Seams: S1 (the API through its RPC contract) and S3 (the app's router with the API fakes). Covers stories 1-17, 20-21, 27-31, 47-48 of #440.

Acceptance criteria

  • Signed out, /puzzles goes to sign-in and comes back after it; a signed-out RPC call is refused.
  • "Next" serves an unseen Puzzle within the window, widens when the band is empty, and never serves a Puzzle this Account already has an Attempt for.
  • A reload or a second "Next" returns the same pending Attempt, at the Moves already played.
  • The opponent's reply follows a correct Move; the end of the line solves; any Checkmate solves; any other legal Move fails and returns the right Move; an illegal Move is refused without failing.
  • A Move on a resolved Attempt is refused.
  • Solving raises and failing lowers the Puzzle rating by the module's amount; the result carries the change.
  • Two concurrent Moves on one Attempt resolve it once.
  • Deleting the Account deletes its Puzzle rating and Attempts.
  • Front view tests: the first Move plays, the orientation, only own pieces movable, solved and failed states, the rating change, "Next".
  • Prior art followed: the rpc-games and rpc-clock integration tests, router.test.tsx.
  • The gate is green (CONTRIBUTING.md, "The five commands").
## Parent #440 ## What to build The tracer bullet: a signed-in Player solves or fails a rated Puzzle, end to end. - **Access.** A Puzzles entry in the navigation. `/puzzles` needs an Account Session, with the same `beforeLoad` guard as the account page (#409), remembering the destination. A Guest is asked to sign in or sign up. - **Serving.** "Next" returns the Account's pending Attempt if there is one. Otherwise it picks a random Puzzle with no Attempt by this Account within ±100 of the Puzzle rating, widening in steps until one is found, and creates the pending Attempt in the same transaction. Randomness comes from a root-provided source, like the clock and minters (ADR 0044). No unseen Puzzle left is a contract error the page shows. - **The board.** The existing board and click resolver. It shows the Puzzle's FEN, plays the opponent's first Move after a short beat, is oriented with the Player's Color at the bottom, and lets only the Player's pieces move. It says whose Turn it is. - **Server-checked Moves.** The client never holds the line beyond the Moves played. A Move is correct if it is the next Player Move of the line, or if it delivers Checkmate (which solves the Puzzle). A correct Move gets the opponent's reply, or solves the Puzzle at the end of the line. Any other legal Move is wrong, and the right Move is shown. Promotion works. Themes are not sent before resolution. - **Rating.** Solving or a wrong Move resolves the Attempt and applies the Glicko-2 update (#441) in one transaction. The page shows the Puzzle rating, and the change after the result. The provisional flag is sent (shown in a later ticket). A failed Attempt then shows the right Move and "Next"; retrying comes later. - **Schema.** The Puzzle rating row (one per Account; defaults read until the first Attempt) and the Attempt row (Account, Puzzle, state, Moves played, rating before, rating change, served at, resolved at, last replayed at). Unique on (Account, Puzzle), at most one pending per Account. Both are deleted with the Account. - **Contract.** A `puzzle` router with `next`, `move` and `rating`, Account-only, its errors in `REFUSAL_STATUS`. Moves over the wire as UCI (ADR 0021). Copy in English and French (ADR 0025). Seams: S1 (the API through its RPC contract) and S3 (the app's router with the API fakes). Covers stories 1-17, 20-21, 27-31, 47-48 of #440. ## Acceptance criteria - [ ] Signed out, `/puzzles` goes to sign-in and comes back after it; a signed-out RPC call is refused. - [ ] "Next" serves an unseen Puzzle within the window, widens when the band is empty, and never serves a Puzzle this Account already has an Attempt for. - [ ] A reload or a second "Next" returns the same pending Attempt, at the Moves already played. - [ ] The opponent's reply follows a correct Move; the end of the line solves; any Checkmate solves; any other legal Move fails and returns the right Move; an illegal Move is refused without failing. - [ ] A Move on a resolved Attempt is refused. - [ ] Solving raises and failing lowers the Puzzle rating by the module's amount; the result carries the change. - [ ] Two concurrent Moves on one Attempt resolve it once. - [ ] Deleting the Account deletes its Puzzle rating and Attempts. - [ ] Front view tests: the first Move plays, the orientation, only own pieces movable, solved and failed states, the rating change, "Next". - [ ] Prior art followed: the `rpc-games` and `rpc-clock` integration tests, `router.test.tsx`. - [ ] The gate is green (`CONTRIBUTING.md`, "The five commands").
root commented 2026-10-16 08:20:32 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #444

mentioned in issue #444
root commented 2026-10-16 08:20:39 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #445

mentioned in issue #445
root commented 2026-10-16 08:20:44 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #446

mentioned in issue #446
root commented 2026-10-16 08:21:13 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #441

mentioned in issue #441
root commented 2026-10-16 08:21:28 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #440

marked this issue as related to #440
root commented 2026-10-16 08:21:40 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #441

marked this issue as related to #441
root commented 2026-10-16 08:21:41 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #442

marked this issue as related to #442
root commented 2026-10-16 08:21:42 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #444

marked this issue as related to #444
root commented 2026-10-16 08:21:43 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #445

marked this issue as related to #445
root commented 2026-10-16 08:21:43 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #446

marked this issue as related to #446
root commented 2026-10-18 13:02:28 +00:00 (Migrated from gitlab.core-project.space)

mentioned in merge request !554

mentioned in merge request !554
root (Migrated from gitlab.core-project.space) closed this issue 2026-10-19 09:53:34 +00:00
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.

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