1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
# 0002 — Client and server must share MAJOR.MINOR
Status: accepted, 2026-11-01
## Context
`AGENTS.md` previously described MINOR as backwards compatible: an old client
should work with a newer server and vice versa. In practice the wire format,
game messages, and client flows have changed in every MINOR so far
(`PLAY_START` payloads, `CRASH_*`, `HISTORY`, cursor and bet semantics). Silent
half-compatibility produces confusing failures: a new client sends a command
the old server echoes back as text, or an old client misparses a new field.
The project now ships multiple frontends (TUI and GUI) and a server, all
released together from one repository.
## Decision
1. **Version compatibility is MAJOR.MINOR lockstep.** A client and server may
differ only in PATCH. Any difference in MAJOR or MINOR refuses the
connection.
2. **The first line after the TLS handshake is `HELLO <version>`.** The server
replies with its own version, the latest release version, and the download
URL. Any other message before `HELLO` is rejected. No credentials are sent
before the versions agree.
3. **The server is authoritative about the latest release.** It advertises
`latest` and the download URL in the handshake; the client compares its own
`CARGO_PKG_VERSION` and offers a link when it is behind. The download site
is not queried by clients: that would add a second TLS stack and a web PKI
trust domain for one string.
4. **A MAJOR bump covers a wire change; a MINOR bump covers a feature that
changes the protocol or the shared semantics.** Both require releasing
clients and server together.
## Consequences
- Every MINOR release must update the server and all clients simultaneously;
a stale server is a hard failure, not a degraded experience. Deployment order
matters.
- `AGENTS.md`'s MINOR rule is rewritten; the old "old clients work with new
servers" promise is withdrawn.
- The handshake is itself a breaking wire change: this lands as v4.0.0.
- The update check needs no extra dependency and works for both frontends, at
the cost of only being as fresh as the server you connect to.
## Alternatives considered
- **Keep MINOR backwards compatible** and negotiate per-feature: more work,
and every feature so far would have needed a capability flag. Rejected.
- **Fetch `version.json` from the download site**: site-authoritative updates,
but adds an HTTP client and a CA trust store with different rules from the
pinned game server. Rejected.
- **Semver-range matching**: allows broader compatibility but makes the
failure modes depend on which optional features each side implemented.
Rejected for a small, tightly released product.
|