# 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 `.** 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.