Spaces:
Paused
Paused
Commit History
-
T-013: fault-injection loopback — latency, reordering, drops
Claude +1: Claude Sonnet 5Unverified signaturenet/loopbackFaults.js wraps any Transport with configurable latencyMs, jitterMs (independent per-call delay that genuinely reorders promise resolution relative to submission order), and dropRate (a dropped submitCommand never reaches the wrapped transport at all — a lost order, never a delayed one — and the promise and onEvent channels drop independently of each other). All randomness is driven by an injectable rng, scripted in every test rather than left to real randomness. Revises T-012's own "five client sites" estimate down to one, with evidence: T-012's actual call-site audit found exactly one command-issuing site that reads a CommandResult (input.js's placeBuildingAt); everything else is provably fire-and-forget. That one site is now proven against a real injected delay, not just a microtask tick, via a new integration test driving it through createFaultyTransport(directTransport, {latencyMs:20}). 10/10 new tests, full suite 2,470/2,470 (test/ailab.test.js still excluded — pre-…c14468b -
T-012: port the single-player client onto session + loopback
Claude +1: Claude Sonnet 5Unverified signatureAn ordinary skirmish, a live competition fixture, and a loaded skirmish save now run their sim behind a real server/session.js session, reached through net/loopback.js exactly as multiplayer will reach one over a socket (ADR-0003/ADR-0004). input.js, inputCommands.js, hudSelection.js, and main.js's minimap handler no longer call engine/commands.js directly anywhere in that path. Odyssey, a scenario/raider/bounty, and a spectated match are deliberately left on their existing tick path this pass (PRD non-goal, dossier 03). ADR-0013 records why that still leaves the shared input/HUD modules with exactly one calling convention: net/directTransport.js is a minimal Transport-shaped adapter (no session, no tick) that boot.js hands them instead, reusing server/session.js's standalone applyCommand. server/session.js's createSession gained an opts.state escape hatch to wrap an already-deserialized save. net/transport.js's submitCommand JSDoc was corrected to match what net/loopback.js actually…42b40d2 -
T-011: net/loopback.js — in-process transport
Unverified signatureWires a client directly to a server/session.js session, no socket (ADR-0004). Implements net/transport.js's generic Transport contract (submitCommand/onEvent/close) plus two loopback-specific extensions (tick, getState) a real remote transport could never offer — T-012 decides how much of the client actually leans on those versus driving purely off onEvent. submitCommand returns a Promise even though the work underneath is genuinely synchronous: the mutation is visible to the caller BEFORE the promise resolves (proven by a test that checks state with no await), so client code written against this is already correct for a transport where resolution takes real time, and T-013's fault injection has an actual gap to delay. Same static-integrity story as T-010: the reachability walk correctly flagged this file as an orphan (nothing imports it yet), extended as a temporary exemption alongside server/session.js, both removed together once T-012 wires boot.js to import loopback.js. 8/8 new …a2cd246 -
T-009 + T-010: the session/transport seam — server/session.js
Unverified signatureEstablishes the seam ADR-0003/ADR-0004 exist to create, before any network code: a session owns one match's state and is the only thing outside engine/ allowed to mutate it. net/commandShapes.js adopts the WireCommand union from docs/analysis/02-command-wire-protocol.md §3 verbatim, covering the full skirmish command surface (all of engine/commands.js's issue*, plus production/research/recycle) and deliberately excluding Odyssey- only mutators (galaxy.js jump/lanes, colonyPolicy.js, colony.js, market.js, diplomacy.js) — grounded directly against hudSelection.js's own imports, not guessed. Odyssey stays on its current path; PRD's own non-goals rule out multiplayer Odyssey, so porting it onto this seam would be scope with no product behind it. net/transport.js documents the Transport interface the same way. server/session.js: submitCommand resolves ids and applies the matching issue* call, dropping a dead id gracefully (a race) vs rejecting a malformed/unknown shape (a client bug) — re…a14579a