prometeu-runtime/discussion/workflow/plans/PLN-0143-guarantee-cooperative-pause-budget-tick-before-suspension.md
2026-07-04 13:24:08 +01:00

5.1 KiB

id ticket title status created ref_decisions tags
PLN-0143 foreground-stack-game-pause-shell-vm-backed Guarantee Cooperative Pause Budget Tick Before Suspension done 2026-07-04
DEC-0037
runtime
os
lifecycle
shell
game
vm
foreground
architecture

Briefing

DEC-0037 requires a Game-visible Paused event followed by a bounded cooperative reaction budget before SystemOS imposes Suspended. The current implementation uses a one-tick budget and advances it before vm.tick in GameRunningStep, so the Game can be suspended without any runtime tick in which it could observe or react to pause.

Objective

Guarantee at least one deterministic VM/runtime delivery point for the Game to observe pause before forced suspension, while preserving SystemOS authority to suspend the Game after the budget.

Dependencies

  • Source decision: DEC-0037.
  • Should be executed after or together with PLN-0142, because budget tests must prove delivered lifecycle events, not only queued OS events.

Scope

Included:

  • Fix pause budget ordering so the pause budget cannot expire before the VM runtime has a delivery point for Pause.
  • Define the budget in deterministic machine ticks/frames, not wall-clock time.
  • Ensure a Game receives no normal gameplay ticks after it reaches PausedSuspended.
  • Preserve the existing forced-suspension authority when the budget expires.
  • Update tests that currently assert no VM tick occurs immediately after Home.

Excluded:

  • No guest-controlled cancellation of suspension.
  • No background execution after suspension.
  • No extension of the pause budget based on host timing.
  • No direct visual-return behavior; render restore gating remains covered by the existing render boundary work.

Non-Goals

  • Do not add a general scheduler.
  • Do not make pause cooperation mandatory for suspension.
  • Do not conflate lifecycle pause with debugger pause.

Execution Method

  1. Redefine pause budget state transitions.

    • What changes: ResidentGameState::PauseRequested must represent a state in which one or more delivery ticks remain before PausedSuspended.
    • How it changes: adjust ForegroundStack::advance_pause_budget or split it into explicit methods such as mark_pause_delivered and advance_pause_budget_after_delivery.
    • File(s): crates/console/prometeu-system/src/services/foreground.rs.
  2. Move budget advancement after lifecycle delivery.

    • What changes: GameRunningStep::on_update must not suspend before the VM runtime has a chance to receive and process the pause lifecycle event.
    • How it changes: reorder the GameRunning update so the event delivery path runs first, then the budget is advanced, and only a subsequent eligible boundary can force suspension.
    • File(s): crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs, crates/console/prometeu-system/src/os/facades/vm.rs.
  3. Preserve no-tick-after-suspended behavior.

    • What changes: once ResidentGameState::PausedSuspended and TaskState::Suspended are reached, the Game must not receive normal ticks, normal input, or frame pacing.
    • How it changes: keep the existing early transition to Hub after suspension expires, but ensure it occurs after the cooperative pause window rather than before it.
    • File(s): crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs.
  4. Update tests to match the corrected semantics.

    • What changes: tests must stop asserting that the first tick after Home does zero VM work purely because Home was requested.
    • How it changes: assert that the pause event was delivered during the cooperative window, then assert that a later deterministic tick forces suspension and no further Game ticks occur.
    • File(s): crates/console/prometeu-firmware/src/firmware/firmware.rs, crates/console/prometeu-system/src/os/system_os.rs.

Acceptance Criteria

  • A Game receives a deterministic pause delivery point before SystemOS suspends it.
  • SystemOS still suspends the Game after the bounded budget even if the Game does not cooperate.
  • A suspended Game receives no normal gameplay ticks, normal Game input, or frame pacing.
  • Tests prove the order: Home request -> pause delivery -> budget expiry -> suspension.
  • Debugger pause behavior is unchanged.

Tests

  • Unit tests in prometeu-system for pause budget transitions.
  • Firmware tests for non-cooperative forced suspension after at least one delivered pause boundary.
  • Regression tests proving suspended Game tick count does not advance.
  • Run cargo test -p prometeu-system foreground lifecycle.
  • Run cargo test -p prometeu-firmware pause.
  • Run discussion validate.

Affected Artifacts

  • crates/console/prometeu-system/src/services/foreground.rs
  • crates/console/prometeu-system/src/os/facades/lifecycle.rs
  • crates/console/prometeu-system/src/os/facades/vm.rs
  • crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs
  • crates/console/prometeu-firmware/src/firmware/firmware.rs