Skip to content

Hotfix: complete the rematch-decline protocol (main is uncompilable)#65

Merged
testtest126 merged 1 commit into
mainfrom
fix/rematch-decline-protocol
Jul 10, 2026
Merged

Hotfix: complete the rematch-decline protocol (main is uncompilable)#65
testtest126 merged 1 commit into
mainfrom
fix/rematch-decline-protocol

Conversation

@testtest126

Copy link
Copy Markdown
Owner

Summary

Main is currently red#54 and #55 were each green on their own stale branches but never built combined: #55 added ClientMessage.declineRematch (plus client handling for a ServerMessage.rematchDeclined that never existed anywhere) while #54 rewrote the same coding switches. The textual merge kept the enum case but no switch arms: non-exhaustive switches in ChessOnline and the coordinator, and a missing enum case for the client. Nothing on main compiles.

This completes the protocol across all layers with real semantics rather than just silencing the compiler:

  • ChessOnline: declineRematch wired through Kind/decode/encode; ServerMessage.rematchDeclined added — an explicit "no" that resets the requester's waiting state, distinct from rematchUnavailable (opponent left). Round-trip tests cover both.
  • Server: the coordinator handles declineRematch — drops the rematch slot and sends rematch_declined to the requester; integration test included.
  • Client: Add rematch decline action and improved UX (#39) #55's decline UI now receives the message it was written against.

Process note: this is the second merge-order race today (#55+#57 was benign; #54+#55 was not). strict: true on required status checks — requiring branches to be up to date before merging — would prevent the class entirely, at the cost of re-running CI after each merge.

Test plan

  • ChessOnline 6/6, server 25/25 (incl. new decline-notifies-requester test), app builds for testing
  • This PR's CI is the first green build of the combined code

🤖 Generated with Claude Code

PRs #54 and #55 were each green on their own branches but never built
combined: #55 added ClientMessage.declineRematch (and client handling
for a ServerMessage.rematchDeclined that never existed) while #54
rewrote the same coding switches — the textual merge kept the enum case
but none of the switch arms, leaving main uncompilable (non-exhaustive
switches in ChessOnline and the coordinator, missing enum case for the
client).

- ChessOnline: declineRematch wired through Kind/decode/encode;
  ServerMessage.rematchDeclined added (explicit "no", distinct from
  rematchUnavailable meaning the opponent left); round-trip tests cover
  both.
- Server: coordinator handles declineRematch — drops the slot and sends
  rematch_declined to the requester; new integration test.
- Client: #55's existing decline UI now has the real message it was
  written against.

Verified: ChessOnline 6/6, server 25/25, app builds for testing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@testtest126 testtest126 enabled auto-merge (squash) July 10, 2026 04:01
@testtest126 testtest126 merged commit 5ce35ff into main Jul 10, 2026
6 of 7 checks passed
@testtest126 testtest126 deleted the fix/rematch-decline-protocol branch July 10, 2026 04:38
@testtest126

Copy link
Copy Markdown
Owner Author

Heads-up: this is a duplicate of #63 (opened ~2 min earlier) — same 4 files, functionally identical protocol/server/test changes; neither includes the #39 offer-expiry TTL, which stays open. To save review cycles I'd suggest consolidating on #63 and closing this one, but the root-cause analysis here is the best writeup of the incident (semantic merge race between #54 and #55, each green on stale branches), and the strict: true required-checks suggestion is worth adopting — it complements #59's cancel-in-progress fix (prevention pre-merge vs detection post-merge).

testtest126 added a commit that referenced this pull request Jul 10, 2026
Bring the String Catalog branch up to date with time controls (#54),
rematch decline (#55/#65), Sign in with Apple (#57), and the online
resume banner (#66). Newly added user-facing strings are localized in
follow-up commits and re-extracted into the catalog.
testtest126 added a commit that referenced this pull request Jul 10, 2026
The rematch slot used to live until a player disconnected, declined,
queued elsewhere, or closed the sheet — an ignored offer left the
requester waiting forever against an idle-but-connected opponent.

Each slot now carries an expiry task (60s, injectable for tests like
the clock override). On expiry both players get rematch_unavailable:
the requester stops waiting and an unanswered offer leaves the
opponent's sheet — the app already handles that message, so no client
changes are needed. Any other slot teardown cancels the task.

Completes the optional-hardening item of #39; the decline action
itself landed in #55/#65.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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