200 lines
9.0 KiB
Markdown
200 lines
9.0 KiB
Markdown
---
|
|
id: DEC-0038
|
|
ticket: foreground-stack-game-pause-shell-vm-backed
|
|
title: VM Session Ownership for VM-Backed Processes
|
|
status: accepted
|
|
created: 2026-07-04
|
|
ref_agenda: AGD-0046
|
|
tags: [runtime, os, lifecycle, shell, game, vm, foreground, architecture]
|
|
---
|
|
|
|
## Status
|
|
|
|
Open for review.
|
|
|
|
## Contexto
|
|
|
|
`DEC-0037` established the foreground stack and Game pause contract for
|
|
`Game -> Home/Shell -> same Game`. It requires a suspended resident Game to stop
|
|
receiving normal gameplay ticks, input, and frame pacing while remaining
|
|
resident for later resume.
|
|
|
|
The current implementation works for native Shell apps because native Shell
|
|
apps do not use the VM. It does not fully support VM-backed Shell coexistence:
|
|
`Firmware` owns a single global `VirtualMachine` (`Firmware.vm`), so loading a
|
|
VM-backed Shell can overwrite the suspended Game context that should remain
|
|
resident.
|
|
|
|
`AGD-0046` closes this gap by separating VM execution context ownership from
|
|
foreground ownership. A foreground owner decides who receives visual/input
|
|
authority. A VM execution context decides where PC, stack, heap, globals,
|
|
handles, cartridge identity, lifecycle delivery state, and VM-scoped runtime
|
|
state live.
|
|
|
|
## Decisao
|
|
|
|
PROMETEU MUST make VM execution context session-owned for VM-backed processes.
|
|
|
|
Every VM-backed process MUST have its own `VmSession` or equivalent
|
|
session-owned context. A VM-backed Game and a VM-backed Shell MUST NOT share the
|
|
same mutable `VirtualMachine` instance, stack, heap, PC, globals, open handles,
|
|
cartridge identity, or VM-scoped lifecycle state.
|
|
|
|
`Firmware.vm` MUST NOT remain the canonical owner of all VM-backed app context.
|
|
Firmware MAY continue to orchestrate macro states such as loading, Home, Shell,
|
|
and GameRunning, but it MUST delegate VM session creation, activation, lookup,
|
|
and ticking to SystemOS/session services.
|
|
|
|
For v1, the system MAY still enforce:
|
|
|
|
- at most one resident Game;
|
|
- at most one foreground Shell;
|
|
- no Game-to-Game switching;
|
|
- no general background execution.
|
|
|
|
Those restrictions MUST NOT be implemented by relying on a single global VM
|
|
context. They must be expressed as lifecycle/session policy.
|
|
|
|
Each VM-backed Shell MUST receive its own VM session. If future Shell
|
|
persistence allows more than one Shell app to remain in memory, each retained
|
|
VM-backed Shell MUST still have distinct mutable VM context.
|
|
|
|
A suspended resident Game MUST preserve its VM session. Suspension means the
|
|
session is not eligible for normal foreground ticks, normal Game input, or
|
|
normal frame pacing. It does not mean serializing, deleting, or overwriting the
|
|
VM context.
|
|
|
|
Foreground ownership and execution eligibility MUST be separate concepts:
|
|
|
|
- foreground ownership controls visual owner, primary input, render ownership,
|
|
and normal foreground frame pacing;
|
|
- execution eligibility controls which sessions may receive ticks or restricted
|
|
callbacks while not foreground.
|
|
|
|
Background execution, including music players or background services, is out of
|
|
scope for the first implementation of this decision. However, the session model
|
|
MUST be compatible with adding background-capable scheduling soon. The initial
|
|
model MUST NOT bake in assumptions that only the foreground session can ever be
|
|
eligible to execute.
|
|
|
|
Render ownership MUST remain a global SystemOS authority. VM sessions may
|
|
produce render submissions, but they MUST NOT decide whether those submissions
|
|
can be presented. SystemOS/render ownership policy remains responsible for
|
|
active owner, epoch/generation validity, stale submission rejection, and final
|
|
publication authority.
|
|
|
|
`LoadCartridgeStep` MUST stop initializing a global firmware VM directly as the
|
|
long-term model. Cartridge load/activation MUST be delegated to a sessions or
|
|
VM-session facade that can create a new VM session, activate an existing VM
|
|
session, or reject an unsupported transition according to lifecycle policy.
|
|
|
|
## Rationale
|
|
|
|
The foreground stack is already task/process-oriented. VM execution context must
|
|
follow the same ownership model. Otherwise the system can mark a Game as
|
|
resident and suspended while the only real VM context has already been reused
|
|
for a Shell.
|
|
|
|
Session ownership solves the actual coexistence problem without requiring VM
|
|
snapshot/restore. A suspended Game is simply a live session that is not scheduled
|
|
for normal ticks. A VM-backed Shell is another session with its own mutable
|
|
state.
|
|
|
|
Keeping background execution out of the first implementation avoids expanding
|
|
this work into a general scheduler. At the same time, making execution
|
|
eligibility separate from foreground ownership prevents an immediate future
|
|
background audio/player feature from requiring another foundational refactor.
|
|
|
|
Keeping render ownership global preserves the contract from `DEC-0037` and the
|
|
render ownership model from `DSC-0040`: sessions can generate frames, but only
|
|
the current foreground/render owner can publish valid current-epoch output.
|
|
|
|
## Invariantes / Contrato
|
|
|
|
- VM-backed mutable execution state is owned by a VM session, not by a global
|
|
firmware VM.
|
|
- A VM-backed Game and VM-backed Shell never share mutable VM context.
|
|
- A suspended resident Game retains its VM session.
|
|
- Suspension prevents normal foreground Game ticks/input/frame pacing; it does
|
|
not destroy or overwrite VM state.
|
|
- Native Shell apps do not require VM sessions.
|
|
- VM-backed Shell apps always require VM sessions.
|
|
- Each VM-backed Shell gets its own mutable VM session.
|
|
- Foreground ownership and execution eligibility are distinct.
|
|
- General background execution is out of scope for the initial implementation,
|
|
but the model must support adding it without replacing session ownership.
|
|
- SystemOS remains lifecycle and render ownership authority.
|
|
- Render ownership and stale frame rejection remain global policy, not per-VM
|
|
session policy.
|
|
- Cartridge load/activation must go through session services rather than
|
|
initializing one global firmware VM.
|
|
- V1 restrictions on one resident Game and one foreground Shell remain policy,
|
|
not a consequence of single-VM storage.
|
|
|
|
## Impactos
|
|
|
|
- **Runtime / SystemOS:** add a VM session model or equivalent service that
|
|
stores VM-backed process execution context and maps it to task/process
|
|
lifecycle.
|
|
- **Firmware:** remove `Firmware.vm` as the canonical VM context owner for all
|
|
apps. Firmware should request session creation/activation/tick from SystemOS.
|
|
- **VM:** support multiple distinct `VirtualMachine` instances or equivalent
|
|
isolated VM contexts in one OS lifetime.
|
|
- **Lifecycle:** task/process states must control session scheduling
|
|
eligibility without conflating foreground ownership with future background
|
|
execution.
|
|
- **Hub / Shell:** VM-backed Shell load must create or activate a Shell VM
|
|
session without overwriting a resident Game session.
|
|
- **Game:** Game pause/suspend/resume must preserve the Game VM session and
|
|
deliver lifecycle events to that session.
|
|
- **Renderer:** render manager stays global and validates ownership/epoch for
|
|
submissions produced by sessions.
|
|
- **FS / Memcard / Assets:** mutable handles and per-app runtime handles must
|
|
be evaluated for session scoping. Durable memcard/app data can remain keyed by
|
|
`app_id`; open handles and staging state should not accidentally leak across
|
|
sessions.
|
|
- **Tests:** add coverage proving VM-backed Shell creation does not overwrite a
|
|
suspended Game session, and that only eligible sessions tick.
|
|
|
|
## Alternativas Descartadas
|
|
|
|
- **Keep one global firmware VM and block VM-backed Shell when a Game is
|
|
resident:** rejected because it leaves `DEC-0037` incomplete and creates
|
|
divergent Shell behavior.
|
|
- **Serialize/snapshot the Game VM on suspension:** rejected because snapshot
|
|
correctness is harder than needed for v1 and would include VM, handles,
|
|
render state, assets, and side effects.
|
|
- **Hard-code two VM slots (`game_vm`, `shell_vm`):** rejected as a permanent
|
|
model because it encodes a short-term limit as architecture. It may only be
|
|
acceptable as an internal stepping stone if represented through the same
|
|
session abstraction.
|
|
- **Treat background-capable apps as hidden foreground owners:** rejected
|
|
because it would violate foreground ownership semantics and make render/input
|
|
authority ambiguous.
|
|
|
|
## Referencias
|
|
|
|
- Source agenda: `AGD-0046`
|
|
- Foreground stack and Game pause contract: `DEC-0037`
|
|
- Runtime mode separation: `DSC-0031`
|
|
- SystemOS lifecycle/process/task authority: `DSC-0032`
|
|
- VM render parallel execution boundary: `DSC-0040`
|
|
- Future Game-to-Game switching: `DSC-0043`
|
|
|
|
## Propagacao Necessaria
|
|
|
|
- Add implementation plans for introducing VM sessions and moving VM context
|
|
out of `Firmware`.
|
|
- Add implementation plans for separating VM-scoped runtime state from global
|
|
SystemOS/render state.
|
|
- Update runtime/firmware specs to describe session-owned VM context and the
|
|
distinction between foreground ownership and execution eligibility.
|
|
- Update tests for Game resident suspension, VM-backed Shell creation, and
|
|
session isolation.
|
|
- Keep future background execution as out of scope for first implementation,
|
|
but document that the model must support background-capable scheduling.
|
|
|
|
## Revision Log
|
|
|
|
- 2026-07-04: Initial decision draft from `AGD-0046`.
|