Commit Graph

5 Commits

Author SHA1 Message Date
drjones
c12640cf52 feat(cluster): zero-config horizontal scaling by cloning
An instance decides what it is at startup instead of being told: it
generates its own identity, registers a heartbeat, and campaigns for
each game. Exactly one instance drives a game's rounds and publishes
frames; the rest relay them and forward mutations to the leader. Clone
the VM, boot it, done.

Sessions and the scratch nonce move to Redis. Both were per-instance
state that would have broken behind a load balancer: a token minted by
one clone was unknown to the others, and two clones would have handed
the same nonce to different players, which for the same key means the
same outcome.

Fixes a bug found by running two instances: /api/games read the local
room object, so a follower reported a permanently settled game and its
clients never saw a betting window. Hubs now serve the last frame they
saw, produced or relayed.

Failover measured at 6s after kill -9 on an instance leading two games.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 23:07:47 +00:00
drjones
5210266fd6 feat(pqid): hybrid post-quantum identity, AGPL-3.0 license
Player identity is now Ed25519 and ML-DSA-65 (NIST FIPS 204) together,
both signatures required. An attacker must break lattice assumptions and
elliptic curves, not either one — which covers both the quantum threat to
Ed25519 and the possibility that a 2024 lattice standard does not hold.

Signatures are domain-separated to this application so one captured from
another ML-DSA protocol cannot be replayed.

Licensed AGPL-3.0: a fork stood up as a service must publish its changes,
which is what keeps a provably-fair platform honest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 22:17:54 +00:00
drjones
2a2a1db8de feat: playable arcade — rooms, identity, client, deployment
Round length is now bounded: the multiplier follows a hyperbolic curve
diverging at 60s, replacing an exponential one where a 275x crash point
produced a two-and-a-half minute round.

Fixes seed reveal, which silently failed every round because pgx cannot
encode a fixed-size byte array as bytea.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 15:34:52 +00:00
drjones
8045e37c16 feat(ledger): add append-only double-entry engine
The Lightning bridge is modelled as the boundary with the outside
world and is the one account permitted to go negative; its negative
balance is exactly what is owed to players inside the system. All
other accounts are floored at zero by both the application and a
database trigger.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 03:23:49 +00:00
drjones
9413537251 feat(fixed): add Q32.32 deterministic fixed-point arithmetic
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 02:19:06 +00:00