implements PLN-0138

This commit is contained in:
bQUARKz 2026-07-03 23:06:35 +01:00
parent 57c9af939b
commit 29e002c5f3
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
7 changed files with 121 additions and 13 deletions

View File

@ -2,7 +2,7 @@
{"type":"discussion","id":"DSC-0043","status":"open","ticket":"system-os-cartridge-switch-orchestrator","title":"SystemOS Cartridge Switch Orchestrator","created_at":"2026-07-03","updated_at":"2026-07-03","tags":["runtime","os","lifecycle","game","cartridge","architecture"],"agendas":[{"id":"AGD-0044","file":"AGD-0044-systemos-cartridge-switch-orchestrator.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0043","status":"open","ticket":"system-os-cartridge-switch-orchestrator","title":"SystemOS Cartridge Switch Orchestrator","created_at":"2026-07-03","updated_at":"2026-07-03","tags":["runtime","os","lifecycle","game","cartridge","architecture"],"agendas":[{"id":"AGD-0044","file":"AGD-0044-systemos-cartridge-switch-orchestrator.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03"}],"decisions":[],"plans":[],"lessons":[]}
{"type":"discussion","id":"DSC-0039","status":"abandoned","ticket":"render-pipeline-family-and-future-3d","title":"Render Pipeline Family and Future 3D","created_at":"2026-06-04","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","architecture","pipeline"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-render-pipeline-family-and-future-3d.md","status":"abandoned","created_at":"2026-06-04","updated_at":"2026-06-04","_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}],"decisions":[],"plans":[],"lessons":[],"_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."} {"type":"discussion","id":"DSC-0039","status":"abandoned","ticket":"render-pipeline-family-and-future-3d","title":"Render Pipeline Family and Future 3D","created_at":"2026-06-04","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","architecture","pipeline"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-render-pipeline-family-and-future-3d.md","status":"abandoned","created_at":"2026-06-04","updated_at":"2026-06-04","_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}],"decisions":[],"plans":[],"lessons":[],"_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}
{"type":"discussion","id":"DSC-0040","status":"done","ticket":"vm-render-parallel-execution-boundary","title":"VM and Render Parallel Execution Boundary","created_at":"2026-06-04","updated_at":"2026-06-06","tags":["runtime","renderer","vm","concurrency","architecture","perf"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0048","file":"discussion/lessons/DSC-0040-vm-render-parallel-execution-boundary/LSN-0048-render-workers-need-a-closed-packet-contract.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-06"}]} {"type":"discussion","id":"DSC-0040","status":"done","ticket":"vm-render-parallel-execution-boundary","title":"VM and Render Parallel Execution Boundary","created_at":"2026-06-04","updated_at":"2026-06-06","tags":["runtime","renderer","vm","concurrency","architecture","perf"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0048","file":"discussion/lessons/DSC-0040-vm-render-parallel-execution-boundary/LSN-0048-render-workers-need-a-closed-packet-contract.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-06"}]}
{"type":"discussion","id":"DSC-0041","status":"in_progress","ticket":"foreground-stack-game-pause-shell-vm-backed","title":"Foreground Stack, Game Pause, and VM-Backed Shell Coexistence","created_at":"2026-06-05","updated_at":"2026-07-03","tags":["runtime","os","lifecycle","shell","game","vm","foreground","architecture"],"agendas":[{"id":"AGD-0041","file":"AGD-0041-foreground-stack-game-pause-shell-vm-backed.md","status":"accepted","created_at":"2026-06-05","updated_at":"2026-07-03"}],"decisions":[{"id":"DEC-0037","file":"DEC-0037-foreground-stack-and-game-pause-contract.md","status":"accepted","created_at":"2026-07-03","updated_at":"2026-07-03","ref_agenda":"AGD-0041"}],"plans":[{"id":"PLN-0136","file":"PLN-0136-route-desktop-home-key-outside-guest-input.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0137","file":"PLN-0137-implement-systemos-foreground-stack-state.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0138","file":"PLN-0138-specify-foreground-pause-and-home-contract.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0139","file":"PLN-0139-validate-game-home-shell-game-end-to-end.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0140","file":"PLN-0140-deliver-game-pause-resume-and-suspension.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0141","file":"PLN-0141-integrate-render-audio-and-input-pause-boundaries.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]}],"lessons":[]} {"type":"discussion","id":"DSC-0041","status":"in_progress","ticket":"foreground-stack-game-pause-shell-vm-backed","title":"Foreground Stack, Game Pause, and VM-Backed Shell Coexistence","created_at":"2026-06-05","updated_at":"2026-07-03","tags":["runtime","os","lifecycle","shell","game","vm","foreground","architecture"],"agendas":[{"id":"AGD-0041","file":"AGD-0041-foreground-stack-game-pause-shell-vm-backed.md","status":"accepted","created_at":"2026-06-05","updated_at":"2026-07-03"}],"decisions":[{"id":"DEC-0037","file":"DEC-0037-foreground-stack-and-game-pause-contract.md","status":"accepted","created_at":"2026-07-03","updated_at":"2026-07-03","ref_agenda":"AGD-0041"}],"plans":[{"id":"PLN-0136","file":"PLN-0136-route-desktop-home-key-outside-guest-input.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0137","file":"PLN-0137-implement-systemos-foreground-stack-state.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0138","file":"PLN-0138-specify-foreground-pause-and-home-contract.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0139","file":"PLN-0139-validate-game-home-shell-game-end-to-end.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0140","file":"PLN-0140-deliver-game-pause-resume-and-suspension.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0141","file":"PLN-0141-integrate-render-audio-and-input-pause-boundaries.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]}],"lessons":[]}
{"type":"discussion","id":"DSC-0042","status":"done","ticket":"real-render-worker-establishment","title":"Real Render Worker Establishment","created_at":"2026-06-06","updated_at":"2026-06-20","tags":["runtime","renderer","worker","concurrency","host","hal","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0049","file":"discussion/lessons/DSC-0042-real-render-worker-establishment/LSN-0049-render-worker-publication-boundary.md","status":"done","created_at":"2026-06-20","updated_at":"2026-06-20"}]} {"type":"discussion","id":"DSC-0042","status":"done","ticket":"real-render-worker-establishment","title":"Real Render Worker Establishment","created_at":"2026-06-06","updated_at":"2026-06-20","tags":["runtime","renderer","worker","concurrency","host","hal","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0049","file":"discussion/lessons/DSC-0042-real-render-worker-establishment/LSN-0049-render-worker-publication-boundary.md","status":"done","created_at":"2026-06-20","updated_at":"2026-06-20"}]}
{"type":"discussion","id":"DSC-0038","status":"done","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0047","file":"discussion/lessons/DSC-0038-render-frame-packet-boundary/LSN-0047-typed-render-submissions-preserve-domain-boundaries.md","status":"done","created_at":"2026-06-04","updated_at":"2026-06-04"}]} {"type":"discussion","id":"DSC-0038","status":"done","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0047","file":"discussion/lessons/DSC-0038-render-frame-packet-boundary/LSN-0047-typed-render-submissions-preserve-domain-boundaries.md","status":"done","created_at":"2026-06-04","updated_at":"2026-06-04"}]}
{"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]} {"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}

