implements PLN-0166

This commit is contained in:
bQUARKz 2026-07-05 09:42:57 +01:00
parent 3aec829c70
commit 49cb16b6cb
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
4 changed files with 50 additions and 2 deletions

View File

@ -1,5 +1,5 @@
{"type":"meta","next_id":{"DSC":45,"AGD":48,"DEC":41,"PLN":167,"LSN":53,"CLSN":1}} {"type":"meta","next_id":{"DSC":45,"AGD":48,"DEC":41,"PLN":167,"LSN":53,"CLSN":1}}
{"type":"discussion","id":"DSC-0044","status":"in_progress","ticket":"hub-suspended-game-kill-affordance","title":"Hub Suspended Game Kill Affordance","created_at":"2026-07-05","updated_at":"2026-07-05","tags":["hub","lifecycle","game","ui"],"agendas":[{"id":"AGD-0047","file":"AGD-0047-hub-suspended-game-kill-affordance.md","status":"accepted","created_at":"2026-07-05","updated_at":"2026-07-05"}],"decisions":[{"id":"DEC-0040","file":"DEC-0040-hub-suspended-game-kill-affordance.md","status":"accepted","created_at":"2026-07-05","updated_at":"2026-07-05","ref_agenda":"AGD-0047"}],"plans":[{"id":"PLN-0163","file":"PLN-0163-render-hub-suspended-game-kill-control.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0040"]},{"id":"PLN-0164","file":"PLN-0164-expose-resident-game-termination-contract.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0040"]},{"id":"PLN-0165","file":"PLN-0165-validate-hub-kill-flow-end-to-end.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0040"]},{"id":"PLN-0166","file":"PLN-0166-publish-hub-kill-contract-spec-and-lesson-hooks.md","status":"open","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0040"]}],"lessons":[]} {"type":"discussion","id":"DSC-0044","status":"in_progress","ticket":"hub-suspended-game-kill-affordance","title":"Hub Suspended Game Kill Affordance","created_at":"2026-07-05","updated_at":"2026-07-05","tags":["hub","lifecycle","game","ui"],"agendas":[{"id":"AGD-0047","file":"AGD-0047-hub-suspended-game-kill-affordance.md","status":"accepted","created_at":"2026-07-05","updated_at":"2026-07-05"}],"decisions":[{"id":"DEC-0040","file":"DEC-0040-hub-suspended-game-kill-affordance.md","status":"accepted","created_at":"2026-07-05","updated_at":"2026-07-05","ref_agenda":"AGD-0047"}],"plans":[{"id":"PLN-0163","file":"PLN-0163-render-hub-suspended-game-kill-control.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0040"]},{"id":"PLN-0164","file":"PLN-0164-expose-resident-game-termination-contract.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0040"]},{"id":"PLN-0165","file":"PLN-0165-validate-hub-kill-flow-end-to-end.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0040"]},{"id":"PLN-0166","file":"PLN-0166-publish-hub-kill-contract-spec-and-lesson-hooks.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0040"]}],"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-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"}]}

View File

@ -2,7 +2,7 @@
id: PLN-0166 id: PLN-0166
ticket: hub-suspended-game-kill-affordance ticket: hub-suspended-game-kill-affordance
title: Publish Hub Kill Contract Spec And Lesson Hooks title: Publish Hub Kill Contract Spec And Lesson Hooks
status: open status: done
created: 2026-07-05 created: 2026-07-05
ref_decisions: [DEC-0040] ref_decisions: [DEC-0040]
tags: [hub, lifecycle, game, ui] tags: [hub, lifecycle, game, ui]

View File

@ -174,6 +174,14 @@ foreground Game. The new Game MUST receive a fresh VM session. Failure while
loading or initializing the replacement Game MUST return the machine to loading or initializing the replacement Game MUST return the machine to
Hub/Home and MUST NOT restore the previous Game in v1. Hub/Home and MUST NOT restore the previous Game in v1.
Manual Hub termination of a suspended resident Game has the same session
removal authority as destructive Game replacement, except that no replacement
Game is started. SystemOS MUST remove the Game from execution eligibility and
resumable state, close its task, stop its process, remove its VM session, clear
task-scoped pending lifecycle delivery, and keep Hub/Home as the foreground
owner. After manual Hub termination, resume queries MUST report no resident
Game. A later launch of the same cartridge is a fresh Game session.
## 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

