extends SceneTree const FOURTEEN_DAYS_MINUTES := 14 * SimulationKernel.MINUTES_PER_DAY const RUNTIME_SNAPSHOT_VERSION := 8 var _checks := 0 var _failures := 0 func _initialize() -> void: call_deferred("_run") func _run() -> void: print("MVP: production Operations acceptance") _test_waiting_choice_and_command_exactly_once() _test_twenty_four_hour_actual_tick_smoke() _test_full_partial_payroll_bankruptcy_and_v8_tamper() _test_fourteen_day_boundary_snapshot_determinism() await process_frame if _failures == 0: print("PASS: %d checks" % _checks) else: push_error("FAIL: %d of %d checks failed" % [_failures, _checks]) quit(_failures) func _new_fixture(seed: int, enable_operations := true) -> Dictionary: var clock: Variant = load("res://autoload/game_clock.gd").new() var state: Variant = load("res://autoload/game_state.gd").new() var runtime: Variant = load("res://autoload/simulation_runtime.gd").new() clock.reset(1, 6, 0) state.reset() var initialized: Dictionary = runtime.initialize(clock, state, seed) clock.set_paused(true) _expect(bool(initialized.get(&"valid", false)), "fixture Runtime initializes") var initial_snapshot: Dictionary = runtime.create_snapshot() _expect( int(initial_snapshot[&"systems"][&"runtime"].get( &"runtime_schema_version", -1 )) == RUNTIME_SNAPSHOT_VERSION, "fixture emits Runtime snapshot schema v8" ) if enable_operations: var enabled: Dictionary = runtime.enable_production_operations() _expect(bool(enabled.get(&"ok", false)), "fixture enables production Operations") return {&"clock": clock, &"state": state, &"runtime": runtime} func _free_fixture(fixture: Dictionary) -> void: var runtime: Variant = fixture.get(&"runtime") var clock: Variant = fixture.get(&"clock") var state: Variant = fixture.get(&"state") if runtime != null: runtime.free() if clock != null: clock.free() if state != null: state.free() # Long acceptance slices deliberately exercise the production Operations # adapter without claiming to execute unrelated actor AI on all 20,160 minutes. # Aggregate clocks are aligned solely to preserve the Runtime transaction # precondition; the separate 24-hour smoke above covers the actual Tick pipeline. # One final rich snapshot (and the midpoint restore) is the Operations oracle. func _advance_operations_boundary_slice(fixture: Dictionary, amount: int) -> int: var clock: Variant = fixture[&"clock"] var runtime: Variant = fixture[&"runtime"] var advanced := 0 while advanced < amount: if runtime.operations_coordinator != null \ and runtime.operations_coordinator.is_terminal(): break # Operations has no recurring boundary finer than 30 minutes. The # coordinator still performs its own unthinned internal minute traversal; # unrelated Runtime AI is intentionally outside this accelerated oracle. var step := mini(30, amount - advanced) var target: int = clock.absolute_minute + step clock.absolute_minute = target clock.call("_sync_calendar_fields") clock.snapshot_version += step runtime.call("_advance_operations_time", target) if bool(runtime.get_operations_report().get(&"runtime_failure_latched", false)): break if runtime.operations_coordinator.is_terminal(): # A terminal daily close commits TIME_BOUNDARIES and deliberately skips # the Runtime suffix; its other aggregates therefore remain at X - 1. _align_operations_fixture_clocks(runtime, target - 1) advanced += step break # These acceptance fixtures contain no Facilities, logistics, raids, or # Staff tasks. Their clocks are aligned for Operations cross-link checks; # their skipped actor/Shift behavior is explicitly outside this fast oracle. _align_operations_fixture_clocks(runtime, target) advanced += step return advanced func _align_operations_fixture_clocks(runtime: Variant, minute: int) -> void: runtime.inventory_service.current_minute = minute runtime.facility_service.current_minute = minute runtime.kitchen_production.current_minute = minute runtime.guest_service.current_minute = minute runtime.staff_service.current_minute = minute runtime.authority_service.current_minute = minute runtime.defense_service.current_minute = minute runtime.construction_service.current_minute = minute runtime.excavation_service.current_minute = minute # This accelerated oracle owns no cars or rides; update its empty transport # aggregate through the public snapshot validator instead of a private clock. var transport_snapshot: Dictionary = runtime.elevators.create_snapshot() if not (transport_snapshot[&"shafts"] as Array).is_empty() or not (transport_snapshot[&"trips"] as Array).is_empty(): _expect(false, "accelerated Operations oracle cannot skip live elevator movement") return transport_snapshot[&"current_minute"] = minute if not runtime.elevators.restore_snapshot(transport_snapshot): _expect(false, "empty transport clock aligns through validated snapshot restore") func _operations_slice_is_healthy(fixture: Dictionary) -> bool: var runtime: Variant = fixture[&"runtime"] var report: Dictionary = runtime.get_operations_report() var foreground: EventInstance = runtime.event_service.get_foreground_instance() return not bool(report.get(&"runtime_failure_latched", true)) \ and int(report.get(&"deferred_runtime_minute", -2)) == -1 \ and not runtime.operations_coordinator.pause_requested \ and not runtime.operations_coordinator.is_terminal() \ and not runtime.operations_coordinator.is_external_quarantined() \ and (foreground == null or foreground.state != EventInstance.State.WAITING_CHOICE) func _test_waiting_choice_and_command_exactly_once() -> void: var fixture := _new_fixture(73_001) var runtime: Variant = fixture[&"runtime"] var clock: Variant = fixture[&"clock"] var state: Variant = fixture[&"state"] var queued: CommandResult = runtime.event_service.enqueue_candidate( &"relationship.threshold", [], clock.absolute_minute, {&"deduplication_key": &"operations-acceptance-choice"} ) var started: CommandResult = runtime.event_service.start_next_event( clock.absolute_minute, {} ) _expect( queued.is_success() and started.is_success() and bool(started.details.get(&"waiting_for_choice", false)), "foreground Event enters WAITING_CHOICE" ) clock.set_paused(false) var before_choice_minute: int = clock.absolute_minute clock.advance_minutes(5) var foreground: EventInstance = runtime.event_service.get_foreground_instance() _expect( clock.paused and clock.absolute_minute == before_choice_minute + 1, "WAITING_CHOICE pauses at the first committed minute and stops catch-up" ) _expect( foreground != null and foreground.state == EventInstance.State.WAITING_CHOICE, "paused foreground ownership remains intact" ) if foreground != null: var choice_result: CommandResult = runtime.submit_command( &"submit_event_choice", { &"event_instance_id": foreground.event_instance_id, &"choice_instance_id": foreground.choice_instance_id, &"choice_id": &"acknowledge", }, &"player", foreground.event_instance_id, 100, -1, &"operations.acceptance.choice" ) _expect( choice_result.is_success() and runtime.event_service.get_foreground_instance() == null and not clock.paused, "submitting the stable Choice token resolves the Event and resumes time" ) clock.set_paused(true) var gold_before: int = state.get_resource(&"gold") var first: CommandResult = runtime.submit_command( &"change_resources", {&"deltas": {&"gold": 17}}, &"player", &"", 50, -1, &"operations.acceptance.exactly-once" ) var gold_after_first: int = state.get_resource(&"gold") var retry: CommandResult = runtime.submit_command( &"change_resources", {&"deltas": {&"gold": 17}}, &"player", &"", 50, -1, &"operations.acceptance.exactly-once" ) _expect( first.is_success() and gold_after_first == gold_before + 17, "first public command commits its resource delta once" ) _expect( not retry.is_success() and retry.code == CommandResult.Code.DUPLICATE_IDEMPOTENCY_KEY and state.get_resource(&"gold") == gold_after_first, "transport retry with the same idempotency key cannot apply twice" ) var command_snapshot: Dictionary = runtime.create_snapshot() _expect( runtime.restore_snapshot(command_snapshot), "command history survives an exact v8 snapshot round trip" ) var restored_retry: CommandResult = runtime.submit_command( &"change_resources", {&"deltas": {&"gold": 17}}, &"player", &"", 50, -1, &"operations.acceptance.exactly-once" ) _expect( not restored_retry.is_success() and restored_retry.code == CommandResult.Code.DUPLICATE_IDEMPOTENCY_KEY and state.get_resource(&"gold") == gold_after_first, "restored idempotency history still rejects the same command" ) _free_fixture(fixture) func _test_twenty_four_hour_actual_tick_smoke() -> void: var fixture := _new_fixture(73_004) var runtime: Variant = fixture[&"runtime"] var clock: Variant = fixture[&"clock"] var start_minute: int = clock.absolute_minute clock.advance_minutes(SimulationKernel.MINUTES_PER_DAY) _expect( clock.absolute_minute - start_minute == SimulationKernel.MINUTES_PER_DAY, "actual SimulationKernel ticks complete an uninterrupted 24-hour smoke slice" ) _expect( _operations_slice_is_healthy(fixture) and runtime.operations_coordinator.current_minute == clock.absolute_minute and runtime.operations_coordinator.get_day_summaries().size() == 1, "24-hour actual-tick slice has no Choice, deferred minute, quarantine, or terminal stop" ) var snapshot: Dictionary = runtime.create_snapshot() _expect( runtime.restore_snapshot(snapshot) and runtime.latest_digest == SimulationDigest.compute(snapshot), "24-hour actual-tick v8 snapshot round trip is exact" ) _free_fixture(fixture) func _test_full_partial_payroll_bankruptcy_and_v8_tamper() -> void: var fixture := _new_fixture(73_002, false) var runtime: Variant = fixture[&"runtime"] var clock: Variant = fixture[&"clock"] var state: Variant = fixture[&"state"] var candidate: Dictionary = runtime.get_mvp_staff_candidate_payload(&"staff_akane") var daily_wage := int(candidate[&"options"][&"daily_wage"]) var hired: CommandResult = runtime.submit_command( &"hire_staff_candidate", {&"candidate_id": &"staff_akane", &"current_cell": Vector3i.ZERO}, &"player", &"staff_akane", 80, -1, &"operations.acceptance.hire" ) _expect(hired.is_success() and daily_wage > 50, "payroll fixture hires one wage-bearing Staff member") var enabled: Dictionary = runtime.enable_production_operations() _expect(bool(enabled.get(&"ok", false)), "payroll fixture enables Operations after the pre-opening hire") var full_advanced := _advance_operations_boundary_slice( fixture, SimulationKernel.MINUTES_PER_DAY ) var full: Dictionary = runtime.staff_service.get_payroll_settlement(&"payroll-day-00000001") _expect( full_advanced == SimulationKernel.MINUTES_PER_DAY and _operations_slice_is_healthy(fixture) and clock.absolute_minute == SimulationKernel.MINUTES_PER_DAY + 6 * 60 and int(full.get(&"new_wages_total", -1)) == daily_wage and int(full.get(&"paid_total", -1)) == daily_wage and int(full.get(&"unpaid_after_total", -1)) == 0, "Day 1 payroll is paid in full and closes at exactly 06:00" ) var cash_now: int = runtime.economy_service.get_balance(runtime.PLAYER_CASH_ACCOUNT) var drained: CommandResult = runtime.submit_command( &"change_resources", {&"deltas": {&"gold": -(cash_now - 50)}}, &"player", &"", 90, -1, &"operations.acceptance.cash-drain" ) _expect( drained.is_success() and runtime.economy_service.get_balance(runtime.PLAYER_CASH_ACCOUNT) == 50, "fixture leaves exactly 50 Gold for a deterministic partial payroll" ) var partial_advanced := _advance_operations_boundary_slice( fixture, SimulationKernel.MINUTES_PER_DAY ) var partial: Dictionary = runtime.staff_service.get_payroll_settlement(&"payroll-day-00000002") _expect( partial_advanced == SimulationKernel.MINUTES_PER_DAY and _operations_slice_is_healthy(fixture) and clock.absolute_minute == 2 * SimulationKernel.MINUTES_PER_DAY + 6 * 60 and int(partial.get(&"new_wages_total", -1)) == daily_wage and int(partial.get(&"paid_total", -1)) == 50 and int(partial.get(&"unpaid_after_total", -1)) == daily_wage - 50, "Day 2 payroll pays available Gold only and carries exact arrears" ) var terminal_advanced := _advance_operations_boundary_slice( fixture, 2 * SimulationKernel.MINUTES_PER_DAY ) var coordinator: OperationsCoordinator = runtime.operations_coordinator var last_three_negative := true for day in [2, 3, 4]: var summary: Dictionary = coordinator.get_day_summary(day) last_three_negative = last_three_negative \ and int(summary.get(&"net_profit", 0)) < 0 \ and int((summary.get(&"settlement", {}) as Dictionary).get( &"arrears_total", 0 )) > 0 _expect( terminal_advanced == 2 * SimulationKernel.MINUTES_PER_DAY and clock.absolute_minute == 4 * SimulationKernel.MINUTES_PER_DAY + 6 * 60 and last_three_negative and coordinator.get_consecutive_insolvency_count() == 3 and coordinator.get_terminal_state() == &"BANKRUPT", "three consecutive negative closes with arrears enter BANKRUPT at the third boundary" ) var terminal_snapshot: Dictionary = runtime.create_snapshot() var terminal_digest := SimulationDigest.compute(terminal_snapshot) _expect( runtime.restore_snapshot(terminal_snapshot), "BANKRUPT terminal v8 snapshot restores without clearing terminal state" ) clock.advance_minutes(180) _expect( clock.absolute_minute == 4 * SimulationKernel.MINUTES_PER_DAY + 6 * 60 and SimulationDigest.compute(runtime.create_snapshot()) == terminal_digest, "BANKRUPT is terminal: later time requests are exact no-ops" ) _expect( not bool(runtime.acknowledge_operations_pause().get(&"ok", true)), "BANKRUPT cannot be acknowledged away" ) _assert_v8_tamper_rejected( runtime, terminal_snapshot, func(tampered: Dictionary) -> void: tampered[&"systems"][&"runtime"][&"operations"][&"personal_action_points"] = 99, "v8 rejects an out-of-range Operations action-point total" ) _assert_v8_tamper_rejected( runtime, terminal_snapshot, func(tampered: Dictionary) -> void: tampered[&"systems"][&"runtime"][&"next_command_id"] = int( tampered[&"systems"][&"runtime"][&"next_command_id"] ) + 1, "v8 rejects command high-water gaps" ) _assert_v8_tamper_rejected( runtime, terminal_snapshot, func(tampered: Dictionary) -> void: var accepted: Array = tampered[&"systems"][&"runtime"][&"command_queue"][&"accepted"] if not accepted.is_empty(): accepted[0][&"idempotency_key"] = &"tampered.accepted.key", "v8 rejects accepted-command/idempotency cross-link tampering" ) _assert_v8_tamper_rejected( runtime, terminal_snapshot, func(tampered: Dictionary) -> void: var summaries: Array = tampered[&"systems"][&"runtime"][&"operations"][&"coordinator"][&"day_summaries"] summaries[0][&"category_totals"][&"wages"] = int( summaries[0][&"category_totals"][&"wages"] ) + 1, "v8 rejects DaySummary/payroll wage reconciliation tampering" ) _assert_v8_tamper_rejected( runtime, terminal_snapshot, func(tampered: Dictionary) -> void: tampered[&"systems"][&"runtime"][&"unexpected_v8_field"] = true, "v8 rejects unknown Runtime fields" ) _assert_v8_tamper_rejected( runtime, terminal_snapshot, func(tampered: Dictionary) -> void: tampered[&"systems"][&"runtime"][&"operations"][&"coordinator"][&"unexpected_field"] = true, "v8 rejects unknown Coordinator fields" ) _free_fixture(fixture) func _assert_v8_tamper_rejected( runtime: Variant, canonical: Dictionary, mutator: Callable, label: String ) -> void: var before: Dictionary = runtime.create_snapshot() var tampered: Dictionary = canonical.duplicate(true) mutator.call(tampered) var rejected: bool = not runtime.restore_snapshot(tampered) _expect(rejected and runtime.create_snapshot() == before, label + " atomically") func _test_fourteen_day_boundary_snapshot_determinism() -> void: var seed := 73_003 var continuous := _new_fixture(seed) var continuous_clock: Variant = continuous[&"clock"] var continuous_runtime: Variant = continuous[&"runtime"] var continuous_start: int = continuous_clock.absolute_minute var first_advanced := _advance_operations_boundary_slice( continuous, FOURTEEN_DAYS_MINUTES / 2 ) var midpoint: Dictionary = continuous_runtime.create_snapshot() _expect( first_advanced == FOURTEEN_DAYS_MINUTES / 2 and continuous_clock.absolute_minute == continuous_start + FOURTEEN_DAYS_MINUTES / 2 and _operations_slice_is_healthy(continuous), "boundary-accelerated midpoint is captured after seven healthy days" ) var second_advanced := _advance_operations_boundary_slice( continuous, FOURTEEN_DAYS_MINUTES / 2 ) var continuous_snapshot: Dictionary = continuous_runtime.create_snapshot() var continuous_digest := SimulationDigest.compute(continuous_snapshot) _expect( first_advanced + second_advanced == FOURTEEN_DAYS_MINUTES and continuous_clock.absolute_minute - continuous_start == FOURTEEN_DAYS_MINUTES and _operations_slice_is_healthy(continuous), "continuous boundary-accelerated Operations advances exactly 14 days = 20,160 minutes" ) _expect( continuous_runtime.operations_coordinator.get_day_summaries().size() == 14, "continuous boundary run commits all fourteen daily closes" ) var resumed := _new_fixture(seed, false) var resumed_clock: Variant = resumed[&"clock"] var resumed_runtime: Variant = resumed[&"runtime"] var restored: bool = resumed_runtime.restore_snapshot(midpoint) _expect(restored, "fresh Runtime restores the enabled v8 midpoint snapshot") var resumed_advanced := 0 if restored: resumed_advanced = _advance_operations_boundary_slice( resumed, FOURTEEN_DAYS_MINUTES / 2 ) var resumed_snapshot: Dictionary = resumed_runtime.create_snapshot() _expect( restored and resumed_advanced == FOURTEEN_DAYS_MINUTES / 2 and resumed_clock.absolute_minute == 6 * 60 + FOURTEEN_DAYS_MINUTES and _operations_slice_is_healthy(resumed), "restored boundary-accelerated Operations completes seven healthy days" ) _expect( restored and SimulationDigest.compute(resumed_snapshot) == continuous_digest and resumed_snapshot == continuous_snapshot, "continuous and midpoint-restored 14-day boundary runs have identical snapshot and Digest" ) _free_fixture(continuous) _free_fixture(resumed) func _expect(condition: bool, label: String) -> void: _checks += 1 if condition: print(" ✓ %s" % label) return _failures += 1 push_error(" ✗ %s" % label)