summaryrefslogtreecommitdiffstats
path: root/CONTEXT.md
diff options
context:
space:
mode:
Diffstat (limited to 'CONTEXT.md')
-rw-r--r--CONTEXT.md76
1 files changed, 76 insertions, 0 deletions
diff --git a/CONTEXT.md b/CONTEXT.md
new file mode 100644
index 0000000..6fefd53
--- /dev/null
+++ b/CONTEXT.md
@@ -0,0 +1,76 @@
1# Context
2
3zagan-bet is a small play-money casino: one Rust workspace with a shared
4library, 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
5current when a term changes meaning.
6
7## Product terms
8
9- **Play credit** — the unit a player wins and loses. Registration grants a
10 starting balance. There are no deposits, withdrawals, cash-outs or KYC; the
11 web app is a game, not a regulated gambling service.
12- **Server** — the authoritative process. It owns the database, the game
13 rules, the balances, the random draws and the clock used to settle crash.
14- **Frontend** — a presentation adapter over `ClientCore`: the terminal client,
15 the egui desktop app, or the browser app behind the web gateway. Frontends
16 send `Command` values and render `View` values. They never compute payouts.
17- **ClientCore** — the I/O-free state machine shared by every frontend. It owns
18 navigation, the current game view, the pending request, and the local clock
19 anchor for crash. It contains no terminal, network or egui types.
20- **Gateway (`webd`)** — a server-side frontend adapter for the browser. It owns
21 one upstream TLS connection and one `ClientCore` per browser session, and
22 translates browser JSON into `Command`/`View`. The browser never speaks the
23 game wire protocol.
24- **Upstream** — the game server the gateway connects to. Its address and SPKI
25 fingerprint are operator configuration. The browser never sees a certificate.
26- **Session** — one browser login held by the gateway. Identified by an
27 HttpOnly cookie. A refresh or a new tab reattaches to the same session during
28 the grace window; a later visit starts a new login.
29
30## Wire terms
31
32- **Frame** — `[u32 length][UTF-8 payload]`, length big-endian, at most 64 KiB.
33 The frame is the unit of transport; the payload is text.
34- **Envelope** — the first token of a frame payload:
35 - `REQ <id> [idem=<token>] <command>` — client request.
36 - `RES <id> <body>` — the reply to that request.
37 - `EVT <seq> <body>` — a server-initiated event, numbered per connection.
38- **Request id** — a client-chosen `u64`, unique on the connection while its
39 reply is cached. It correlates a reply with the request that caused it.
40- **Idempotency key** — an optional opaque token on a request. The connection
41 caches the last 256 request ids; resending the same id and payload replays the
42 stored reply instead of performing the action twice.
43- **Event sequence** — a server-chosen `u64`, incremented once per `EVT` on a
44 connection. Clients use it to drop duplicates and to notice gaps.
45- **HELLO** — the first request after TLS. Client and server must share
46 `MAJOR.MINOR`; the reply carries the server version, download URL and the
47 server's Unix time in milliseconds.
48- **Tick** — `EVT crash.tick session=<id> t=<server_ms> m=<multiplier>`, pushed
49 at most every 100 ms while a crash round runs. The server clock still settles
50 a cash-out.
51- **Commit** — `sha256(seed)` in hex, sent with `CRASH_START` before the player
52 can act. **Reveal** — the seed itself, sent when the round ends. The crash
53 point is a pure function of the seed, so a player can check both.
54
55## Deployment terms
56
57- **Download site** — `web/`: `index.php` lists builds, `latest.php` feeds the
58 stable installers, `install.sh`/`install.ps1` fetch and verify the newest app.
59- **Play app** — the static browser bundle under `/play/`, built from
60 `web/play/` with esbuild and served by nginx.
61- **Grace window** — the 60 seconds the gateway keeps an upstream connection
62 after the last browser socket closes. Reattaching within it preserves a live
63 round; expiry closes upstream and the server forfeits per its existing rule.
64- **Takeover** — a new browser connection presenting an existing session cookie
65 replaces the old socket; the old tab is told it was replaced.
66
67## Invariants
68
69- One payout formula, one place. `process_action` stores raw data;
70 `calculate_result` derives the result. Frontends only render.
71- Every balance mutation is transactional, and an audit row exists before the
72 balance moves.
73- A crash point never reaches a client before the round ends.
74- The server clock, not a browser or gateway clock, settles cash-out.
75- `MAJOR.MINOR` is lockstep between client and server; only the patch component
76 may differ. A wire change is a MAJOR bump.