View File

@ -55,6 +55,8 @@ The VM does not own the machine lifecycle. Firmware does.
frame pacing. frame pacing.
- **VM session**: the POS-owned mutable execution context for one VM-backed - **VM session**: the POS-owned mutable execution context for one VM-backed
process. It contains the VM instance and per-session runtime state. process. It contains the VM instance and per-session runtime state.
- **Hub resident Game kill control**: a Hub/Home affordance that terminates the
current resident Game instead of resuming it.
## 3 POS Responsibilities ## 3 POS Responsibilities
@ -89,6 +91,8 @@ PrometeuHub is responsible for:
- presenting the host-provided local games library when `--games-root <dir>` is - presenting the host-provided local games library when `--games-root <dir>` is
configured; configured;
- emitting system-owned launch actions for selected Home entries. - emitting system-owned launch actions for selected Home entries.
- presenting a resident Game kill control while Hub/Home owns foreground and a
Game is resident/suspended.
The Hub does not execute bytecode directly. It always delegates execution setup to POS. The Hub does not execute bytecode directly. It always delegates execution setup to POS.
@ -219,6 +223,17 @@ It preserves Game VM state but is not execution-eligible except for the bounded
pause handoff and later foreground resume. A VM-backed Shell has a separate VM pause handoff and later foreground resume. A VM-backed Shell has a separate VM
session. A native Shell has no VM session. session. A native Shell has no VM session.
When Hub/Home is foreground and a Game cartridge remains resident/suspended,
PrometeuHub MUST render a red control in the bottom-right of the Hub viewport.
The control MUST display only the resident Game title. It MUST NOT be rendered
for no resident Game, Shell tasks, System tasks, or native Shell tasks.
Clicking the Hub resident Game kill control is a system-owned immediate
termination request. Firmware MUST keep the user in Hub/Home, MUST NOT ask for
confirmation in v1, and MUST NOT resume the killed Game on subsequent Home
actions. The control MUST disappear on the next Hub frame after the resident
Game is no longer present.
## 8 Cartridge Load Flow ## 8 Cartridge Load Flow
Current high-level flow: Current high-level flow:
@ -257,6 +272,28 @@ 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 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.
Manual Hub resident Game kill and destructive different-Game replacement MUST
share the canonical resident-Game termination path. That path MUST:
- close the resident Game task;
- mark its process stopped;
- remove its VM session;
- clear resident Game state and pending Game lifecycle delivery for that task;
- keep or return foreground ownership to Hub/Home;
- transition render ownership to Shell/Hub (`AppMode::Shell`, `app_id = 0`);
- clear the Game lifecycle audio pause state;
- unbind the Game2D frame composer scene;
- shut down cartridge-scoped asset manager state, including slot identity and
physical glyph/scene/sound banks.
After this operation, the killed Game MUST NOT be resumable. Launching that
same Game again from Home is a fresh cartridge load and a fresh VM session.
Manual Hub kill MUST emit an INFO Hub log with the message shape:
```text
Resident game killed from Hub: <title>
```
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`.
When Home launches a discovered Game entry, the request is a system-owned action When Home launches a discovered Game entry, the request is a system-owned action
@ -341,6 +378,9 @@ Expected behavior:
resident Game session; resident Game session;
- returning to the same Game resumes it through the foreground lifecycle and - returning to the same Game resumes it through the foreground lifecycle and
waits for current-epoch Game rendering before visual Game presentation. waits for current-epoch Game rendering before visual Game presentation.
- clicking the red bottom-right resident Game kill control terminates the
resident Game, keeps Home foreground, clears runtime/cartridge residue, and
removes the resume path.
## 13 Relationship to Other Specs ## 13 Relationship to Other Specs