{ "design_version": "1.0", "status": "proposed_semantic_contract_not_existing_wire_schema", "target_architecture": { "authority": "Rust Glitch room controller", "transport": "NATS", "operator_ui": "Flutter", "game_runtime": "Godot", "persistence_proposal": "durable transactional journal and outbox with JetStream observation delivery" }, "profiles": { "guided": { "time_limit_ms": 3600000, "passes_per_station": 1, "response_window_ms": 60000, "stable_target_hold_ms": 1000, "final_ack_window_ms": 30000, "hint_1_inactivity_ms": 90000, "next_hint_interval_ms": 60000, "score_target_multiplier": 0.6, "frogger_homes": 1 }, "standard": { "time_limit_ms": 3600000, "passes_per_station": 2, "response_window_ms": 40000, "stable_target_hold_ms": 2000, "final_ack_window_ms": 20000, "hint_1_inactivity_ms": 120000, "next_hint_interval_ms": 90000, "score_target_multiplier": 1.0, "frogger_homes": 1 }, "challenge": { "time_limit_ms": 3600000, "passes_per_station": 3, "response_window_ms": 25000, "stable_target_hold_ms": 3000, "final_ack_window_ms": 12000, "hint_1_inactivity_ms": 180000, "next_hint_interval_ms": 120000, "score_target_multiplier": 1.4, "frogger_homes": 1 } }, "entities": [ { "cabinet_id": "cabinet_01", "first_state_id": "A01", "game": "pacman", "token_id": "T01", "cell_id": "CELL01", "socket_id": "SOCKET01", "status": "existing_assignment" }, { "cabinet_id": "cabinet_02", "first_state_id": "A02", "game": "galaga", "token_id": "T02", "cell_id": "CELL02", "socket_id": "SOCKET02", "status": "existing_assignment" }, { "cabinet_id": "cabinet_03", "first_state_id": "A03", "game": "tempest", "token_id": "T03", "cell_id": "CELL03", "socket_id": "SOCKET03", "status": "existing_assignment" }, { "cabinet_id": "cabinet_04", "first_state_id": "A04", "game": "missile_command", "token_id": "T04", "cell_id": "CELL04", "socket_id": "SOCKET04", "status": "existing_assignment" }, { "cabinet_id": "cabinet_05", "first_state_id": "A05", "game": "frogger", "token_id": "T05", "cell_id": "CELL05", "socket_id": "SOCKET05", "status": "proposed_assignment" }, { "cabinet_id": "cabinet_06", "first_state_id": "A06", "game": "space_invaders", "token_id": "T06", "cell_id": "CELL06", "socket_id": "SOCKET06", "status": "proposed_assignment" } ], "boss": { "cabinet_id": "cabinet_07", "id": "B07", "game_proposal": "robotron_or_bespoke_variant", "unlock": "all_six_distinct_first_state_wins" }, "durations_ms": { "charge": 30000, "passage_debounce": 300, "cell_debounce": 500, "ship_power_stable": 2000, "retry_delay": 3000, "countdown": 5000, "agent_stale": 3000, "agent_offline": 8000, "command_accept": 2000, "command_expiry": 5000, "boot_completion": 10000 }, "staffing": { "operator_count_rule": "max(1, min(party_size - 1, 6))", "calibration_concurrency": "operator_count", "solo": "assisted sequential ship/arcade interaction", "finale": "sequential station arm, group readiness, navigator commit", "solo_final_ack_window_ms": 90000 }, "event_envelope_schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Proposed Glitch normalized event envelope", "type": "object", "additionalProperties": false, "required": [ "schema_version", "event_id", "type", "room_id", "run_id", "entity_id", "source_id", "boot_id", "source_seq", "assignment_id", "occurred_at_ms", "received_at_ms", "payload" ], "properties": { "schema_version": { "type": "integer", "minimum": 0, "const": 1 }, "event_id": { "type": "string", "minLength": 1 }, "type": { "type": "string", "minLength": 1 }, "room_id": { "type": "string", "minLength": 1 }, "run_id": { "type": "string", "minLength": 1 }, "entity_id": { "type": "string", "minLength": 1 }, "source_id": { "type": "string", "minLength": 1 }, "boot_id": { "type": "string", "minLength": 1 }, "source_seq": { "type": "integer", "minimum": 0 }, "assignment_id": { "type": [ "string", "null" ] }, "occurred_at_ms": { "type": "integer", "minimum": 0 }, "received_at_ms": { "type": "integer", "minimum": 0 }, "payload": { "type": "object" }, "correlation_id": { "type": "string", "minLength": 1 }, "causation_id": { "type": "string", "minLength": 1 }, "actor_id": { "type": "string", "minLength": 1 }, "reason": { "type": "string", "minLength": 1 } } }, "room_state_example": { "schema_version": 1, "room_id": "glitch", "run_id": "example-run-001", "revision": 0, "config_hash": "EXAMPLE_REPLACE_WITH_CONTENT_HASH", "lifecycle": "READY", "phase": "BRIEFING", "outcome": null, "active_elapsed_ms": 0, "time_limit_ms": 3600000, "difficulty": "standard", "party_size": 2, "controller_epoch": 1, "seed": 42, "cabinet_first_wins": [], "cells_installed": [], "calibration_passes": {}, "launch": { "launch_epoch": 0, "armed_stations": [], "acknowledged_groups": [], "committed": false } }, "simulation_cases": [ { "id": "SIM01", "scenario": "Golden path with 6 players, standard", "assertion": "All acts, six cells and two calibration passes; one launch commit", "execution_status": "specified_not_executed" }, { "id": "SIM02", "scenario": "2 players, guided; one roaming operator", "assertion": "All six stations completed; no simultaneous multi-station human input required", "execution_status": "specified_not_executed" }, { "id": "SIM03", "scenario": "1 assisted player; sequential ship and arcade interactions", "assertion": "No deadlock; clearly assisted outcome/metadata", "execution_status": "specified_not_executed" }, { "id": "SIM04", "scenario": "8 players, challenge; six stations active", "assertion": "Unused helper never required for a guard; three passes per station", "execution_status": "specified_not_executed" }, { "id": "SIM05", "scenario": "Wrong token, repeated scan, stale historical scan", "assertion": "No credit for wrong/stale; only one authorization for correct scan", "execution_status": "specified_not_executed" }, { "id": "SIM06", "scenario": "Lose A03 twice then retry", "assertion": "No extra token needed; other wins and charge retained", "execution_status": "specified_not_executed" }, { "id": "SIM07", "scenario": "Duplicate A01 win and missing A06 win", "assertion": "Boss remains dark; unique set count stays 5", "execution_status": "specified_not_executed" }, { "id": "SIM08", "scenario": "Claw reward ACK but token delivery jam", "assertion": "Reward pending; GM hand-delivery logged; no duplicate dispense", "execution_status": "specified_not_executed" }, { "id": "SIM09", "scenario": "Boss won; passage ACK without open sensor", "assertion": "Reveal hold after 5 s; no assumed opening", "execution_status": "specified_not_executed" }, { "id": "SIM10", "scenario": "Wrong socket, duplicate cell identity, missing cell", "assertion": "Ship power guard false; explicit diagnostic per conflict", "execution_status": "specified_not_executed" }, { "id": "SIM11", "scenario": "Cell removed during calibration and countdown", "assertion": "Current wave/countdown canceled; completed passes retained; fresh IDs", "execution_status": "specified_not_executed" }, { "id": "SIM12", "scenario": "Late Ready for old challenge; Execute exactly at deadline", "assertion": "Both rejected; current wave remains consistent", "execution_status": "specified_not_executed" }, { "id": "SIM13", "scenario": "One final group late, then retry", "assertion": "Acknowledgements clear; calibration retained; launch once on valid retry", "execution_status": "specified_not_executed" }, { "id": "SIM14", "scenario": "Restart controller after durable boss win before output publish", "assertion": "Recovered outbox sends same command ID; no repeated physical release", "execution_status": "specified_not_executed" }, { "id": "SIM15", "scenario": "Agent restarts after uncertain bay release", "assertion": "No blind pulse replay; reconcile or GM inspect", "execution_status": "specified_not_executed" }, { "id": "SIM16", "scenario": "Network drop, duplicate and reordered events", "assertion": "No regression/double reward; snapshot reconciliation reaches same state", "execution_status": "specified_not_executed" }, { "id": "SIM17", "scenario": "Teddy unavailable or stale queued hint", "assertion": "Fallback text; stale hint discarded; gameplay can finish", "execution_status": "specified_not_executed" }, { "id": "SIM18", "scenario": "Pause 5 min; expire action while paused", "assertion": "Active timer frozen; expired wall-time command rejected", "execution_status": "specified_not_executed" }, { "id": "SIM19", "scenario": "Time expires in calibration; extend 5 min", "assertion": "TIME_EXPIRED then preserved phase; no automatic normal win", "execution_status": "specified_not_executed" }, { "id": "SIM20", "scenario": "Reset and inject old-run win/scan/launch", "assertion": "All rejected; fresh run remains pristine", "execution_status": "specified_not_executed" } ], "calibration_selections": { "cabinet_01": { "min": 0, "max": 3 }, "cabinet_02": { "min": 1, "max": 5 }, "cabinet_03": { "min": 0, "max": 7 }, "cabinet_04": { "min": 1, "max": 3 }, "cabinet_05": { "min": 1, "max": 4 }, "cabinet_06": { "min": 1, "max": 4 } }, "payload_schemas": { "puzzle.solved": { "type": "object", "additionalProperties": false, "properties": { "puzzle_id": { "type": "string", "minLength": 1 }, "evidence": { "type": "string", "minLength": 1 } }, "required": [ "puzzle_id", "evidence" ] }, "reward.delivered": { "type": "object", "additionalProperties": false, "properties": { "reward_id": { "type": "string", "minLength": 1 }, "evidence": { "type": "string", "minLength": 1 } }, "required": [ "reward_id", "evidence" ] }, "token.observed": { "type": "object", "additionalProperties": false, "properties": { "reader_id": { "type": "string", "minLength": 1 }, "token_id": { "type": "string", "minLength": 1 } }, "required": [ "reader_id", "token_id" ] }, "game.started": { "type": "object", "additionalProperties": false, "properties": { "attempt_id": { "type": "string", "minLength": 1 } }, "required": [ "attempt_id" ] }, "game.progress": { "type": "object", "additionalProperties": false, "properties": { "attempt_id": { "type": "string", "minLength": 1 }, "value": { "type": "integer", "minimum": 0 } }, "required": [ "attempt_id", "value" ] }, "game.won": { "type": "object", "additionalProperties": false, "properties": { "attempt_id": { "type": "string", "minLength": 1 }, "objective_id": { "type": "string", "minLength": 1 }, "value": { "type": "integer", "minimum": 0 } }, "required": [ "attempt_id", "objective_id", "value" ] }, "game.lost": { "type": "object", "additionalProperties": false, "properties": { "attempt_id": { "type": "string", "minLength": 1 }, "reason": { "type": "string", "minLength": 1 } }, "required": [ "attempt_id", "reason" ] }, "cell.observed": { "type": "object", "additionalProperties": false, "properties": { "cell_id": { "type": "string", "minLength": 1 }, "location": { "type": "string", "minLength": 1 }, "present": { "type": "boolean" } }, "required": [ "cell_id", "location", "present" ] }, "passage.observed": { "type": "object", "additionalProperties": false, "properties": { "open": { "type": "boolean" }, "sensor_id": { "type": "string", "minLength": 1 } }, "required": [ "open", "sensor_id" ] }, "calibration.ready": { "type": "object", "additionalProperties": false, "properties": { "challenge_id": { "type": "string", "minLength": 1 }, "selection": { "type": "integer", "minimum": 0 }, "stable_for_ms": { "type": "integer", "minimum": 0 } }, "required": [ "challenge_id", "selection", "stable_for_ms" ] }, "calibration.ready_revoked": { "type": "object", "additionalProperties": false, "properties": { "challenge_id": { "type": "string", "minLength": 1 }, "reason": { "type": "string", "minLength": 1 } }, "required": [ "challenge_id", "reason" ] }, "calibration.execute": { "type": "object", "additionalProperties": false, "properties": { "challenge_id": { "type": "string", "minLength": 1 } }, "required": [ "challenge_id" ] }, "launch.group_ready": { "type": "object", "additionalProperties": false, "properties": { "launch_epoch": { "type": "integer", "minimum": 0 }, "group_id": { "type": "string", "minLength": 1 } }, "required": [ "launch_epoch", "group_id" ] }, "launch.commit_requested": { "type": "object", "additionalProperties": false, "properties": { "launch_epoch": { "type": "integer", "minimum": 0 } }, "required": [ "launch_epoch" ] }, "teddy.playback_status": { "type": "object", "additionalProperties": false, "properties": { "cue_id": { "type": "string", "minLength": 1 }, "status": { "enum": [ "accepted", "started", "completed", "failed" ] } }, "required": [ "cue_id", "status" ] } }, "payload_validation": "Validate envelope, then select payload schema by event.type. Reject unknown event types unless separately defined as controller-internal events. Apply semantic guards after schema validation.", "command_envelope_schema": { "type": "object", "additionalProperties": false, "properties": { "schema_version": { "const": 1 }, "command_id": { "type": "string", "minLength": 1 }, "type": { "type": "string", "minLength": 1 }, "room_id": { "type": "string", "minLength": 1 }, "run_id": { "type": "string", "minLength": 1 }, "target_entity": { "type": "string", "minLength": 1 }, "target_boot_id": { "type": "string", "minLength": 1 }, "controller_epoch": { "type": "integer", "minimum": 0 }, "expected_revision": { "type": "integer", "minimum": 0 }, "expires_at_ms": { "type": "integer", "minimum": 0 }, "payload": { "type": "object" } }, "required": [ "schema_version", "command_id", "type", "room_id", "run_id", "target_entity", "target_boot_id", "controller_epoch", "expected_revision", "expires_at_ms", "payload" ] }, "command_result_schema": { "type": "object", "additionalProperties": false, "properties": { "command_id": { "type": "string", "minLength": 1 }, "status": { "enum": [ "ACCEPTED", "REJECTED", "COMPLETED", "FAILED", "DELIVERY_UNKNOWN" ] }, "reason_code": { "type": "string", "minLength": 1 }, "snapshot_revision": { "type": "integer", "minimum": 0 } }, "required": [ "command_id", "status", "reason_code", "snapshot_revision" ] }, "event_example": { "schema_version": 1, "event_id": "evt-example-001", "type": "game.won", "room_id": "glitch", "run_id": "example-run-001", "entity_id": "cabinet_01", "source_id": "agent-cabinet-01", "boot_id": "boot-example-001", "source_seq": 14, "assignment_id": "assignment-a01-001", "occurred_at_ms": 1792260000000, "received_at_ms": 1792260000010, "payload": { "attempt_id": "attempt-a01-001", "objective_id": "score_500", "value": 500 } } }