View File

@ -2,7 +2,7 @@
id: PLN-0138 id: PLN-0138
ticket: foreground-stack-game-pause-shell-vm-backed ticket: foreground-stack-game-pause-shell-vm-backed
title: Specify Foreground Pause and Home Contract title: Specify Foreground Pause and Home Contract
status: open status: done
created: 2026-07-03 created: 2026-07-03
ref_decisions: [DEC-0037] ref_decisions: [DEC-0037]
tags: [runtime, specs, lifecycle, input, renderer, foreground] tags: [runtime, specs, lifecycle, input, renderer, foreground]

View File

@ -239,8 +239,10 @@ The same physical surface may be reused by multiple visual owners, but logical
ownership MUST remain explicit. ownership MUST remain explicit.
Game pause/resume, foreground stack behavior, and coexistence of a paused Game Game pause/resume, foreground stack behavior, and coexistence of a paused Game
with VM-backed Shell apps are outside this contract and are tracked by the with VM-backed Shell apps are defined by the foreground/lifecycle contract. The
foreground/lifecycle discussion. render boundary's responsibility is narrower: foreground owner changes MUST
advance ownership, stale submissions MUST be discarded, and visual return to a
resumed Game MUST wait for a valid submission from the current ownership epoch.
### 4.7 Render telemetry ### 4.7 Render telemetry

View File

