summaryrefslogtreecommitdiffstats
path: root/docs/adr/0002-version-lockstep.md
blob: 1e7f8ba90459bfedaa12f9dd3d960b754b0d00ad (plain) (blame)
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.