Production freeze reported after the v0.9.3 (#21) deploy: every API route
hung and all panels stayed at LOADING. Root cause was not the #21 layout
(verified healthy across all 7 tabs/viewports) but makeName's unbounded
rejection loop over a finite 16x8=128 system-name pool — once a save grew
past ~128 systems, any jump into an undiscovered system spun forever on
Node's single thread (sql.js is synchronous), blocking the whole process.
makeName and makeCrewName now fall back to numbered variants ('Kepler Drift 2')
once their pools are exhausted, so they always terminate.
expand had no event assertion at all; build and mission-complete asserted
type/message but not the event's turn. Issue #11 requires every action type
to be covered with correct turn/type/message.
lib/game/events.ts: the latest N events of the save, newest first (ORDER BY
id DESC), with parseEventLimit for the optional ?limit= param (default 50,
cap 200, 400 otherwise). Unit tests cover default/accept/reject and
newest-first ordering + slicing.
Routes call ensureSave first (mission functions assume an initialized save),
map MissionError to 404/409 and non-integer path ids to 400. OpenAPI spec in
code gains both paths + the Mission schema (12 -> 14 paths); openapi.test.ts
covers the new shapes.
New missions table (schema + DDL). Pure model in lib/game/missions.ts:
DELIVER / EXPLORE / FIND contracts generated from missionRng(seed, turn),
board always topped up to >=3 AVAILABLE after every action. save.ts wires
SCHEMA_VERSION 5 -> 6 with a v6 backfill step and completion hooks inside
jumpToSystem/explorePlanet (one atomic persist). Unit tests cover generation
determinism, top-up idempotency, backfill, accept validation and per-type
completion incl. reward accumulation.
Flight-Ops plumbing minus game code: in-memory WASM DB, persist() via tmp+rename,
globalThis singleton. Schema is empty at scaffold stage; _meta plumbing table stamps
created_at on first open so the ./db volume holds a valid SQLite file from boot
(a brand-new sql.js database exports as zero bytes). instrumentation.ts opens it at
server start behind a runtime-guarded dynamic import (keeps node:fs out of the Edge
instrumentation bundle).
lib/openapi.ts is the machine-readable spec (served at /api/openapi) per AGENTS.md;
info.version sourced from package.json. Unit tests pin the spec shape and version sync.
scificn-ui v0.1.0 integrated copy-paste per its docs: Button/Panel/Badge/Card/Alert
in components/ui/, cn() helper in lib/utils.ts, theme tokens in app/globals.css.
Deliberate deviation from upstream: --text-muted #4A4A40 -> #6B6B5C (+12pt lightness)
for readability on the near-black background (default SCI-FI theme only). Landing page
proves the integration; no game UI yet.