@ -107,3 +107,21 @@ Input access is VM-owned and should not be reported as host syscall consumption.
All platforms must provide the mandatory input elements (`pad`, `touch`, `button`) to the runtime. All platforms must provide the mandatory input elements (`pad`, `touch`, `button`) to the runtime.
Platform differences in physical device mapping are resolved outside VM semantics. Platform differences in physical device mapping are resolved outside VM semantics.
## 9 Host/System Controls
Host/System controls are not part of the guest-visible input surface.
The Home/SystemOS request changes machine foreground authority. It must be
handled by the host, firmware, or SystemOS before input is exposed to the Game.
It must not be represented as `pad.start`, `pad.select`, a new pad field, a VM
intrinsic, or a userland syscall.
For the desktop host, `Esc` is the primary keyboard mapping for the
Home/SystemOS request. The physical `Home` key may be supported as an alias.
Both mappings are host controls and must not mutate `InputSignals`.
When a Game leaves or re-enters foreground, pending Game input must be cleared
or barriered so held or pressed input cannot leak across pause/resume
boundaries. This barrier applies to the Game-facing snapshot; it does not
change the meaning of host/system Home controls.

View File

@ -100,7 +100,40 @@ Important properties:
- no execution occurs outside the frame loop; - no execution occurs outside the frame loop;
- frame structure remains observable for host tooling and host-owned certification. - frame structure remains observable for host tooling and host-owned certification.
## 7 Render Worker Concurrency ## 7 Foreground Lifecycle Events
Foreground lifecycle events are system events with bounded delivery points.
They do not execute arbitrary guest callbacks at arrival time.
The Game pause path is:
```text
Home/SystemOS request
-> pause event becomes visible to the Game
-> bounded pause reaction budget
-> SystemOS suspension, even if the Game did not cooperate
```
The Game resume path is:
```text
SystemOS resume request
-> VM reactivation
-> resume or foreground-restore event becomes visible to the Game
-> Game may synchronize while still internally paused
-> visual foreground returns after a valid current-epoch render submission
```
`Paused` is the Game-visible event/state. `Suspended` is the OS-owned
scheduler/runtime state. A Game may observe pause/resume, but it must not
control whether SystemOS suspends or resumes the VM.
Pause budgets are measured in deterministic machine units, not host wall-clock
time. A suspended Game receives no normal gameplay ticks, no normal Game input,
and no frame pacing. Real background execution is outside the v1 foreground
contract.
## 8 Render Worker Concurrency
The render worker is not a machine-visible event source and does not introduce The render worker is not a machine-visible event source and does not introduce
guest callbacks. It is an implementation-side consumer of closed render guest callbacks. It is an implementation-side consumer of closed render
@ -127,7 +160,7 @@ Shutdown is explicit and bounded. A shutdown request wakes a waiting worker,
causes pending work that will not be consumed to be discarded, and reports a causes pending work that will not be consumed to be discarded, and reports a
typed failure if the worker cannot join within the configured timeout. typed failure if the worker cannot join within the configured timeout.
## 8 Async Asset and IO Work Lane ## 9 Async Asset and IO Work Lane
The asset/IO async work lane is not a machine-visible event source and does not The asset/IO async work lane is not a machine-visible event source and does not
introduce guest callbacks. It is an implementation-side lane for asset introduce guest callbacks. It is an implementation-side lane for asset
@ -151,7 +184,7 @@ does not publish resident graphics/audio/scene state directly.
FS and game persistence services may consume this lane for IO-style work, but FS and game persistence services may consume this lane for IO-style work, but
public FS API shape is defined by the FS/app-home contract, not by this chapter. public FS API shape is defined by the FS/app-home contract, not by this chapter.
## 9 Determinism and Best Practices ## 10 Determinism and Best Practices
PROMETEU encourages: PROMETEU encourages:
@ -166,7 +199,7 @@ PROMETEU discourages:
- hidden timing channels; - hidden timing channels;
- ambiguous out-of-band execution. - ambiguous out-of-band execution.
## 10 Relationship to Other Specs ## 11 Relationship to Other Specs
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md) defines coroutine lifecycle and scheduling behavior. - [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md) defines coroutine lifecycle and scheduling behavior.
- [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md) defines observability and diagnostics surfaces. - [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md) defines observability and diagnostics surfaces.

View File

