jonnify·codemojex /codemojex/guesses-on-fair-lanes

Codemojex · chapter C3 · the play path

Guesses on fair lanes.

A guess is the game’s one write, and the play path is where the architecture earns its keep. Codemojex.Guesses.submit/3 validates the six codes, overlays the player’s locks, charges the room’s currency, and only then enqueues a branded JOB on the player’s own lane — answering before the guess is scored. The scoring happens behind the bus, on one leased consumer.

Grounding — echo/apps/codemojex/lib/codemojex: game.ex (Codemojex.Guesses, the ScoreWorker) · locks.ex · rate_limiter.ex · application.ex (the four consumers) · design §Messaging / §Core flows / §Privacy and fairness.

A guess, end to end — select a stage of the path
C3.1 · admit & lock validate vs keyboard overlay Locks.merge C3.2 · charge & enqueue charge keys | clips enqueue JOB · PLR lane ↓ answer: on its way C3.3 · lanes & score score pure · linear announce live | seal
C3.1 → submit/3 reads the game from the system of record, checks it is open and unexpired, validates the six codes against the game’s snapshotted keyboard, then overlays the player’s durable locks. A closed, expired, or malformed guess never becomes work.
§1

Three properties

the play path

Admission before enqueue. A guess that is closed, expired, malformed, or unaffordable never becomes a job. submit/3 walks a cond of guards and charges the wallet before it enqueues — so everything on the queue is a validated, paid attempt, never waste. The surface answers accepted-and-on-its-way, and there is no process per game, so a large field of idle games costs nothing.

Per-player fairness. The guess lane is keyed by the player’s PLR, and the bus rotates service across lanes. A player who taps twice as fast gets their own lane serviced in turn — not twice the field’s throughput. Paying for speed buys a turn, not the field, and the fairness is structural: it is the group key on the queue, not a throttle at the edge.

At-least-once, made harmless. Delivery is at-least-once and every handler is idempotent. The enqueue answers :duplicate to a re-send; scoring is a pure function of the secret and the guess, so a re-scored guess is identical; and each consumer leases the job it works, so a crashed consumer’s in-flight job becomes visible again rather than lost. The attempt a player paid for is scored, once, even across a failure.

Scoring is linear only — 100 − 20·d per position summing to 600, no tiers, no bonus — and it lives in C4. C3 is the admission and the delivery: how a guess earns its place on the bus and rides it safely to the one authority that scores it.

§2

The three dives

hub + 3 dives

Grounding — the play path read on the running code: Codemojex.Guesses.submit/3 and Codemojex.ScoreWorker.handle/1 in game.ex, Codemojex.Locks, Codemojex.RateLimiter, the four EchoMQ.Consumer children in application.ex, and the scoring story feature.

§3

References

sources · related

Sources

Related