prometeu-runtime/discussion/lessons/DSC-0041-foreground-stack-game-pause-shell-vm-backed/LSN-0052-foreground-ownership-and-vm-session-ownership-are-separate.md
bQUARKz 6dc8cb5372
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/pr-master This commit looks good
VM Context Ownership for Resident Game and VM-Backed Shell
2026-07-05 00:36:15 +01:00

6.5 KiB

id ticket title created tags
LSN-0052 foreground-stack-game-pause-shell-vm-backed Foreground Ownership and VM Session Ownership Are Separate 2026-07-05
runtime
os
lifecycle
shell
game
vm
foreground
architecture

LSN-0052: Foreground Ownership and VM Session Ownership Are Separate

Context

DSC-0041 closed the Game -> Home/Shell -> same Game lifecycle for the first runtime implementation that supports both native Shell apps and VM-backed Shell apps. The important architectural shift was not only pausing the Game. The runtime also had to stop treating one firmware-owned VM as the place where all guest execution state lives.

The final model separates two questions:

  • Who owns the foreground visual/input authority right now?
  • Which VM-backed process owns a mutable VM execution context?

Foreground ownership is global SystemOS policy. VM execution state belongs to a session associated with a task/process. A suspended resident Game is not a saved snapshot and not a special global VM. It is a live VM session that is temporarily ineligible for normal foreground ticks, input, frame pacing, and render publication.

Key Decisions

Foreground Stack and Game Pause Contract

What: PROMETEU uses a single foreground owner in v1. Hub/Home is the root Shell owner, a Game may remain resident, and one foreground Shell app may run in front of the resident Game. Pressing desktop Esc is a host/SystemOS Home request, not guest input.

Why: This preserves console-like navigation without turning the runtime into a general multitasking scheduler. It lets the system pause and suspend a Game, run Hub or Shell, then resume the same Game deterministically.

Trade-offs: The model intentionally rejects multiple resident Games, direct Shell-to-Game return, background execution, and Game-to-Game switching in v1. Those features remain future work, but the lifecycle structure now has a place to add them.

VM Session Ownership for VM-Backed Processes

What: VM-backed mutable execution state is owned by VM sessions. A VM-backed Game and a VM-backed Shell never share the same VM, stack, heap, PC, open handles, cartridge identity, or VM-scoped runtime state.

Why: A single firmware-owned VM cannot represent a suspended resident Game and a foreground VM Shell at the same time. Loading the Shell into that global VM would overwrite the Game context that the lifecycle model says is resident.

Trade-offs: Session ownership is more explicit than one global VM, but it keeps the model simpler than snapshot/restore. It also prepares the runtime for future background-capable sessions without committing to background scheduling yet.

Patterns and Algorithms

Pause Is Cooperative, Suspension Is OS Authority

The Game receives lifecycle events such as pause and resume, but the OS owns the actual scheduling state. If the Game does not cooperate within the bounded pause budget, SystemOS can suspend it anyway. On resume, the Game receives a foreground restore event and may still keep its internal pause screen while it synchronizes.

This distinction prevents userland from owning system navigation. The Game may observe and react. It cannot veto Home.

Foreground Owner Is Not the Same as Tick Eligibility

Foreground ownership controls input, visual authority, render ownership, and normal frame pacing. Tick eligibility controls whether a VM session may execute. In v1, only the foreground VM session receives normal ticks, and the resident Game does not tick while Shell or Hub is foreground.

The important design detail is that the data model does not assume this must be true forever. Sessions can later become background-eligible without changing who owns render/input foreground.

VM Sessions Are the Unit of Mutable Guest State

Each VM-backed task/process maps to a VmSession. The session owns the VM, runtime state, session-scoped filesystem state, open file handles, next handle allocation, cartridge identity, lifecycle delivery state, and debug state.

Cartridge loading creates or reuses a VM session through SystemOS session services. Firmware orchestrates macro states such as LoadCartridge, GameRunning, HubHome, and ShellRunning, but it no longer owns a canonical guest VM.

Debugger and Host Inspection Must Follow the Active Session

Host debugging must inspect and mutate the active session VM, not a transitional global VM. PC, operand stack, breakpoints, debug-step execution, cartridge identity, and breakpoint-hit events all need to resolve through active session state.

This keeps debugger behavior aligned with actual execution. A debugger that observes a different VM than the scheduler ticks is worse than no debugger: it creates false confidence and hides lifecycle bugs.

Operational Failures Should Cross Facades as Typed Errors

Session creation and loading are operational boundaries. Missing task, missing process, duplicate VM session, missing VM session during initialization, and foreground Shell rejection should be typed errors. Firmware can then choose a controlled crash report, a launch rejection, or a logged no-transition outcome.

Panics are reserved for test/setup wrappers or impossible internal invariants that have already been proven by prior checks.

Pitfalls

  • Do not use a global VM as a compatibility bridge after session ownership is introduced. It will eventually become stale or contradictory.
  • Do not let Home/SystemOS be guest input. It changes OS authority, so it must bypass guest pad state.
  • Do not present old frames after foreground ownership changes. Render ownership and epoch validation are part of lifecycle correctness, not renderer polish.
  • Do not model pause and suspension as the same state. Pause is visible to the Game; suspension is the scheduler mechanism.
  • Do not encode v1 limits such as one resident Game or one foreground Shell by collapsing storage into one VM. Express those limits as lifecycle/session policy.
  • Do not let debugger state drift from scheduler state. The debugger must use the same active session as normal execution.

Takeaways

  • Foreground ownership is global policy; VM execution state is session-owned.
  • A suspended Game is a preserved session, not a serialized VM and not a global VM waiting to be reused.
  • Shell apps can be native or VM-backed, but only VM-backed processes need VM sessions.
  • Session ownership is the foundation for future background-capable processes, even before background execution exists.
  • Typed session/lifecycle errors make launch and recovery behavior explicit at firmware boundaries.