@ -43,6 +43,13 @@ The VM does not own the machine lifecycle. Firmware does.
Game directory cartridges. Game directory cartridges.
- **Library entry**: an internal catalog record retained by Hub/SystemOS for a - **Library entry**: an internal catalog record retained by Hub/SystemOS for a
discovered cartridge. discovered cartridge.
- **Foreground visual owner**: the single machine owner whose visual output may
be presented at a given time.
- **Paused**: a Game-visible lifecycle event/state. The Game may observe it and
prepare for foreground loss.
- **Suspended**: an OS-owned scheduler/runtime state. A suspended Game remains
resident but does not receive normal gameplay ticks, normal Game input, or
frame pacing.
## 3 POS Responsibilities ## 3 POS Responsibilities
@ -154,7 +161,50 @@ Shell task loses its eligible focused window
-> FirmwareState::HubHome -> FirmwareState::HubHome
``` ```
## 7 Cartridge Load Flow ## 7 Foreground Stack and Game Pause
The v1 foreground contract is single-owner:
- exactly one foreground visual owner exists at a time;
- at most one Game may be resident;
- at most one Shell app may be foreground;
- Hub/Home is the root Shell owner and back-stack controller.
The minimal supported navigation cycle is:
```text
Game foreground
-> Home request
-> Game pause notification
-> Game suspended by SystemOS after a bounded budget
-> Hub/Home foreground
-> optional Shell foreground
-> Shell close returns to Hub/Home
-> same Game resume/foreground-restore notification
-> Game foreground after a valid current-epoch render submission
```
`Paused` is cooperative and visible to the Game. `Suspended` is imposed by
SystemOS. The Game may react to pause/resume, but it must not control whether
the OS suspends or resumes its VM.
When Home is requested during Game execution, SystemOS must notify the Game and
grant a short bounded pause budget. After the budget, SystemOS may suspend the
VM even if the Game did not cooperate. While suspended, the Game must not
receive normal gameplay ticks, normal Game input, or frame pacing.
When returning to the same Game, SystemOS must reactivate the VM and send a
resume or foreground-restore notification before visual foreground is restored.
The Game may remain internally paused while it synchronizes. Hub/Shell remains
visible until the resumed Game publishes a valid render submission for the
current ownership epoch.
Input pending for the Game must be cleared or barriered across pause/resume
boundaries. Game audio pauses with the Game VM in v1. Independent background
audio, real background execution, multiple resident Games, multiple foreground
Shells, and direct Game-to-Game switching are outside this contract.
## 8 Cartridge Load Flow
Current high-level flow: Current high-level flow:
@ -179,7 +229,7 @@ If the selected cartridge cannot be loaded, firmware must leave or return the
machine in the Hub/Home flow and record the failure through diagnostics or machine in the Hub/Home flow and record the failure through diagnostics or
logging. A polished Home error surface is not required by v1. logging. A polished Home error surface is not required by v1.
## 8 Firmware States ## 9 Firmware States
The current firmware state model includes: The current firmware state model includes:
@ -193,7 +243,7 @@ The current firmware state model includes:
These states express machine orchestration above the VM. They are not guest-visible bytecode states. These states express machine orchestration above the VM. They are not guest-visible bytecode states.
## 9 Execution Contract ## 10 Execution Contract
For game-mode execution, firmware/runtime coordination preserves: For game-mode execution, firmware/runtime coordination preserves:
@ -204,7 +254,7 @@ For game-mode execution, firmware/runtime coordination preserves:
This keeps the machine model deterministic and observable. This keeps the machine model deterministic and observable.
## 10 Crash Handling ## 11 Crash Handling
Firmware owns terminal fault presentation. Firmware owns terminal fault presentation.
@ -216,7 +266,7 @@ When a terminal app fault occurs:
Crash handling is outside the guest VM execution model. Crash handling is outside the guest VM execution model.
## 11 Relationship to Other Specs ## 12 Relationship to Other Specs
- [`02-vm-instruction-set.md`](02-vm-instruction-set.md) defines the VM subsystem run by firmware. - [`02-vm-instruction-set.md`](02-vm-instruction-set.md) defines the VM subsystem run by firmware.
- [`09-events-and-concurrency.md`](09-events-and-concurrency.md) defines the frame-boundary model used by firmware. - [`09-events-and-concurrency.md`](09-events-and-concurrency.md) defines the frame-boundary model used by firmware.

View File

@ -99,6 +99,11 @@ Game-to-game switching after a game is already active is not part of this boot
profile. That orchestration belongs to the foreground/home and cartridge switch profile. That orchestration belongs to the foreground/home and cartridge switch
contracts. contracts.
The foreground/home contract defines `Game -> Home/Shell -> same Game` after a
Game is already running. It does not change direct `--run`, debugger direct
boot, or `--games-root` Home library startup semantics. Home/SystemOS requests
are host/system controls, not guest cartridge boot APIs.
## 5 Firmware State Relationship ## 5 Firmware State Relationship
Boot target selection feeds into firmware states such as: Boot target selection feeds into firmware states such as: