From 0ffb3467b113eeb5742ab870925ceff34b4a2049 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Sun, 5 Jul 2026 01:03:02 +0100 Subject: [PATCH] SystemOS Cartridge Switch Orchestrator --- discussion/index.ndjson | 4 +- ...-systemos-cartridge-switch-orchestrator.md | 73 ++++++-- ...emos-game-cartridge-switch-orchestrator.md | 174 ++++++++++++++++++ ...ce-systemos-game-switch-target-contract.md | 86 +++++++++ ...sident-game-before-switching-cartridges.md | 98 ++++++++++ ...cover-failed-game-switches-back-to-home.md | 86 +++++++++ ...-dummy-boy-visual-switch-test-cartridge.md | 90 +++++++++ ...ess-to-dummy-boy-game-switch-end-to-end.md | 93 ++++++++++ ...tch-contract-and-direct-boot-separation.md | 93 ++++++++++ 9 files changed, 775 insertions(+), 22 deletions(-) create mode 100644 discussion/workflow/decisions/DEC-0039-systemos-game-cartridge-switch-orchestrator.md create mode 100644 discussion/workflow/plans/PLN-0157-introduce-systemos-game-switch-target-contract.md create mode 100644 discussion/workflow/plans/PLN-0158-terminate-resident-game-before-switching-cartridges.md create mode 100644 discussion/workflow/plans/PLN-0159-recover-failed-game-switches-back-to-home.md create mode 100644 discussion/workflow/plans/PLN-0160-add-dummy-boy-visual-switch-test-cartridge.md create mode 100644 discussion/workflow/plans/PLN-0161-validate-stress-to-dummy-boy-game-switch-end-to-end.md create mode 100644 discussion/workflow/plans/PLN-0162-specify-game-switch-contract-and-direct-boot-separation.md diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 519b2791..9c08136e 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,5 +1,5 @@ -{"type":"meta","next_id":{"DSC":44,"AGD":47,"DEC":39,"PLN":157,"LSN":53,"CLSN":1}} -{"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":"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":"open","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":"open","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":"open","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":"open","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":"open","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-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-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"}]} diff --git a/discussion/workflow/agendas/AGD-0044-systemos-cartridge-switch-orchestrator.md b/discussion/workflow/agendas/AGD-0044-systemos-cartridge-switch-orchestrator.md index e0fe0855..476cc33b 100644 --- a/discussion/workflow/agendas/AGD-0044-systemos-cartridge-switch-orchestrator.md +++ b/discussion/workflow/agendas/AGD-0044-systemos-cartridge-switch-orchestrator.md @@ -2,7 +2,7 @@ id: AGD-0044 ticket: system-os-cartridge-switch-orchestrator title: SystemOS Cartridge Switch Orchestrator -status: open +status: accepted created: 2026-07-03 resolved: decision: @@ -90,35 +90,58 @@ pode cair em estados incoerentes: ## Sugestao / Recomendacao -Recomendo a Opcao A agora, com esta agenda aberta como marcador explicito de -escopo futuro. +`DSC-0041` foi fechada e o contrato de foreground/pausa/resume ja existe. A +recomendacao agora deixa de ser adiar e passa a ser fechar uma decisao curta +para o orquestrador de troca `Game A -> Home -> Game B`. -A ordem preferida passa a ser: +O contrato sugerido e: -1. fechar a `AGD-0041` para definir foreground, pausa/suspensao, Shell no - foreground e retorno ao mesmo Game; -2. voltar para esta agenda e decidir o contrato do orquestrador de troca de - cartucho no SystemOS; -3. so entao planejar a execucao de `Game A -> Home -> Game B`. - -Se durante a `AGD-0041` aparecer uma decisao que exige antecipar parte do -orquestrador, esta agenda deve ser reaberta/atualizada com a dependencia -concreta em vez de esconder a troca de cartucho dentro da agenda de foreground. +- trocar para outro Game e uma substituicao controlada, nao uma pausa/resume; +- o Game residente anterior e fechado/descartado; +- a VM session do Game anterior e removida; +- o novo Game sempre recebe uma VM session nova e zerada; +- se o novo load falhar, o sistema volta ao Home/Hub com diagnostico e nao + tenta preservar o Game anterior em v1; +- o loader continua sendo etapa interna, sem possuir politica de lifecycle; +- a evidencia minima deve usar dois cartuchos distintos, incluindo um cartucho + simplista `dummy-boy` alem do stress test. ## Perguntas em Aberto -- [ ] Depois da `AGD-0041`, qual estado representa um Game que sera descartado +- [x] Depois da `AGD-0041`, qual estado representa um Game que sera descartado em vez de retomado? -- [ ] O fechamento do Game atual e observavel para o firmware/game, ou e uma + - Resposta: fechamento/encerramento controlado, nao `PausedSuspended`. O Game + anterior deixa de ser resident/resumable e sua VM session e removida. +- [x] O fechamento do Game atual e observavel para o firmware/game, ou e uma destruicao interna do SystemOS? -- [ ] Quais estados cartridge-scoped devem ser limpos antes do novo load: VM, + - Resposta: deve ser observavel como uma transicao de lifecycle/firmware, mas + nao cooperativo nem bloqueante para o Game. O SystemOS tem autoridade para + encerrar e descartar a sessao. Pode ser emitido um evento de encerramento + para permitir save/flush cooperativo quando existir esse mecanismo, mas a + troca nao deve depender da resposta do Game. +- [x] Quais estados cartridge-scoped devem ser limpos antes do novo load: VM, assets, FS handles, input, audio, render ownership, telemetry, logs? -- [ ] Se o novo cartucho falha ao carregar, o sistema volta ao Home, mostra uma + - Resposta: a troca nao reaproveita VM. O Game anterior e encerrado, sua VM + session e descartada, e o novo Game recebe VM/session nova e zerada. Devem + ser limpos ou reatribuídos os estados cartridge-scoped ligados a VM, + handles abertos, input pendente/barreiras, audio do app, render ownership, + telemetry/debug/crash state do app. Logs historicos podem permanecer como + observabilidade. +- [x] Se o novo cartucho falha ao carregar, o sistema volta ao Home, mostra uma tela de erro, ou tenta preservar o Game anterior? -- [ ] Como a resolucao do novo alvo e representada sem depender de catalogo + - Resposta: o Game anterior ja foi encerrado. Se o novo load falha, a sessao + parcial do novo Game e descartada e o sistema volta ao Home/Hub com + diagnostico. Preservar o Game anterior fica fora de escopo em v1. +- [x] Como a resolucao do novo alvo e representada sem depender de catalogo completo ou `.pmc`? -- [ ] Qual evidencia minima prova `Game A -> Home -> Game B` sem depender de UX + - Resposta: para o contrato minimo, o alvo pode ser um path/entrada ja + resolvido pelo Hub/game library atual. O contrato nao depende de `.pmc` nem + de catalogo final. +- [x] Qual evidencia minima prova `Game A -> Home -> Game B` sem depender de UX final de launcher? + - Resposta: criar um cartucho `dummy-boy` ao lado do stress test. O teste deve + provar `Stress -> Home -> Dummy Boy`, com troca de VM session, identidade de + cartridge distinta e render observavel do novo Game. ## Criterio para Encerrar @@ -139,7 +162,17 @@ A agenda pode virar decisao quando: O novo escopo cobre a troca posterior `Game A -> Home -> Game B`, com orquestracao pelo SystemOS depois que o contrato de foreground estiver fechado. +- 2026-07-05: Apos fechamento de `DSC-0041`, a discussao convergiu para troca + destrutiva simples em v1: ao iniciar outro Game, o Game residente anterior e + encerrado, sua VM session e removida, e o novo Game recebe VM session nova. + Falha de load volta ao Home/Hub com diagnostico. A evidencia minima deve + incluir um novo cartucho `dummy-boy` que desenha um quadrado com cores + oscilando, alem do stress test. +- 2026-07-05: Refinamento: o encerramento do Game anterior pode emitir evento + cooperativo para save/flush, mas esse evento nao e uma permissao nem uma + barreira obrigatoria. O SystemOS continua com autoridade para concluir a troca + e remover a VM session anterior. ## Resolution -Ainda em aberto. +Pronta para virar decisao, pendente confirmacao explicita do usuario. diff --git a/discussion/workflow/decisions/DEC-0039-systemos-game-cartridge-switch-orchestrator.md b/discussion/workflow/decisions/DEC-0039-systemos-game-cartridge-switch-orchestrator.md new file mode 100644 index 00000000..387a9399 --- /dev/null +++ b/discussion/workflow/decisions/DEC-0039-systemos-game-cartridge-switch-orchestrator.md @@ -0,0 +1,174 @@ +--- +id: DEC-0039 +ticket: system-os-cartridge-switch-orchestrator +title: SystemOS Game Cartridge Switch Orchestrator +status: accepted +created: 2026-07-05 +ref_agenda: AGD-0044 +tags: [runtime, os, lifecycle, game, cartridge, architecture] +--- + +## Status + +Open for review. + +## Contexto + +`DEC-0037` fechou o contrato `Game -> Home/Shell -> mesmo Game`: o Game pode +ficar residente, ser pausado/suspenso pelo SystemOS, e depois ser retomado. + +`DEC-0038` fechou o ownership de VM sessions: VM-backed mutable execution state +pertence a sessoes de VM associadas a processos/tarefas, nao a uma VM global do +firmware. + +Esta decision cobre outro fluxo: `Game A -> Home -> Game B`. Nesse caso, o +usuario nao esta retomando o mesmo Game. O usuario esta escolhendo substituir o +Game residente por outro cartucho. Essa substituicao precisa ser orquestrada +pelo SystemOS, nao pelo loader e nao por userland. + +## Decisao + +PROMETEU MUST tratar `Game A -> Home -> Game B` como uma substituicao +controlada de Game, nao como pause/resume. + +Quando o usuario escolher iniciar um Game diferente enquanto ja existe um Game +residente, SystemOS MUST encerrar o Game residente anterior, remover sua +resident state e descartar sua VM session antes de ativar o novo Game como +resident/foreground. + +O Game anterior MAY receber um evento cooperativo de encerramento para permitir +save/flush quando esse mecanismo existir. Esse evento MUST NOT ser uma +permissao, veto ou barreira obrigatoria para a troca. SystemOS MUST manter +autoridade para concluir a troca e remover a VM session anterior mesmo se o +Game nao reagir. + +O novo Game MUST receber uma VM session nova e zerada. A troca MUST NOT +reutilizar a VM session, PC, stack, heap, globals, open handles, cartridge +identity, lifecycle state, debug state ou runtime state do Game anterior. + +O loader/materializador de cartridge MUST permanecer uma etapa interna de +carregamento. Ele MUST NOT possuir politica de lifecycle, foreground, +close/discard, cleanup ou recuperacao de falha. + +Se o novo cartucho falhar ao carregar, SystemOS MUST descartar qualquer session +parcial ou estado cartridge-scoped parcial do novo Game e retornar ao Home/Hub +com diagnostico. V1 MUST NOT tentar preservar ou restaurar o Game anterior +depois que a troca tiver comecado. + +Boot direto por CLI/debug permanece um caminho separado e mais simples. Esta +decision governa troca de Game sob SystemOS depois que o usuario retorna ao +Home/Hub. + +A evidencia minima de implementacao MUST incluir dois test cartridges +distintos: o stress cartridge existente e um novo cartridge `dummy-boy`. +`dummy-boy` MUST renderizar um quadrado visualmente distinto com cor oscilante +para que os testes provem que o segundo Game, e nao um frame/session anterior +stale, esta ativo. + +## Rationale + +Trying to preserve Game A while loading Game B would turn the switch into a +transactional snapshot/rollback problem. That is not needed for v1 and would +pull in VM snapshot correctness, open handle restoration, assets, render +ownership rollback, audio rollback, input state, debugger state, and telemetry +rollback. + +The simpler and safer v1 contract is destructive replacement: + +1. the user requests another Game; +2. SystemOS ends the previous resident Game; +3. SystemOS removes its VM session and cartridge-scoped runtime state; +4. SystemOS attempts to load the new Game into a fresh VM session; +5. success enters the new Game; +6. failure returns to Home/Hub with diagnostic. + +This aligns with `DEC-0037` because pause/suspend remains the same-Game resume +flow. It aligns with `DEC-0038` because VM identity is session-owned and each +Game receives a distinct VM session. + +## Invariantes / Contrato + +- SystemOS is the authority for switching from one Game cartridge to another + under Home/Hub. +- `Game -> Home -> same Game` is pause/resume and remains governed by + `DEC-0037`. +- `Game A -> Home -> Game B` is destructive replacement and is governed by this + decision. +- A Game that is being replaced MUST stop being resident/resumable. +- The previous Game VM session MUST be removed before the new Game becomes the + active resident/foreground Game. +- A cooperative close/terminate/save event MAY be delivered to the previous + Game, but it MUST NOT block replacement. +- The new Game MUST get a fresh VM session. +- The new Game MUST NOT inherit VM execution state, open handles, lifecycle + delivery state, cartridge identity, debug state, telemetry state, or crash + state from the previous Game. +- Render ownership MUST transition through SystemOS ownership policy and stale + submissions from the previous Game MUST NOT be presented after the switch. +- Input pending/barrier state MUST be cleared or made safe across the switch. +- App audio from the previous Game MUST be stopped or detached from the active + app before the new Game becomes foreground. +- Logs MAY remain as historical observability; they are not cartridge execution + state. +- If new Game load fails, Home/Hub is the recovery state for v1. +- V1 does not preserve, restore, or rollback to the previous Game after a + switch begins. +- The launcher target MAY be a path or already-resolved game-library entry for + v1. `.pmc` and final catalog UX are out of scope. +- `run_cart`, if retained, is not a userland command and not the switch + orchestrator. + +## Impactos + +- **Runtime / SystemOS:** needs an explicit Game switch orchestration path that + closes/removes the current resident Game session before loading the next Game. +- **Lifecycle:** needs a controlled replacement transition distinct from + pause/suspend/resume. +- **VM sessions:** previous Game session removal and new Game session creation + are mandatory switch steps. +- **Firmware:** should observe macro states such as Home, loading, load failure, + and GameRunning, but should not own switch policy. +- **Hub / launcher:** should request a switch through SystemOS using a resolved + target; it should not call a loader directly as lifecycle authority. +- **Loader:** remains a materialization step and returns success/failure without + owning cleanup policy. +- **Renderer:** render ownership/stale submission invalidation must prove the + new Game owns current presentation after success. +- **Input/audio:** previous Game input/audio must not leak into the new Game. +- **Tests:** need a second visually distinct test cartridge, `dummy-boy`, to + prove Game identity and render transition. + +## Alternativas Descartadas + +- **Preserve Game A until Game B loads successfully:** rejected for v1 because it + requires rollback semantics across VM, assets, handles, render ownership, + input, audio, debugger, and telemetry. +- **Treat Game A -> Game B as pause/resume:** rejected because a different Game + should not inherit resumable state from the previous Game. +- **Let the loader close the previous Game:** rejected because loader/materializer + should not own lifecycle policy. +- **Reuse the previous VM session for the new Game:** rejected because it + violates VM session ownership and risks state leakage. +- **Depend on `.pmc` or final catalog UX now:** rejected because the lifecycle + contract can be validated using path/game-library targets first. + +## Referencias + +- Source agenda: `AGD-0044` +- Foreground stack and Game pause contract: `DEC-0037` +- VM session ownership for VM-backed processes: `DEC-0038` +- SystemOS lifecycle/process/task authority: `DSC-0032` +- Launch authority lesson: `LSN-0051` +- Foreground/session ownership lesson: `LSN-0052` + +## Propagacao Necessaria + +- Add/update runtime spec for Game cartridge switching under SystemOS. +- Add implementation plans for: + - SystemOS switch orchestration; + - resident Game termination/session removal; + - fresh session load for the new Game; + - failure recovery to Home/Hub; + - `dummy-boy` test cartridge; + - end-to-end `Stress -> Home -> Dummy Boy` validation. +- Ensure host/debug direct boot remains separate from SystemOS Game switch. diff --git a/discussion/workflow/plans/PLN-0157-introduce-systemos-game-switch-target-contract.md b/discussion/workflow/plans/PLN-0157-introduce-systemos-game-switch-target-contract.md new file mode 100644 index 00000000..dc71d06a --- /dev/null +++ b/discussion/workflow/plans/PLN-0157-introduce-systemos-game-switch-target-contract.md @@ -0,0 +1,86 @@ +--- +id: PLN-0157 +ticket: system-os-cartridge-switch-orchestrator +title: Introduce SystemOS Game Switch Target Contract +status: open +created: 2026-07-05 +ref_decisions: [DEC-0039] +tags: [runtime, os, lifecycle, game, cartridge, architecture] +--- + +## Briefing + +DEC-0039 requires Game-to-Game switching under Home/Hub to be owned by SystemOS. +Before destructive replacement can be implemented, Hub/Firmware/SystemOS need a +small explicit contract for "launch this resolved Game target as a replacement" +that is separate from direct boot and from loader internals. + +## Objective + +Introduce a SystemOS-owned Game switch request/target abstraction that can carry +a resolved cartridge path or game-library entry from Hub/Home into the switch +orchestrator without making the loader or userland the lifecycle authority. + +## Dependencies + +- Source decision: DEC-0039. +- Builds on DEC-0037 and DEC-0038 as already implemented. +- Must be implemented before PLN-0158, PLN-0159, and PLN-0161. + +## Scope + +- Define a minimal Game switch target type, such as `GameSwitchTarget` or + `CartridgeLaunchTarget`, in the SystemOS/Firmware boundary. +- Route Hub game-library launch actions through that target contract instead of + treating a path as an implicit lifecycle operation. +- Keep direct boot/debug boot paths separate from SystemOS Game switching. +- Add tests proving the target preserves cartridge identity/path without + starting lifecycle replacement by itself. + +## Non-Goals + +- Do not implement destructive replacement in this plan. +- Do not add `.pmc`, final catalog UX, or a new launcher UI. +- Do not change direct CLI/debug boot behavior. +- Do not add background execution. + +## Execution Method + +1. Inspect `crates/console/prometeu-system/src/services/game_library.rs`, + `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs`, + and `crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs`. +2. Add a minimal launch target model at the SystemOS/Firmware boundary: + - resolved cartridge path; + - optional app_id/title metadata if already available; + - no loader-owned lifecycle policy. +3. Update Hub action plumbing so `SystemProfileAction::LaunchGame` carries the + resolved target type or maps immediately into it at the firmware boundary. +4. Add a placeholder SystemOS/Firmware entry point for Game switching that + accepts the target but still delegates to the existing load path until + PLN-0158 changes replacement behavior. +5. Add unit tests for target construction and path propagation. +6. Keep direct `BootTarget::Cartridge` behavior unchanged. + +## Acceptance Criteria + +- There is an explicit type or function contract representing a resolved + SystemOS Game switch target. +- Hub/Home no longer treats a raw path as lifecycle authority. +- The loader remains a materialization step, not the switch orchestrator. +- Direct boot/debug boot code paths remain separate and behaviorally unchanged. +- Tests prove target identity is carried without implicitly closing or loading a + Game. + +## Tests + +- `cargo test -p prometeu-system` +- `cargo test -p prometeu-firmware` +- `cargo test -p prometeu-host-desktop-winit` +- `cargo clippy -p prometeu-system -p prometeu-firmware -p prometeu-host-desktop-winit --all-targets -- -D warnings` + +## Affected Artifacts + +- `crates/console/prometeu-system/src/services/game_library.rs` +- `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs` +- `crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs` +- `crates/console/prometeu-firmware/src/firmware/firmware.rs` diff --git a/discussion/workflow/plans/PLN-0158-terminate-resident-game-before-switching-cartridges.md b/discussion/workflow/plans/PLN-0158-terminate-resident-game-before-switching-cartridges.md new file mode 100644 index 00000000..d2176204 --- /dev/null +++ b/discussion/workflow/plans/PLN-0158-terminate-resident-game-before-switching-cartridges.md @@ -0,0 +1,98 @@ +--- +id: PLN-0158 +ticket: system-os-cartridge-switch-orchestrator +title: Terminate Resident Game Before Switching Cartridges +status: open +created: 2026-07-05 +ref_decisions: [DEC-0039] +tags: [runtime, os, lifecycle, game, cartridge, architecture] +--- + +## Briefing + +DEC-0039 defines `Game A -> Home -> Game B` as destructive replacement. The +current same-Game resume flow keeps the resident Game session alive; switching +to a different Game must instead close/remove that resident session and create a +fresh session for the new Game. + +## Objective + +Implement the SystemOS lifecycle/session operation that terminates the current +resident Game before loading a different Game cartridge. + +## Dependencies + +- Source decision: DEC-0039. +- Requires PLN-0157 target contract. +- Should be implemented before PLN-0159 and PLN-0161. + +## Scope + +- Add a controlled resident Game termination/replacement operation to SystemOS + lifecycle/session services. +- Optionally emit a cooperative terminate/close/save lifecycle event when the + current event model can carry it, but do not block replacement on it. +- Remove the previous Game from resident/resumable state. +- Remove the previous Game VM session before activating the new Game. +- Clear or reassign app-scoped state that cannot leak into the new Game: + session VM, open handles, pending lifecycle state, input barrier/pending + input, audio active app state, render ownership, telemetry/debug/crash state. + +## Non-Goals + +- Do not preserve Game A for rollback. +- Do not implement failed-load recovery beyond surfacing errors; that is + PLN-0159. +- Do not add background execution or multiple resident Games. +- Do not build final launcher UX. + +## Execution Method + +1. Inspect lifecycle/session state in: + - `crates/console/prometeu-system/src/os/lifecycle.rs`; + - `crates/console/prometeu-system/src/os/facades/sessions.rs`; + - `crates/console/prometeu-system/src/services/foreground`; + - `crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs`; + - `crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs`. +2. Add a `replace_resident_game` or equivalent operation that: + - finds the current resident Game; + - marks its task/process closed or stopped according to existing lifecycle + semantics; + - removes the resident Game entry from foreground stack/lifecycle state; + - removes its VM session. +3. Ensure same-Game resume still bypasses replacement and remains governed by + DEC-0037. +4. Update game launch from Home so launching a different app_id triggers + replacement before load. +5. Ensure render ownership transitions away from the old Game before the new + Game becomes foreground. +6. Add focused tests for resident Game termination and session removal. + +## Acceptance Criteria + +- Launching a different Game from Home closes/removes the resident Game rather + than resuming it. +- The previous Game VM session is absent before the new Game is made active. +- Same-Game selection still resumes the existing resident Game. +- A cooperative close/terminate event, if added, is non-blocking. +- No previous Game VM, handle, lifecycle, render, or debug state is reused by + the new Game. + +## Tests + +- `cargo test -p prometeu-system` +- `cargo test -p prometeu-firmware` +- `cargo clippy -p prometeu-system -p prometeu-firmware --all-targets -- -D warnings` +- Add tests for: + - different Game launch removes previous resident session; + - same Game launch resumes existing resident session; + - old Game task/process state is closed/stopped; + - old Game session cannot be resolved after replacement starts. + +## Affected Artifacts + +- `crates/console/prometeu-system/src/os/lifecycle.rs` +- `crates/console/prometeu-system/src/os/facades/sessions.rs` +- `crates/console/prometeu-system/src/services/foreground` +- `crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs` +- `crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs` diff --git a/discussion/workflow/plans/PLN-0159-recover-failed-game-switches-back-to-home.md b/discussion/workflow/plans/PLN-0159-recover-failed-game-switches-back-to-home.md new file mode 100644 index 00000000..06dba643 --- /dev/null +++ b/discussion/workflow/plans/PLN-0159-recover-failed-game-switches-back-to-home.md @@ -0,0 +1,86 @@ +--- +id: PLN-0159 +ticket: system-os-cartridge-switch-orchestrator +title: Recover Failed Game Switches Back To Home +status: open +created: 2026-07-05 +ref_decisions: [DEC-0039] +tags: [runtime, os, lifecycle, game, cartridge, architecture] +--- + +## Briefing + +DEC-0039 rejects preserving Game A after a switch begins. If Game B fails to +load, the system must discard partial Game B state and return to Home/Hub with a +diagnostic, not attempt rollback to Game A. + +## Objective + +Implement controlled failed-switch recovery to Home/Hub after destructive Game +replacement begins. + +## Dependencies + +- Source decision: DEC-0039. +- Requires PLN-0157 target contract. +- Requires PLN-0158 resident Game termination/session removal. + +## Scope + +- Detect load/init failure while switching to a different Game. +- Discard any partial new Game task/session/window/render/input/audio state. +- Return firmware/SystemOS to Home/Hub. +- Log or expose a diagnostic that Home can surface or tests can assert. +- Ensure previous Game is not restored after switch failure. + +## Non-Goals + +- Do not implement transactional rollback. +- Do not preserve the previous Game after switch begins. +- Do not design final user-facing error UI. +- Do not change direct boot failure behavior unless needed to keep paths + separate. + +## Execution Method + +1. Inspect existing load failure flow in + `crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs`. +2. Add a switch-specific failure outcome or context flag that distinguishes + SystemOS Game switching from direct boot load. +3. On switch load failure: + - remove partial new VM session/task/process if created; + - clear partial cartridge-scoped state; + - transition to `HubHome` instead of app crash when appropriate for switch + recovery; + - log a diagnostic containing target identity/path and failure summary. +4. Preserve existing direct boot and explicit load failure tests unless a direct + boot path intentionally still goes to crash. +5. Add tests for bad Game B after Game A was already terminated. + +## Acceptance Criteria + +- Failed `Game A -> Home -> Broken Game B` returns to Home/Hub. +- Previous Game A is not resident, resumable, or restored. +- Partial Game B VM session/task/process state is removed or closed. +- A diagnostic is logged or otherwise observable. +- Existing direct boot/debug boot failure semantics remain separate. + +## Tests + +- `cargo test -p prometeu-firmware` +- `cargo test -p prometeu-system` +- `cargo test -p prometeu-host-desktop-winit` +- `cargo clippy -p prometeu-system -p prometeu-firmware -p prometeu-host-desktop-winit --all-targets -- -D warnings` +- Add tests for: + - switch failure returns Home; + - old Game not restored; + - partial new session cleanup; + - direct boot failure path remains unchanged. + +## Affected Artifacts + +- `crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs` +- `crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs` +- `crates/console/prometeu-firmware/src/firmware/firmware.rs` +- `crates/console/prometeu-system/src/os/facades/sessions.rs` +- `crates/console/prometeu-system/src/os/lifecycle.rs` diff --git a/discussion/workflow/plans/PLN-0160-add-dummy-boy-visual-switch-test-cartridge.md b/discussion/workflow/plans/PLN-0160-add-dummy-boy-visual-switch-test-cartridge.md new file mode 100644 index 00000000..34ad7d49 --- /dev/null +++ b/discussion/workflow/plans/PLN-0160-add-dummy-boy-visual-switch-test-cartridge.md @@ -0,0 +1,90 @@ +--- +id: PLN-0160 +ticket: system-os-cartridge-switch-orchestrator +title: Add Dummy Boy Visual Switch Test Cartridge +status: open +created: 2026-07-05 +ref_decisions: [DEC-0039] +tags: [runtime, os, lifecycle, game, cartridge, architecture] +--- + +## Briefing + +DEC-0039 requires minimum evidence using two distinct test cartridges. The +existing stress cartridge proves execution/logging but is not visually distinct +enough for switch validation. A second cartridge, `dummy-boy`, must render an +oscillating-color square. + +## Objective + +Add a simple `test-cartridges/dummy-boy` cartridge that renders a visible square +with changing colors so Game switching can prove visual/session identity. + +## Dependencies + +- Source decision: DEC-0039. +- Can be implemented independently of PLN-0157 through PLN-0159. +- Required before PLN-0161 end-to-end validation. + +## Scope + +- Add `test-cartridges/dummy-boy/manifest.json`. +- Generate or add `test-cartridges/dummy-boy/program.pbx`. +- Add empty or minimal assets payload if the loader requires `assets.pa`. +- Implement Dummy Boy behavior: + - Game cartridge identity distinct from stress; + - deterministic visible square; + - color oscillates across frames; + - no dependency on final launcher UX. +- Add build/generation documentation or tests so the cartridge can be + regenerated safely if needed. + +## Non-Goals + +- Do not add final game content. +- Do not add `.pmc`. +- Do not depend on host screenshots for the first validation unless an existing + harness already supports it. +- Do not change stress cartridge behavior. + +## Execution Method + +1. Inspect the stress cartridge and any PBX generator tooling: + - `test-cartridges/stress-console`; + - `crates/tools/pbxgen-stress`; + - bytecode assembler helpers in `crates/console/prometeu-bytecode`. +2. Choose the smallest maintainable generator path: + - extend existing PBX generator if appropriate; or + - add a focused `pbxgen-dummy-boy` tool; or + - add deterministic generated PBX with source instructions. +3. Create `manifest.json` with unique `app_id`, title `Dummy Boy`, Game mode, + and version. +4. Generate `program.pbx` that renders the square and advances color over + frames. +5. Add tests or smoke checks that the cartridge is discoverable by games-root + discovery. + +## Acceptance Criteria + +- `test-cartridges/dummy-boy` exists and loads as a Game cartridge. +- Dummy Boy has a unique `app_id` and title distinct from Stress. +- Dummy Boy renders a visible square. +- Square color changes deterministically over time. +- Games-root discovery sees both Stress and Dummy Boy. +- Existing stress cartridge remains unchanged. + +## Tests + +- `cargo test -p prometeu-hal` +- `cargo test -p prometeu-system` +- `cargo test -p prometeu-firmware` +- Run any cartridge generator tests added by this plan. +- Add or update tests for games-root discovery including Dummy Boy. + +## Affected Artifacts + +- `test-cartridges/dummy-boy/manifest.json` +- `test-cartridges/dummy-boy/program.pbx` +- `test-cartridges/dummy-boy/assets.pa` if required +- `crates/tools/*` cartridge generator tooling if needed +- `crates/console/prometeu-system/src/services/game_library.rs` tests if needed diff --git a/discussion/workflow/plans/PLN-0161-validate-stress-to-dummy-boy-game-switch-end-to-end.md b/discussion/workflow/plans/PLN-0161-validate-stress-to-dummy-boy-game-switch-end-to-end.md new file mode 100644 index 00000000..6889679e --- /dev/null +++ b/discussion/workflow/plans/PLN-0161-validate-stress-to-dummy-boy-game-switch-end-to-end.md @@ -0,0 +1,93 @@ +--- +id: PLN-0161 +ticket: system-os-cartridge-switch-orchestrator +title: Validate Stress To Dummy Boy Game Switch End To End +status: open +created: 2026-07-05 +ref_decisions: [DEC-0039] +tags: [runtime, os, lifecycle, game, cartridge, architecture] +--- + +## Briefing + +DEC-0039 requires proof that `Game A -> Home -> Game B` creates a fresh Game +session and does not present stale state from Game A. The minimum evidence is +switching from Stress to Dummy Boy. + +## Objective + +Add end-to-end validation for `Stress -> Home -> Dummy Boy` through the real +Hub/Home flow, proving lifecycle, VM session, cartridge identity, and render +ownership switch correctly. + +## Dependencies + +- Source decision: DEC-0039. +- Requires PLN-0157 target contract. +- Requires PLN-0158 destructive replacement. +- Requires PLN-0159 failed-switch recovery for negative path assertions. +- Requires PLN-0160 Dummy Boy cartridge. + +## Scope + +- Add firmware/system tests that drive: + - launch Stress from games root; + - request Home; + - launch Dummy Boy; + - assert Stress session is gone; + - assert Dummy Boy session is active; + - assert cartridge identity and render ownership belong to Dummy Boy. +- Add a negative end-to-end test for broken Game B returning to Home if not + already covered by PLN-0159. +- Use existing test platform/render submission inspection where possible. + +## Non-Goals + +- Do not require final launcher UX. +- Do not add screenshot-based host automation unless existing test utilities + make it cheap and deterministic. +- Do not implement additional Game-to-Game variants beyond Stress to Dummy Boy. + +## Execution Method + +1. Inspect existing firmware tests in + `crates/console/prometeu-firmware/src/firmware/firmware.rs`. +2. Reuse existing `TestGameRoot` or games-root helpers to expose Stress and + Dummy Boy. +3. Drive input through Hub/Home selection rather than calling cartridge load + directly when possible. +4. Assert lifecycle/session invariants: + - old task closed/stopped; + - old VM session removed; + - new VM session created; + - foreground owner is new Game; + - current cartridge identity is Dummy Boy. +5. Assert render invariants: + - render ownership epoch belongs to Dummy Boy app identity; + - stale Stress submissions are not accepted after switch; + - latest observable Game frame comes from Dummy Boy when render inspection is + available. +6. Add a focused test for failure path if missing after PLN-0159. + +## Acceptance Criteria + +- End-to-end test proves Stress can be replaced by Dummy Boy from Home. +- Stress is not resumable after switching to Dummy Boy. +- Dummy Boy receives a fresh VM session. +- Cartridge identity and active render ownership are Dummy Boy after switch. +- Failure path returns Home and does not restore Stress. +- Tests are deterministic and do not rely on manual host interaction. + +## Tests + +- `cargo test -p prometeu-firmware` +- `cargo test -p prometeu-system` +- `cargo test -p prometeu-host-desktop-winit` +- `cargo clippy -p prometeu-system -p prometeu-firmware -p prometeu-host-desktop-winit --all-targets -- -D warnings` + +## Affected Artifacts + +- `crates/console/prometeu-firmware/src/firmware/firmware.rs` +- `crates/console/prometeu-system/src/services/game_library.rs` +- `test-cartridges/dummy-boy` +- Host/render test utilities if needed diff --git a/discussion/workflow/plans/PLN-0162-specify-game-switch-contract-and-direct-boot-separation.md b/discussion/workflow/plans/PLN-0162-specify-game-switch-contract-and-direct-boot-separation.md new file mode 100644 index 00000000..b4d85d48 --- /dev/null +++ b/discussion/workflow/plans/PLN-0162-specify-game-switch-contract-and-direct-boot-separation.md @@ -0,0 +1,93 @@ +--- +id: PLN-0162 +ticket: system-os-cartridge-switch-orchestrator +title: Specify Game Switch Contract And Direct Boot Separation +status: open +created: 2026-07-05 +ref_decisions: [DEC-0039] +tags: [runtime, os, lifecycle, game, cartridge, architecture] +--- + +## Briefing + +DEC-0039 must be reflected in the canonical runtime specs after the operational +contract is implemented or alongside implementation. The spec must distinguish +same-Game resume, Game replacement under SystemOS, and direct boot/debug boot. + +## Objective + +Update the canonical runtime documentation to describe SystemOS Game cartridge +switching and to keep direct boot/debug boot separate from Home/Hub-driven Game +replacement. + +## Dependencies + +- Source decision: DEC-0039. +- Can be implemented before code if the spec is written as intended behavior. +- Should be reconciled after PLN-0157 through PLN-0161 if implementation names + differ from initial plan names. + +## Scope + +- Update relevant files under `docs/specs/runtime/`, especially: + - `12-firmware-pos-and-prometeuhub.md`; + - `13-cartridge.md`; + - `14-boot-profiles.md`; + - `09-events-and-concurrency.md` if lifecycle events need mention; + - `10-debug-inspection-and-profiling.md` if debugger separation needs note. +- Document: + - SystemOS authority for Game switching; + - destructive replacement semantics; + - optional non-blocking terminate/save event; + - fresh VM session for new Game; + - failed switch recovery to Home/Hub; + - direct boot/debug boot separation; + - test cartridge evidence requirement. + +## Non-Goals + +- Do not document `.pmc` or final catalog UX as required. +- Do not specify background execution. +- Do not revise DEC-0037 or DEC-0038 semantics. +- Do not write lesson material; housekeeping will decide lessons after + execution. + +## Execution Method + +1. Read the runtime spec files listed in scope. +2. Add a Game switching section in the most appropriate canonical spec file. +3. Cross-reference existing Home/Hub, cartridge, boot profile, and debug boot + sections. +4. Ensure language is English and normative enough for future implementers: + `MUST`, `MUST NOT`, `MAY`, `SHOULD`. +5. Verify no non-English agenda language leaks into specs. +6. Run docs grep checks for the newly introduced terms. + +## Acceptance Criteria + +- Specs explicitly distinguish: + - same-Game pause/resume; + - Game A to Game B destructive replacement; + - direct boot/debug boot. +- Specs state that SystemOS owns Game switching policy. +- Specs state that a new Game gets a fresh VM session. +- Specs state that failed switch returns Home/Hub and does not restore the old + Game in v1. +- Specs mention Dummy Boy or equivalent two-cartridge evidence only as test + evidence, not as runtime feature. +- Documentation is English. + +## Tests + +- `rg -n "Game switch|destructive replacement|direct boot|Dummy Boy|VM session" docs/specs/runtime` +- `discussion validate` +- Run code tests only if this plan is implemented together with code changes: + `cargo test -p prometeu-system -p prometeu-firmware` + +## Affected Artifacts + +- `docs/specs/runtime/12-firmware-pos-and-prometeuhub.md` +- `docs/specs/runtime/13-cartridge.md` +- `docs/specs/runtime/14-boot-profiles.md` +- `docs/specs/runtime/09-events-and-concurrency.md` +- `docs/specs/runtime/10-debug-inspection-and-profiling.md`