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

146 lines
6.5 KiB
Markdown

---
id: LSN-0052
ticket: foreground-stack-game-pause-shell-vm-backed
title: Foreground Ownership and VM Session Ownership Are Separate
created: 2026-07-05
tags: [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.