Add web game (plan2.md) on the independent runtime, merge-blocking gates

Builds the browser game around the existing Rust runtime: a window into the
universe, not a second simulation. Pure std, no external crates.

New crates:
- protocol: versioned, hashable client/server messages + hand-rolled JSON value
  and total parser (malformed packet -> Err, never panic).
- game_runtime: authoritative match state. Resolves turns through the
  INDEPENDENT interpreter (runtime_under_test::native_resolve), not the
  reference engine; filters visibility/knowledge; records and regenerates
  replays. A match is a pure function of (seed, roster, ordered inputs).
- web_assets/web_client: embedded browser client (arena, rune editor,
  knowledge panels, replay viewer) + static HTTP delivery.
- server: std::net HTTP + WebSocket (hand-rolled SHA-1/base64/RFC-6455 framing),
  turn timer, disconnect handling, panic-proof dispatch, poison-tolerant lock.
- web_tests: dependency-free WebSocket test client + Phase H gates.

Trust hardening per review:
- game_runtime no longer delegates to reference_runtime::execute; it runs the
  independent interpreter that the runtime-equivalence gate proves correct.
- Protocol/socket/replay/visibility/resilience gates are merge-blocking
  (added to the merge_group-required job in merge-gates.yml): 1k matches/0
  drift, 10k fuzz/0 panics, 100 headless socket E2E, 0 hidden-state leaks.
- Rendered-browser E2E is marked EXTERNAL-BLOCKED: Playwright runs advisory-only
  (continue-on-error, artifacts) until CI infrastructure with a browser exists;
  it is treated as unsatisfied, not green. The headless 100-match gate is
  labeled protocol-level coverage, not rendered-browser coverage.
- README documents the hand-rolled crypto/parser audit risk explicitly.

Fixes an integer-overflow panic in observed-volatility inference (i64 sum /
abs near i64::MIN) that could poison the server mutex.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-21 20:20:46 -07:00
co-authored by Claude Opus 4.8
parent 659544f0b2
commit 9d9d5ce41c
33 changed files with 5065 additions and 0 deletions
+262
View File
@@ -0,0 +1,262 @@
Web Game Implementation Plan
Prime Directive
Build the browser game around the already-defined Rust simulation/testing system.
The web game must be:
Browser-first
Server-authoritative
Replayable
Deterministic
Test-gated
Playable before pretty
No web feature may bypass the Rust runtime contract.
Architecture
Rust simulation core
Authoritative server
WebSocket protocol
Browser client
UI / arena / rune editor
Browser never decides truth.
Browser only sends:
intent
movement choice
rune program
library slot selection
inspection request
Server returns:
world snapshot
visible observations
turn result
trace excerpts
replay hash
legal player-facing diagnostics
Crates
crates/
world_model
rune_ir
trace_model
reference_runtime
game_runtime
replay_corpus
protocol
server
web_client
web_assets
web_tests
Phase A — Protocol First
Define all client/server messages before UI.
ClientMessage
JoinMatch
SubmitTurn
EditRuneProgram
InspectTarget
RequestReplay
Ping
ServerMessage
MatchState
TurnStarted
TurnResolved
ObservationResult
ValidationReport
ReplayChunk
ErrorEvent
Rules:
All messages versioned
All messages serializable
All messages replay-testable
All server outputs hashable
No client-only game truth
Phase B — Authoritative Match Server
Server owns:
match state
turn timer
submitted actions
rune execution
visibility filtering
knowledge filtering
replay recording
disconnect handling
Server loop:
Create match
Send visible snapshot
Start turn timer
Collect actions
Resolve through runtime
Persist replay event
Send filtered results
Advance turn
Hard gates:
same inputs produce same replay hash
late input rejected deterministically
disconnect does not corrupt match
invalid client packet cannot panic server
client cannot mutate hidden state
Phase C — Browser Client Shell
Client responsibilities:
connect
authenticate anonymously/dev
join match
render visible arena
show entities
show turn timer
edit rune program
submit action
display results
display observations
play replay events
Do not implement complex art yet.
Use debug visuals:
grid
tokens
panels
logs
timers
entity markers
domain indicators
Phase D — Rune Editor
The rune editor is the core UI.
Required:
keyboard-bound rune input
token grid / sequence view
library slot panel
syntax-neutral execution preview
visible cost/risk diagnostics
submission lock on timer expiry
Important:
The editor must not pretend to know full truth.
It can show observed diagnostics only.
Player-facing diagnostics should say:
known reads
known writes
observed risks
unknown listeners
previous outcomes
Not:
guaranteed damage
guaranteed success
full hidden state
Phase E — Arena Interaction
Each turn, player can:
move
inspect
cast rune program
use stick/basic attack
wait
All actions become server commands.
Client-side previews are advisory only.
Phase F — Visibility / Knowledge Layer
Server sends filtered state:
VisibleWorldSnapshot {
observed_domains,
observed_entities,
observed_environment,
known_history,
inferred_markers,
hidden_state_redactions,
}
Knowledge must be game state, not UI notes.
Client displays:
known
unknown
suspected
contradicted
newly observed
Phase G — Replay System
Every match produces:
initial seed
player inputs
turn boundaries
runtime hashes
visible outputs
trace excerpts
final hash
Browser replay consumes the same protocol stream.
CI gate:
recorded replay equals regenerated replay
browser replay event order matches server order
Phase H — Web Testing
Required test layers:
Rust protocol tests
server integration tests
browser protocol tests
Playwright end-to-end tests
replay determinism tests
fuzzed packet tests
disconnect/reconnect tests
timer edge tests
Minimum web CI gates:
1,000 simulated matches
10,000 protocol fuzz cases
100 browser E2E matches
0 server panics
0 replay hash mismatches
0 hidden-state leaks
Phase I — Vertical Slice
First playable slice:
2 players or 1 player + dummy opponent
small arena
turn timer
movement
inspection
basic attack
rune submission
multicast execution
visible consequences
replay viewer
No progression.
No accounts.
No cosmetics.
No marketplace.
No complex content.
Acceptance Criteria
Web phase is accepted only when:
A player can join a browser match.
A turn timer runs.
The player can inspect, move, attack, or cast.
Rune programs execute only on the server.
Results return as filtered observations.
Replay can reproduce the match.
Browser cannot alter hidden truth.
CI proves protocol, replay, visibility, and server authority.
Core rule:
The web game is just a playable window into the Rust universe.
It must not become a second simulation.