Sil-Q implementation

The public contract is documented in GAME_GUIDE.md. Current validation and experiment status are in LAUNCH_READINESS.md. The runtime uses silq-session-v4, silq-observation-v2 and silq-response-v1.

Isolation and native state

The game service owns the native engine, private random streams, append-only journal, request receipts and scorer. The agent container receives only public client modules, the guide/manual, and its persistent workspace. It has neither the game binary nor private state. The internal network, dropped capabilities, read-only filesystems and container limits are defined in compose/compose.yaml.

The native adapter exposes rendered screens plus player-visible status, displayed creatures, known inventory, native prompt types and drawn messages. Menu overlays, hallucination and other unavailable information are explicit. Monster membership includes native detection and memory; it does not establish current line of sight. Hidden-state and side-effect tests check the projection.

Upstream repairs are checked patches against the pinned source revision. GRADING_AUDIT.md records native command, visibility, RNG and scoring repairs. Test-only setup remains absent from the production engine.

Python architecture

Pydantic schemas validate JSON boundaries without extra fields or scalar coercion. Enums name endpoints, events, modes and trial states; dataclasses hold mutable runtime/replay state. JSON conversion occurs at persistence and transport boundaries.

Responsibility Module in silq_eval/
Public observations and responses models.py, protocol.py
Session schedule and input validation contract.py, requests.py
Native process and bounded reads native.py
HTTP framing and authentication transport.py
Journal schemas and integrity journal.py, evidence.py
Trial transitions lifecycle.py
Reconstruction and summary verification audit.py
Durable receipts and recovery durable.py, replay.py
CLI and HTTP client client.py, client_api.py
Client intent and frame history history.py
Actions, prompt guards and event projection actions.py, controls.py, presentation.py
Readable output rendering.py
Native victory and progress scoring.py, progress.py
Inspect task and protected snapshots task.py, operator.py

reconstruct returns a typed ReplayState; recovery consumes it directly. Each journal event has a schema and transition handler. Hash checks use the original JSON before normalization. Reconstructed summaries include timestamps, progress and pending operations, rather than trusting cached totals.

Input and recovery

Named actions and typed replies validate the native prompt and the latest trial/frame. Guarded key batches stop at action/prompt boundaries and report unsent keys. Raw input remains available. Acknowledgment dismisses only native message pages; it may let an unfinished native turn continue. There is no built-in combat, navigation or resting strategy.

The CLI persists intent before transmission and archives complete public frames. A durable request ID binds the entire body. Exact retries return the committed response without executing twice. Recovery replays the same random stream and compares every accepted native frame, including protected state. Mismatched sources, receipts or replay fail closed. Deadlines stay absolute across downtime.

Scoring and admission

Victory requires the native terminal escape transition and actual possession of a Silmaril. Rendered text and model claims never award a win. Depth, acquisition and ascent are independent diagnostics. Every metric shares one authenticated, finalized scoring snapshot reconstructed from accepted native observations.

Admission requires a complete evaluation, exact replay, verified model requests, complete tool results, public-view review, bound evidence and no unresolved environment failure or infrastructure limit. Under success-within-budget-v1, trial time/key exhaustion is a valid zero outcome. A protected session_expired event proves that the original session deadline was reached; only then may a partial schedule count, with unfinished/unstarted games scoring zero and earlier wins retained. Inspect time limits must match that evidence. Operator stops, cost/token limits and provider/native failures cannot become budget outcomes. An Inspect time-limit event can explain only trailing canceled generations or unfinished calls in the last tool batch; it must match protected session expiry. Earlier errors or missing results remain failures. Cancellation never invents API usage or a completed response, and the qualitative review covers its effects. complete denotes a completed evaluation; schedule_complete requires every scheduled game to have ended. Missing public frames require observation_review.py coverage naming each trial/frame exactly once, with supporting evidence. Deliberate agent summaries are distinguished from interface loss; unprinted fields are not claimed as model-visible evidence.

Experiments and reporting

experiments.py is the only dispatch path; launch.py freezes source, images, schedules, pricing and commands without making model requests. Worker locks, launch intents and authorization rechecks prevent duplicate or stale dispatch. Research readiness binds the exact plan and environment. Max additionally requires the reviewed medium gate. See README.md for templates and commands.

Time, input, retry and container budgets are frozen before dispatch. A null cost cap disables dollar-based stopping while retaining usage accounting. Resource telemetry is separate from the native outcome. Reports retain every registered attempt and compute capability statistics only for complete admitted conditions.

Current reports include depth per scheduled game and protected elapsed-time trajectories, jewel acquisition and carrying-ascent. Unstarted games have zero attainment but no trajectory. No observation accepted at or after a deadline earns progress. Model-specific pricing is frozen in each manifest: GPT-5.5's long-context uplift is session-wide; Astra's is per-request. The primary cost field is estimated_session_priced_usd; missing usage leaves the total unknown.

Historical results retain their original materials, exclusions and scores. Historical runtime and controller-specific validators are available in frozen run sources and Git history; the active runtime has no v1/v2 compatibility branches.