"""In-memory per-run state. Suspicion is server-authoritative and lives here, keyed by runId. For v1 single-player this is process memory; a run is (re)created from a stored case by Case ID, so share/resume just needs the Case ID. Persisting runs to disk is a later enhancement. """ from __future__ import annotations import uuid from dataclasses import dataclass, field from .golden import load_golden @dataclass class RunState: run_id: str case_id: str suspicion: dict[str, int] = field(default_factory=dict) _RUNS: dict[str, RunState] = {} def create_run(case_id: str) -> RunState: """Create a run seeded with the case's baseline suspicion.""" golden = load_golden(case_id) suspicion = {s["id"]: int(s["suspicion"]) for s in golden["suspects"]} run = RunState(run_id=uuid.uuid4().hex, case_id=case_id, suspicion=suspicion) _RUNS[run.run_id] = run return run def get_run(run_id: str) -> RunState | None: return _RUNS.get(run_id)