# Context zagan-bet is a small play-money casino: one Rust workspace with a shared library, a terminal client, a server, a desktop GUI and a browser frontend. This file names the things the code and the docs talk about. Keep it current when a term changes meaning. ## Product terms - **Play credit** — the unit a player wins and loses. Registration grants a starting balance. There are no deposits, withdrawals, cash-outs or KYC; the web app is a game, not a regulated gambling service. - **Server** — the authoritative process. It owns the database, the game rules, the balances, the random draws and the clock used to settle crash. - **Frontend** — a presentation adapter over `ClientCore`: the terminal client, the egui desktop app, or the browser app behind the web gateway. Frontends send `Command` values and render `View` values. They never compute payouts. - **ClientCore** — the I/O-free state machine shared by every frontend. It owns navigation, the current game view, the pending request, and the local clock anchor for crash. It contains no terminal, network or egui types. - **Gateway (`webd`)** — a server-side frontend adapter for the browser. It owns one upstream TLS connection and one `ClientCore` per browser session, and translates browser JSON into `Command`/`View`. The browser never speaks the game wire protocol. - **Upstream** — the game server the gateway connects to. Its address and SPKI fingerprint are operator configuration. The browser never sees a certificate. - **Session** — one browser login held by the gateway. Identified by an HttpOnly cookie. A refresh or a new tab reattaches to the same session during the grace window; a later visit starts a new login. ## Wire terms - **Frame** — `[u32 length][UTF-8 payload]`, length big-endian, at most 64 KiB. The frame is the unit of transport; the payload is text. - **Envelope** — the first token of a frame payload: - `REQ [idem=] ` — client request. - `RES ` — the reply to that request. - `EVT ` — a server-initiated event, numbered per connection. - **Request id** — a client-chosen `u64`, unique on the connection while its reply is cached. It correlates a reply with the request that caused it. - **Idempotency key** — an optional opaque token on a request. The connection caches the last 256 request ids; resending the same id and payload replays the stored reply instead of performing the action twice. - **Event sequence** — a server-chosen `u64`, incremented once per `EVT` on a connection. Clients use it to drop duplicates and to notice gaps. - **HELLO** — the first request after TLS. Client and server must share `MAJOR.MINOR`; the reply carries the server version, download URL and the server's Unix time in milliseconds. - **Tick** — `EVT crash.tick session= t= m=`, pushed at most every 100 ms while a crash round runs. The server clock still settles a cash-out. - **Commit** — `sha256(seed)` in hex, sent with `CRASH_START` before the player can act. **Reveal** — the seed itself, sent when the round ends. The crash point is a pure function of the seed, so a player can check both. ## Deployment terms - **Download site** — `web/`: `index.php` lists builds, `latest.php` feeds the stable installers, `install.sh`/`install.ps1` fetch and verify the newest app. - **Play app** — the static browser bundle under `/play/`, built from `web/play/` with esbuild and served by nginx. - **Grace window** — the 60 seconds the gateway keeps an upstream connection after the last browser socket closes. Reattaching within it preserves a live round; expiry closes upstream and the server forfeits per its existing rule. - **Takeover** — a new browser connection presenting an existing session cookie replaces the old socket; the old tab is told it was replaced. ## Invariants - One payout formula, one place. `process_action` stores raw data; `calculate_result` derives the result. Frontends only render. - Every balance mutation is transactional, and an audit row exists before the balance moves. - A crash point never reaches a client before the round ends. - The server clock, not a browser or gateway clock, settles cash-out. - `MAJOR.MINOR` is lockstep between client and server; only the patch component may differ. A wire change is a MAJOR bump.