implements PLN-0162
This commit is contained in:
parent
8d719843c7
commit
c814e057dc
@ -1,5 +1,5 @@
|
|||||||
{"type":"meta","next_id":{"DSC":44,"AGD":47,"DEC":40,"PLN":163,"LSN":53,"CLSN":1}}
|
{"type":"meta","next_id":{"DSC":44,"AGD":47,"DEC":40,"PLN":163,"LSN":53,"CLSN":1}}
|
||||||
{"type":"discussion","id":"DSC-0043","status":"in_progress","ticket":"system-os-cartridge-switch-orchestrator","title":"SystemOS Cartridge Switch Orchestrator","created_at":"2026-07-03","updated_at":"2026-07-05","tags":["runtime","os","lifecycle","game","cartridge","architecture"],"agendas":[{"id":"AGD-0044","file":"AGD-0044-systemos-cartridge-switch-orchestrator.md","status":"accepted","created_at":"2026-07-03","updated_at":"2026-07-05"}],"decisions":[{"id":"DEC-0039","file":"DEC-0039-systemos-game-cartridge-switch-orchestrator.md","status":"accepted","created_at":"2026-07-05","updated_at":"2026-07-05","ref_agenda":"AGD-0044"}],"plans":[{"id":"PLN-0157","file":"PLN-0157-introduce-systemos-game-switch-target-contract.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0158","file":"PLN-0158-terminate-resident-game-before-switching-cartridges.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0159","file":"PLN-0159-recover-failed-game-switches-back-to-home.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0160","file":"PLN-0160-add-dummy-boy-visual-switch-test-cartridge.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0161","file":"PLN-0161-validate-stress-to-dummy-boy-game-switch-end-to-end.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0162","file":"PLN-0162-specify-game-switch-contract-and-direct-boot-separation.md","status":"open","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]}],"lessons":[]}
|
{"type":"discussion","id":"DSC-0043","status":"in_progress","ticket":"system-os-cartridge-switch-orchestrator","title":"SystemOS Cartridge Switch Orchestrator","created_at":"2026-07-03","updated_at":"2026-07-05","tags":["runtime","os","lifecycle","game","cartridge","architecture"],"agendas":[{"id":"AGD-0044","file":"AGD-0044-systemos-cartridge-switch-orchestrator.md","status":"accepted","created_at":"2026-07-03","updated_at":"2026-07-05"}],"decisions":[{"id":"DEC-0039","file":"DEC-0039-systemos-game-cartridge-switch-orchestrator.md","status":"accepted","created_at":"2026-07-05","updated_at":"2026-07-05","ref_agenda":"AGD-0044"}],"plans":[{"id":"PLN-0157","file":"PLN-0157-introduce-systemos-game-switch-target-contract.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0158","file":"PLN-0158-terminate-resident-game-before-switching-cartridges.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0159","file":"PLN-0159-recover-failed-game-switches-back-to-home.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0160","file":"PLN-0160-add-dummy-boy-visual-switch-test-cartridge.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0161","file":"PLN-0161-validate-stress-to-dummy-boy-game-switch-end-to-end.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0162","file":"PLN-0162-specify-game-switch-contract-and-direct-boot-separation.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]}],"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":"done","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-05","tags":["runtime","os","lifecycle","shell","game","vm","foreground","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0052","file":"discussion/lessons/DSC-0041-foreground-stack-game-pause-shell-vm-backed/LSN-0052-foreground-ownership-and-vm-session-ownership-are-separate.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]}
|
{"type":"discussion","id":"DSC-0041","status":"done","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-05","tags":["runtime","os","lifecycle","shell","game","vm","foreground","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0052","file":"discussion/lessons/DSC-0041-foreground-stack-game-pause-shell-vm-backed/LSN-0052-foreground-ownership-and-vm-session-ownership-are-separate.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
id: PLN-0162
|
id: PLN-0162
|
||||||
ticket: system-os-cartridge-switch-orchestrator
|
ticket: system-os-cartridge-switch-orchestrator
|
||||||
title: Specify Game Switch Contract And Direct Boot Separation
|
title: Specify Game Switch Contract And Direct Boot Separation
|
||||||
status: open
|
status: done
|
||||||
created: 2026-07-05
|
created: 2026-07-05
|
||||||
ref_decisions: [DEC-0039]
|
ref_decisions: [DEC-0039]
|
||||||
tags: [runtime, os, lifecycle, game, cartridge, architecture]
|
tags: [runtime, os, lifecycle, game, cartridge, architecture]
|
||||||
|
|||||||
@ -128,6 +128,11 @@ SystemOS resume request
|
|||||||
scheduler/runtime state. A Game may observe pause/resume, but it must not
|
scheduler/runtime state. A Game may observe pause/resume, but it must not
|
||||||
control whether SystemOS suspends or resumes the VM.
|
control whether SystemOS suspends or resumes the VM.
|
||||||
|
|
||||||
|
When SystemOS replaces one Game with another from Home, the old Game MAY receive
|
||||||
|
a cooperative terminate/save lifecycle event if the runtime supports such an
|
||||||
|
event. That event is non-blocking in v1. SystemOS remains authoritative and may
|
||||||
|
close the old Game task/session without guest acknowledgement.
|
||||||
|
|
||||||
Pause budgets are measured in deterministic machine units, not host wall-clock
|
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,
|
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
|
and no frame pacing. Real background execution is outside the v1 foreground
|
||||||
@ -163,6 +168,12 @@ requires it. Transient VM handles, open files, lifecycle delivery queues, and
|
|||||||
staging state are session-scoped unless another spec explicitly makes them
|
staging state are session-scoped unless another spec explicitly makes them
|
||||||
durable app data.
|
durable app data.
|
||||||
|
|
||||||
|
During destructive Game replacement, the old Game VM session MUST be removed
|
||||||
|
from execution eligibility and resumable state before the new Game becomes the
|
||||||
|
foreground Game. The new Game MUST receive a fresh VM session. Failure while
|
||||||
|
loading or initializing the replacement Game MUST return the machine to
|
||||||
|
Hub/Home and MUST NOT restore the previous Game in v1.
|
||||||
|
|
||||||
## 9 Render Worker Concurrency
|
## 9 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
|
||||||
|
|||||||
@ -44,6 +44,11 @@ PROMETEU operates in three main modes:
|
|||||||
|
|
||||||
No mode alters the logical result of the program.
|
No mode alters the logical result of the program.
|
||||||
|
|
||||||
|
Debug boot is a host-selected direct cartridge boot profile. It follows the same
|
||||||
|
cartridge/app-mode resolution path as direct boot and is separate from
|
||||||
|
Home-driven Game switching. Debug boot MUST NOT be modeled as a guest-visible
|
||||||
|
Game switch request and MUST NOT reuse a Home switch failure-recovery contract.
|
||||||
|
|
||||||
## 3 Execution Control
|
## 3 Execution Control
|
||||||
|
|
||||||
### 3.1 Pause and Resume
|
### 3.1 Pause and Resume
|
||||||
|
|||||||
@ -43,6 +43,9 @@ 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.
|
||||||
|
- **Game switch target**: a SystemOS-owned launch target derived from a library
|
||||||
|
entry. It carries the cartridge path plus resolved identity such as `app_id`,
|
||||||
|
`title`, and `app_version`.
|
||||||
- **Foreground visual owner**: the single machine owner whose visual output may
|
- **Foreground visual owner**: the single machine owner whose visual output may
|
||||||
be presented at a given time.
|
be presented at a given time.
|
||||||
- **Paused**: a Game-visible lifecycle event/state. The Game may observe it and
|
- **Paused**: a Game-visible lifecycle event/state. The Game may observe it and
|
||||||
@ -231,9 +234,27 @@ Current high-level flow:
|
|||||||
If VM initialization fails, firmware transitions to the crash path.
|
If VM initialization fails, firmware transitions to the crash path.
|
||||||
|
|
||||||
For v1, POS must enforce at most one resident Game session. Selecting the same
|
For v1, POS must enforce at most one resident Game session. Selecting the same
|
||||||
resident Game from Home resumes that session. Selecting a different Game while a
|
resident Game from Home resumes that session. Selecting a different Game from
|
||||||
resident Game exists is outside the v1 foreground contract and must not create a
|
Home is a SystemOS-owned Game switch and MUST be destructive replacement:
|
||||||
second resident Game session. VM-backed Shell loading creates a distinct Shell
|
|
||||||
|
```text
|
||||||
|
Game A resident
|
||||||
|
-> Hub/Home selected Game B with different app_id
|
||||||
|
-> SystemOS terminates Game A resident task/session
|
||||||
|
-> SystemOS removes Game A from resumable state
|
||||||
|
-> firmware loads Game B through LoadCartridge
|
||||||
|
-> Game B receives a fresh VM session
|
||||||
|
```
|
||||||
|
|
||||||
|
SystemOS MUST NOT create a second resident Game session. SystemOS MUST NOT
|
||||||
|
reuse the old Game VM session, transient VM handles, pending lifecycle delivery
|
||||||
|
state, render ownership, debug pause state, or crash/debug runtime state for the
|
||||||
|
new Game. Durable app data remains governed by the relevant storage specs and
|
||||||
|
may still be keyed by `app_id`.
|
||||||
|
|
||||||
|
SystemOS MAY emit a cooperative non-blocking terminate/save lifecycle event
|
||||||
|
before closing the old Game when such an event exists. Replacement MUST NOT
|
||||||
|
block on that event in v1. VM-backed Shell loading creates a distinct Shell
|
||||||
session and must not overwrite resident Game VM state.
|
session and must not overwrite resident Game VM state.
|
||||||
|
|
||||||
POS selects the cartridge and its execution context, but the cartridge's initial callable is not chosen by firmware metadata. Execution starts from the cartridge boot protocol defined in [`13-cartridge.md`](13-cartridge.md), currently `func_id = 0`.
|
POS selects the cartridge and its execution context, but the cartridge's initial callable is not chosen by firmware metadata. Execution starts from the cartridge boot protocol defined in [`13-cartridge.md`](13-cartridge.md), currently `func_id = 0`.
|
||||||
@ -248,6 +269,16 @@ 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.
|
||||||
|
|
||||||
|
If a destructive Game switch has already begun and the new Game fails to load or
|
||||||
|
initialize, firmware MUST return to Hub/Home, MUST discard any partial new Game
|
||||||
|
task/session/window/render/input/audio state, and MUST NOT restore the previous
|
||||||
|
Game. Direct boot and debug boot failures remain governed by the boot profile
|
||||||
|
that requested them and may still transition to the crash path.
|
||||||
|
|
||||||
|
Switch validation MUST include two distinct Game cartridges. The current
|
||||||
|
repository evidence uses `Stress Console` and `Dummy Boy`; those cartridges are
|
||||||
|
test evidence, not required runtime features.
|
||||||
|
|
||||||
## 9 Firmware States
|
## 9 Firmware States
|
||||||
|
|
||||||
The current firmware state model includes:
|
The current firmware state model includes:
|
||||||
|
|||||||
@ -186,6 +186,9 @@ For the v1 Home games library:
|
|||||||
- the manifest must declare `app_mode: "Game"`;
|
- the manifest must declare `app_mode: "Game"`;
|
||||||
- the library retains the loaded manifest data, `title`, `app_id`,
|
- the library retains the loaded manifest data, `title`, `app_id`,
|
||||||
`app_version`, the internal cartridge path, and discovery metadata;
|
`app_version`, the internal cartridge path, and discovery metadata;
|
||||||
|
- the library entry identity is the input to the SystemOS Game switch target;
|
||||||
|
- `app_id` is the v1 identity used to distinguish same-Game resume from
|
||||||
|
different-Game destructive replacement;
|
||||||
- invalid candidates are logged or reported as diagnostics and omitted from the
|
- invalid candidates are logged or reported as diagnostics and omitted from the
|
||||||
Home list;
|
Home list;
|
||||||
- valid non-Game cartridges are omitted from the Game library.
|
- valid non-Game cartridges are omitted from the Game library.
|
||||||
@ -193,6 +196,11 @@ For the v1 Home games library:
|
|||||||
Discovery reads metadata for cataloging. It does not replace the normal
|
Discovery reads metadata for cataloging. It does not replace the normal
|
||||||
cartridge loader used when firmware starts the selected cartridge.
|
cartridge loader used when firmware starts the selected cartridge.
|
||||||
|
|
||||||
|
Selecting a discovered Game from Home is not cartridge self-execution and is not
|
||||||
|
guest-controlled. The cartridge path is consumed by firmware/SystemOS, which
|
||||||
|
owns same-Game resume, different-Game replacement, failure recovery, and VM
|
||||||
|
session creation policy.
|
||||||
|
|
||||||
### Packaged `.pmc` form
|
### Packaged `.pmc` form
|
||||||
|
|
||||||
This form is recognized conceptually by the loader boundary, but its actual load path is not implemented yet.
|
This form is recognized conceptually by the loader boundary, but its actual load path is not implemented yet.
|
||||||
|
|||||||
@ -97,9 +97,11 @@ The v1 games root contract is:
|
|||||||
and transitions through `LoadCartridge`;
|
and transitions through `LoadCartridge`;
|
||||||
- launch failure leaves or returns the machine to Home and records an error.
|
- launch failure leaves or returns the machine to Home and records an error.
|
||||||
|
|
||||||
Game-to-game switching after a game is already active is not part of this boot
|
Game-to-game switching after a game is already active is not a boot profile.
|
||||||
profile. That orchestration belongs to the foreground/home and cartridge switch
|
That orchestration belongs to the foreground/home and cartridge switch
|
||||||
contracts.
|
contracts. In that path, SystemOS owns the switch policy: selecting the same
|
||||||
|
resident Game resumes it, while selecting a different Game performs destructive
|
||||||
|
replacement and creates a fresh VM session for the new Game.
|
||||||
|
|
||||||
The foreground/home contract defines `Game -> Home/Shell -> same Game` after a
|
The foreground/home contract defines `Game -> Home/Shell -> same Game` after a
|
||||||
Game is already running. It does not change direct `--run`, debugger direct
|
Game is already running. It does not change direct `--run`, debugger direct
|
||||||
@ -108,6 +110,10 @@ are host/system controls, not guest cartridge boot APIs.
|
|||||||
|
|
||||||
Direct boot creates the initial VM session for the selected cartridge. It does
|
Direct boot creates the initial VM session for the selected cartridge. It does
|
||||||
not create a reusable global VM shared by later Game or Shell cartridges.
|
not create a reusable global VM shared by later Game or Shell cartridges.
|
||||||
|
Direct boot and debug boot MUST NOT be treated as failed-switch recovery paths:
|
||||||
|
load or initialization failures for direct boot may transition to the crash
|
||||||
|
flow, while Home-driven switch failures return to Home and do not restore the
|
||||||
|
previous Game.
|
||||||
|
|
||||||
## 5 Firmware State Relationship
|
## 5 Firmware State Relationship
|
||||||
|
|
||||||
@ -152,6 +158,10 @@ Direct single-cartridge boot remains a separate validation path:
|
|||||||
cargo run --release -p prometeu-host-desktop-winit -- --run test-cartridges/stress-console
|
cargo run --release -p prometeu-host-desktop-winit -- --run test-cartridges/stress-console
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Game switch validation should cover the Home-driven two-cartridge path, for
|
||||||
|
example `Stress Console -> Home -> Dummy Boy`, and assert that the first Game is
|
||||||
|
not resumable after replacement.
|
||||||
|
|
||||||
## 8 Relationship to Other Specs
|
## 8 Relationship to Other Specs
|
||||||
|
|
||||||
- [`12-firmware-pos-and-prometeuhub.md`](12-firmware-pos-and-prometeuhub.md) defines the firmware state machine that consumes boot targets.
|
- [`12-firmware-pos-and-prometeuhub.md`](12-firmware-pos-and-prometeuhub.md) defines the firmware state machine that consumes boot targets.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user