Decisions Log
The authoritative, append-only decisions log lives in
docs/design.mdin the repository — each entry dated, with rationale and alternatives considered. This page is a curated milestone summary; for the full trail (and the most recent entries), readdesign.md.
Foundational decisions (2026-06-02)
- A1 before A2. Prove the protocol and the table feel before layering the roguelike skin. The roguelike is decoration; the table is foundation.
- B2 persistence (JSONB blob) before B3. In-memory only is a regression given
pgis in the scaffold; the action log is the right end state but a blob is the right v1 since the engine is already pure. - Serializable from day one. Not just for save/resume — it’s the same problem as online co-op, anti-cheat, replay, spectate, and deterministic tests. Solve it once. See Architecture → Engine purity.
- Solo bot = auto-rolls, no AI. The cheapest possible solo opponent: when the bettor locks bets, the bot rolls.
- Chip dispatch contract is mechanical. The shooter/bettor split is enforced by the TypeScript types and reducer dispatch, not by code review — making the purist test a property of the system, not a promise. See Chip Dispatch Contract.
Bet catalog buildout (2026-06-02 → 06-03)
The catalog grew from “v1 minimum” to a full casino table, then to the complete v1 set:
- Standard table: don’t-pass + odds, come / don’t-come, all place numbers, field, hardways, big 6/8, any 7, any craps. Come/don’t-come needed the only reducer extension — the
establish_pointsettlement. - Buy / lay (12 bets, 5% vig in the payout fractions), the high-prop set, all 21 hop combos.
- Multi-roll bets: fire, sharpshooter, ATS, repeaters — all on the
ResolveContextmechanism the fire bet established.
Every payout asserted in resolver.test.ts against real-casino numbers. See Bet Catalog.
Roguelike layer A2 (2026-06-02 → 06-05)
Shipped end-to-end: run/antes, chip shop (BUY_CHIP / REROLL_SHOP), shooter rotation (CHANGE_SHOOTER), bet leveling (LEVEL_BET), rarity-weighted + synergy-biased shop drafting, rarity-tiered pricing — plus the full client UI (run-status banner, shop with rarity badges + synergy hints, leveling, rotation). See Roguelike Layer.
Dice-skill + physics (2026-06-02 → 06-05)
The SkillInput { power, angle, hold } primitive threaded through ROLL into ChipCtx; skill-aware shooter chips (power_throw / finesse_shot / loaded_dice / steady_hand); the press-and-flick dice-gesture client with throw arc, tumble, mock physics, multi-die juggling, particle trails, and impact bursts; and the Phase 4 skill-quality training panel with per-chip threshold tooltips.
Auth + online foundation (2026-06-02 → 06-05)
Per-bettor opaque-token auth (mint-once 128-bit tokens; Authorization: Bearer on player-owned actions; shared actions token-free). A3 mid-game join: JOIN_TABLE + the "spectator" role, the POST /api/rooms/:id/join endpoint, read-only spectator WS, and the client lobby browser + spectate view. Full user accounts remain deferred.
Bug-hunt hardening (2026-06-05)
A sweep across subsystems closed real defects and tightened invariants:
- Engine — pass/don’t-pass odds point-match fix + level-cost clamp.
- Persistence — independent
initial_statereplay base + a reduce-immutability fence. - Client dice-physics — keyboard quick-roll +
e.repeatguard, doc/test hardening. - Chip-dispatch contract — fenced at all three seams:
the_loaderinvalid-die fix + the runtime dice-seam guard (assertValidRoll), the settlement-seam guard (assertValidBettorSettlements, including a 1:1 bijection that closes a money-minting gap), and the compile-time discriminated-union that makes side-crossing a type error. See Chip Dispatch Contract → Enforced at all three seams.
For the exact dated entries with full rationale, always defer to docs/design.md.