--- id: PLN-0142 ticket: foreground-stack-game-pause-shell-vm-backed title: Deliver Game Lifecycle Events To VM Runtime status: open created: 2026-07-04 ref_decisions: [DEC-0037] tags: [runtime, os, lifecycle, shell, game, vm, foreground, architecture] --- ## Briefing `DEC-0037` requires pause/resume to be Game-visible lifecycle events. The current implementation records `GameLifecycleEvent` values in SystemOS, but no runtime or VM execution path consumes them. Tests currently prove that the OS queue contains events, not that the Game/runtime can observe them before suspension or after resume. ## Objective Deliver Game lifecycle pause/resume events from SystemOS into the VM runtime boundary in a deterministic, testable way, without exposing Home as guest pad input or a userland syscall. ## Dependencies - Source decision: `DEC-0037`. - Fixes the lifecycle event delivery gap found after `PLN-0140` and `PLN-0141`. - `PLN-0143` depends on this plan if it needs to prove that the pause event is consumed before the pause budget expires. ## Scope Included: - Define the runtime-facing lifecycle event delivery API for `Pause` and `ResumeForeground`. - Move events from the SystemOS queue into the VM/runtime tick boundary. - Make delivered events observable in tests without creating a broad app event system. - Preserve the distinction between lifecycle pause and debugger pause. - Ensure events are delivered only to the resident Game task they target. Excluded: - No guest Home input, pad field, intrinsic, or syscall. - No general userland event bus. - No background execution while suspended. - No new Shell lifecycle event model. ## Non-Goals - Do not implement Game-to-Game switching. - Do not change renderer ownership policy except where tests need to assert lifecycle event ordering. - Do not add wall-clock timers or asynchronous callbacks. ## Execution Method 1. Add a narrow VM runtime lifecycle inbox. - What changes: introduce a small data structure for pending/delivered Game lifecycle events in `VirtualMachineRuntime`. - How it changes: add methods such as `queue_game_lifecycle_events`, `take_delivered_game_lifecycle_events`, or a more idiomatic local name that preserves deterministic frame-boundary delivery. - File(s): `crates/console/prometeu-system/src/services/vm_runtime/mod.rs`, `crates/console/prometeu-system/src/services/vm_runtime/tick.rs`, and focused tests under `crates/console/prometeu-system/src/services/vm_runtime/`. 2. Route SystemOS events into the VM facade before ticking. - What changes: `VmFacade::tick` must drain lifecycle events from SystemOS and pass only events targeted at the currently running resident Game into the VM runtime lifecycle inbox. - How it changes: use the existing `LifecycleFacade::take_game_lifecycle_events` or replace it with an equivalent internal method if borrowing requires a cleaner API. Do not leave events only observable through `pending_game_lifecycle_events`. - File(s): `crates/console/prometeu-system/src/os/facades/vm.rs`, `crates/console/prometeu-system/src/os/facades/lifecycle.rs`. 3. Expose deterministic test visibility. - What changes: tests must be able to assert that `Pause` and `ResumeForeground` reached the VM runtime boundary. - How it changes: add test-only or public diagnostic accessors on `VmFacade`/`VirtualMachineRuntime` for delivered lifecycle events, scoped to lifecycle validation rather than a guest ABI. - File(s): `crates/console/prometeu-system/src/os/facades/vm.rs`, `crates/console/prometeu-system/src/services/vm_runtime/tests.rs`. 4. Update firmware tests to assert delivery, not only queue presence. - What changes: existing firmware tests that inspect `pending_game_lifecycle_events` should assert VM-runtime delivery at the tick boundary. - How it changes: after a Game pause/resume flow, verify that the VM/runtime observed the lifecycle event in order. - File(s): `crates/console/prometeu-firmware/src/firmware/firmware.rs`. ## Acceptance Criteria - [ ] `Pause` is moved from SystemOS into the VM runtime boundary before suspension is allowed to complete. - [ ] `ResumeForeground` is moved into the VM runtime boundary before the Game is considered visually restored. - [ ] Tests fail if events remain only in `SystemOS.game_lifecycle_events`. - [ ] Lifecycle event delivery does not mutate `InputSignals`. - [ ] Debugger pause remains separate from lifecycle pause. ## Tests - Unit tests in `prometeu-system` proving VM runtime lifecycle event delivery and drain semantics. - Firmware tests proving Home request delivers `Pause` to the VM/runtime before suspension. - Firmware tests proving resident Game resume delivers `ResumeForeground` before Game foreground restoration. - Run `cargo test -p prometeu-system`. - Run `cargo test -p prometeu-firmware`. - Run `discussion validate`. ## Affected Artifacts - `crates/console/prometeu-system/src/os/facades/vm.rs` - `crates/console/prometeu-system/src/os/facades/lifecycle.rs` - `crates/console/prometeu-system/src/services/vm_runtime/mod.rs` - `crates/console/prometeu-system/src/services/vm_runtime/tick.rs` - `crates/console/prometeu-firmware/src/firmware/firmware.rs`