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