Files
chexit d45629ae29
build / mod (push) Failing after 22s
Fix the UI-event fuel trap on a second large raid order
The Windows log for #122 showed the mod stopping in the UI event
(fuel budget 1e9, remaining 0) with known_units <- order_raid <-
launch_wave <- ui_select: order_raid recomputed the planner snapshot
known_units() for every drone, and the snapshot itself rescanned the
whole force and the dedup list per intel entry. A second big Smart
order cost drones x intel-log x force-size inside one event.

Reproduced in actual WASM with measured per-callback fuel through the
exact ui_select(BTN_LAUNCH) handler (diagnostic guest, trigger.patch):
before, a 111-drone second order at revealed=13172/known=144 exhausted
exactly 1e9 and stopped the mod (an 11-drone order at the same state:
247805865); after, the same scenario passes with max command fuel
32946177/1e9, failures=0, and /stats at tick 2602 byte-identical.
A stacked single-point layout dies to one warhead (known=0, cheap
order), so the scenario deploys spread clusters with a moved player.

Fix: one known_units snapshot per order_raid passed to radar_strikes
and choose_target; known_units is a single O(log + force) set pass;
price_grid_on reuses its snapshot. Emitter/network targeting and
carrier choice semantics are unchanged (native equivalence test
against the former predicate; WASM checkpoint counters equal).
Limits unchanged; HD/recording untouched; wave size unrestricted.

Committed regressions: native snapshot-equivalence and
second-smart-order tests; the heavy WASM fixture now orders two Smart
raids through the wave screen's launch function (airdef preset +
airdef raid) with EW and a combat intel log, four accepted orders
asserted; the light contract covers preset and the empty-wave refusal.

Core release 195 + 8 scenarios; adapter 65 + 1 boundary + 5 scenarios;
light WASM 30 steps; heavy WASM 283 steps (tick max 182413686/300M,
command max 6939810/1e9, failures 0). Windows GUI acceptance remains
external and is not claimed.

Co-Authored-By: Kimi Code (Moonshot AI) <noreply@moonshot.cn>
2026-11-06 10:29:36 +03:00

68 lines
3.1 KiB
JSON

{
"schema": 1,
"issue": 122,
"kind": "diagnostic_guest_ui_path_comparison_not_exact_user_session",
"user_report": {
"log": "Horizon: mod airdef stopped in UI event (fuel budget 1000000000, remaining Some(0))",
"backtrace": "airdef_core::sim::ew::Sim::known_units <- sim::raid::Sim::order_raid <- airdef::AirDef::launch_wave <- horizon_mod_sdk::Mod::ui_select <- ui-events select",
"windows_session_confirmed_same_cause": false
},
"root_cause": {
"what": "order_raid recomputed the planner snapshot known_units() for every drone (choose_target), and known_units() itself rescanned the whole force and the dedup list per intel entry",
"growth": "drones x intel_log x force_size per UI event; the intel log holds every launch, EW disclosure, and radar disclosure of the last 6000 ticks",
"state_at_trap": {
"revealed_entries": 13172,
"known_alive_units": 144,
"sams_total": 172
}
},
"fix": {
"description": "one known_units snapshot per order_raid passed to radar_strikes and choose_target; known_units is a single O(R+S) set pass; price_grid_on reuses its snapshot",
"semantics": "identical planner results; native equivalence test against the former predicate; WASM checkpoint /airdef stats byte-identical before/after at tick 2602",
"limits_unchanged": true,
"wave_size_unrestricted": true,
"hd_record_untouched": true
},
"setup": {
"defenses": "40 spread clusters x 4 heavy SAMs + 12 EW = 172, player moved per deploy step",
"first_raid": "airdef wave mix 10 (111 drones, Smart, AllSides) via the diagnostic UI-path trigger",
"second_raid": "same, at tick ~2600 after the first raid is fought off",
"note": "stacked single-point layouts die to one warhead (known=0, cheap order); the trap needs a surviving force, like the user's session"
},
"before": {
"source": "e6a7000 + trigger.patch (diagnostic guest only)",
"second_order_111_drones": {
"callback": "command (the diagnostic trigger invokes the exact ui_select(BTN_LAUNCH) handler; the UI event and the command share the same 1e9 event budget)",
"max_used": 1000000000,
"budget": 1000000000,
"failures": 1,
"mod_stopped": true,
"log": "before-trap.txt"
},
"scaling_witness_11_drones_same_state": {
"max_used": 247805865,
"budget": 1000000000,
"failures": 0,
"log": "before-scaling.txt"
}
},
"after": {
"same_scenario_passed": true,
"steps": 255,
"max_command_fuel": 32946177,
"max_tick_fuel": 236581288,
"failures": 0,
"checkpoint_stats_equal_before_after": true,
"log": "after.txt"
},
"artifacts": {
"trigger_patch": "trigger.patch",
"scenario_before": "scenario-before.toml",
"scenario_after": "scenario-after.toml",
"before_guest_sha256": "6d4525cd7aaa61dbf344593f9819be1b61e06654126e9e9088e57967dc657365",
"after_guest_sha256": "c4ef7d759524eb053ccd55f0eccdcb49c91954201eb4e0ad923ee9b2828efc4e",
"scenario_before_sha256": "398d099275e396deab269601e5adbcf325ab5e0ea6b540c1d03a477d6b0963d1",
"scenario_after_sha256": "3bc27338d2e6fb433f027a0cf1afc39ff9a94e1af5840454082af6d8d15aad7c"
}
}