From de53eb5ad72e7ff57db3d0e9b94cafb20d60a6be Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Sun, 5 Jul 2026 16:27:05 +0100 Subject: [PATCH] Hub Suspended Game Kill Affordance --- discussion/index.ndjson | 6 +- ...s-lifecycle-replacement-not-loader-work.md | 67 +++++++ ...ill-must-share-game-termination-cleanup.md | 72 +++++++ ...-systemos-cartridge-switch-orchestrator.md | 178 ------------------ ...0047-hub-suspended-game-kill-affordance.md | 91 --------- ...emos-game-cartridge-switch-orchestrator.md | 174 ----------------- ...0040-hub-suspended-game-kill-affordance.md | 73 ------- ...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 --------- ...-render-hub-suspended-game-kill-control.md | 85 --------- ...pose-resident-game-termination-contract.md | 93 --------- ...-0165-validate-hub-kill-flow-end-to-end.md | 92 --------- ...hub-kill-contract-spec-and-lesson-hooks.md | 78 -------- 17 files changed, 142 insertions(+), 1413 deletions(-) create mode 100644 discussion/lessons/DSC-0043-system-os-cartridge-switch-orchestrator/LSN-0053-game-switching-is-lifecycle-replacement-not-loader-work.md create mode 100644 discussion/lessons/DSC-0044-hub-suspended-game-kill-affordance/LSN-0054-manual-hub-kill-must-share-game-termination-cleanup.md delete mode 100644 discussion/workflow/agendas/AGD-0044-systemos-cartridge-switch-orchestrator.md delete mode 100644 discussion/workflow/agendas/AGD-0047-hub-suspended-game-kill-affordance.md delete mode 100644 discussion/workflow/decisions/DEC-0039-systemos-game-cartridge-switch-orchestrator.md delete mode 100644 discussion/workflow/decisions/DEC-0040-hub-suspended-game-kill-affordance.md delete mode 100644 discussion/workflow/plans/PLN-0157-introduce-systemos-game-switch-target-contract.md delete mode 100644 discussion/workflow/plans/PLN-0158-terminate-resident-game-before-switching-cartridges.md delete mode 100644 discussion/workflow/plans/PLN-0159-recover-failed-game-switches-back-to-home.md delete mode 100644 discussion/workflow/plans/PLN-0160-add-dummy-boy-visual-switch-test-cartridge.md delete mode 100644 discussion/workflow/plans/PLN-0161-validate-stress-to-dummy-boy-game-switch-end-to-end.md delete mode 100644 discussion/workflow/plans/PLN-0162-specify-game-switch-contract-and-direct-boot-separation.md delete mode 100644 discussion/workflow/plans/PLN-0163-render-hub-suspended-game-kill-control.md delete mode 100644 discussion/workflow/plans/PLN-0164-expose-resident-game-termination-contract.md delete mode 100644 discussion/workflow/plans/PLN-0165-validate-hub-kill-flow-end-to-end.md delete mode 100644 discussion/workflow/plans/PLN-0166-publish-hub-kill-contract-spec-and-lesson-hooks.md diff --git a/discussion/index.ndjson b/discussion/index.ndjson index daa693f8..6e4ca8a2 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,6 +1,6 @@ -{"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":"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":"meta","next_id":{"DSC":45,"AGD":48,"DEC":41,"PLN":167,"LSN":55,"CLSN":1}} +{"type":"discussion","id":"DSC-0044","status":"done","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":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0054","file":"discussion/lessons/DSC-0044-hub-suspended-game-kill-affordance/LSN-0054-manual-hub-kill-must-share-game-termination-cleanup.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]} +{"type":"discussion","id":"DSC-0043","status":"done","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":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0053","file":"discussion/lessons/DSC-0043-system-os-cartridge-switch-orchestrator/LSN-0053-game-switching-is-lifecycle-replacement-not-loader-work.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]} {"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/lessons/DSC-0043-system-os-cartridge-switch-orchestrator/LSN-0053-game-switching-is-lifecycle-replacement-not-loader-work.md b/discussion/lessons/DSC-0043-system-os-cartridge-switch-orchestrator/LSN-0053-game-switching-is-lifecycle-replacement-not-loader-work.md new file mode 100644 index 00000000..c5f2525b --- /dev/null +++ b/discussion/lessons/DSC-0043-system-os-cartridge-switch-orchestrator/LSN-0053-game-switching-is-lifecycle-replacement-not-loader-work.md @@ -0,0 +1,67 @@ +--- +id: LSN-0053 +ticket: system-os-cartridge-switch-orchestrator +title: Game Switching Is Lifecycle Replacement, Not Loader Work +created: 2026-07-05 +tags: [runtime, os, lifecycle, game, cartridge] +--- + +## Context + +PROMETEU supports two superficially similar flows: + +- `Game -> Home -> same Game`, which is pause/suspend/resume. +- `Game A -> Home -> Game B`, which is destructive replacement. + +The second flow is not a loader feature. It is a SystemOS lifecycle operation +that happens to use the cartridge loader after the old resident Game has been +removed from resumable state. + +## Key Decisions + +### SystemOS Game Cartridge Switch Orchestrator + +**What:** A different-Game launch from Home terminates the previous resident +Game before loading the new cartridge. The new Game receives a fresh VM session. + +**Why:** Reusing or preserving the old Game while the new Game loads creates a +rollback problem across VM state, handles, assets, input, audio, render +ownership, debug state, and lifecycle delivery. V1 does not need that +transactional model. + +**Trade-offs:** Failed replacement returns to Home and does not restore the old +Game. This is intentionally simpler than snapshot/rollback and makes state +ownership visible in tests. + +## Patterns and Algorithms + +Use a resolved SystemOS switch target, not a guest syscall, for Home launches. +The target carries cartridge path and identity, while SystemOS owns the policy: + +1. detect whether the selected Game matches the resident `app_id`; +2. resume if it is the same Game; +3. terminate the old resident Game if it is different; +4. load the new cartridge through the normal loader; +5. create and initialize a fresh VM session; +6. return to Home on replacement failure without restoring the previous Game. + +The loader stays a materializer. It does not close tasks, remove sessions, +repair foreground state, or own failure recovery. + +## Pitfalls + +- Treating a different Game as a resume path leaks VM execution state. +- Letting the loader own lifecycle cleanup hides policy in the wrong layer. +- Keeping the old Game as rollback state requires correctness across assets, + render ownership, input barriers, audio, open handles, and debugger state. +- A switch test with only one cartridge cannot prove identity replacement. + +## Takeaways + +- Same-Game Home selection is resume; different-Game Home selection is + destructive replacement. +- SystemOS owns cartridge switching policy; the cartridge loader only loads. +- Replacement failure should be a clean Home state, not a rollback to the old + Game. +- End-to-end switch tests need visually distinct cartridges to catch stale + session or stale frame reuse. diff --git a/discussion/lessons/DSC-0044-hub-suspended-game-kill-affordance/LSN-0054-manual-hub-kill-must-share-game-termination-cleanup.md b/discussion/lessons/DSC-0044-hub-suspended-game-kill-affordance/LSN-0054-manual-hub-kill-must-share-game-termination-cleanup.md new file mode 100644 index 00000000..b82c5aa7 --- /dev/null +++ b/discussion/lessons/DSC-0044-hub-suspended-game-kill-affordance/LSN-0054-manual-hub-kill-must-share-game-termination-cleanup.md @@ -0,0 +1,72 @@ +--- +id: LSN-0054 +ticket: hub-suspended-game-kill-affordance +title: Manual Hub Kill Must Share Game Termination Cleanup +created: 2026-07-05 +tags: [hub, lifecycle, game, ui, assets] +--- + +## Context + +After a Game returns to Home, the Game can remain resident and suspended so it +can be resumed later. That state needs a visible, direct way to terminate the +resident Game without launching another cartridge just to force replacement. + +The Hub kill affordance solved the UX gap, but the durable engineering lesson is +the cleanup boundary: manual kill must not become a second, partial termination +path. + +## Key Decisions + +### Hub Suspended Game Kill Affordance + +**What:** Hub renders a red bottom-right control when a Game is resident and +suspended. The control shows only the Game title. Clicking it immediately +terminates the resident Game and keeps the user in Hub. + +**Why:** The user can distinguish "resume this Game" from "discard this resident +Game" without starting a different cartridge. Reusing the canonical termination +path prevents a repeat of stale scene/glyph/asset state bugs. + +**Trade-offs:** V1 has no confirmation step. The destructive nature is carried +by placement, color, and the fact that the target Game is already out of +foreground. + +## Patterns and Algorithms + +Manual Hub kill and destructive Game replacement should call the same resident +Game termination helper. That helper is responsible for the whole runtime +surface: + +- close the Game task; +- stop the process; +- remove the VM session; +- clear resident Game state and task-scoped lifecycle delivery; +- restore Shell/Hub render ownership; +- clear lifecycle audio pause state; +- unbind the Game2D composer scene; +- shut down cartridge-scoped asset manager state and physical banks; +- emit explicit Hub/POS observability for manual kill. + +The Hub itself should emit a high-level action such as `KillResidentGame`; it +should not know how to clean runtime subsystems. + +## Pitfalls + +- A UI-only kill that removes a task but leaves assets or composer binding alive + can still fail later when another Game renders. +- A cleanup-only helper without an end-to-end Hub click test can miss the + interaction between hitbox, foreground ownership, render owner, and no-resume. +- Hard-coded click coordinates in tests make the UI contract harder to maintain; + expose the layout hitbox when tests need to exercise it. + +## Takeaways + +- Visible system controls should produce system actions, not direct subsystem + mutation from UI code. +- Manual kill and Game replacement are variants of the same resident Game + termination contract. +- Cleanup tests should prove both logical state removal and visible-frame + behavior: the control appears before kill and disappears after kill. +- "No resume after kill" is as important as "task closed" because resumability + is the user-facing state. diff --git a/discussion/workflow/agendas/AGD-0044-systemos-cartridge-switch-orchestrator.md b/discussion/workflow/agendas/AGD-0044-systemos-cartridge-switch-orchestrator.md deleted file mode 100644 index 476cc33b..00000000 --- a/discussion/workflow/agendas/AGD-0044-systemos-cartridge-switch-orchestrator.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -id: AGD-0044 -ticket: system-os-cartridge-switch-orchestrator -title: SystemOS Cartridge Switch Orchestrator -status: accepted -created: 2026-07-03 -resolved: -decision: -tags: [runtime, os, lifecycle, game, cartridge, architecture] ---- - -## Contexto - -A `AGD-0041` cobre o caso `Game -> Home/Shell -> mesmo Game`: o usuario sai do -foreground do jogo, o SO assume a tela, Shell/Hub pode rodar, e depois o mesmo -Game e retomado. - -Existe um segundo caso, diferente, que nao deve ser escondido dentro da -`AGD-0041`: `Game A -> Home -> Game B`. - -Nesse fluxo, o usuario esta com um Game rodando, aperta Home, volta para o SO e -pede para iniciar outro jogo. O SystemOS nao deve simplesmente chamar um loader -por cima do estado atual. Ele precisa orquestrar a substituicao do app corrente: -fechar ou descartar o Game residente, limpar estado cartridge-scoped, resolver o -novo alvo, carregar o proximo cartucho e entrar no novo estado de firmware. - -Essa agenda tambem se relaciona com a `AGD-0003 / system-run-cart`: `run_cart`, -se existir, nao e userland e nao e o orquestrador. O carregador de cartucho e -apenas uma etapa dentro de uma transicao comandada pelo SystemOS. - -## Problema - -Sem um orquestrador explicito de troca de cartucho no SystemOS, a plataforma -pode cair em estados incoerentes: - -- carregar um novo Game sem fechar corretamente o Game anterior; -- reaproveitar estado VM, assets, input, audio, render ou telemetria do cartucho - anterior; -- misturar boot direto por linha de comando com troca de app sob o SO; -- deixar o loader decidir lifecycle, quando ele deveria apenas materializar o - cartucho alvo; -- tentar implementar `Home -> outro Game` antes de existir o contrato de - foreground/pausa definido pela `AGD-0041`. - -## Pontos Criticos - -- Esta agenda deve ser executada depois da `AGD-0041`. -- `Game -> Home -> mesmo Game` fica fora desta agenda. -- O SystemOS deve ser a autoridade da troca entre cartuchos sob o SO. -- O loader nao deve possuir politica de fechamento, pausa, foreground ou - cleanup. -- Boot direto por CLI/debug continua sendo caminho separado e mais simples. -- A troca para outro Game deve tratar falha de load sem deixar o sistema em - estado parcialmente substituido. -- `.pmc`, catalogo completo e UX final de launcher continuam fora de escopo, - salvo se forem necessarios para definir o contrato minimo. - -## Opcoes - -### Opcao A - Adiar tudo para depois da AGD-0041 - -- **Abordagem:** manter esta agenda como registro de escopo futuro; primeiro - fechar e implementar o contrato `Game -> Home -> mesmo Game`. -- **Pro:** evita misturar pausa/resume com substituicao de cartucho; reduz risco - de reabrir arquitetura durante a `AGD-0041`. -- **Contra:** a plataforma continua sem troca `Home -> outro Game` ate uma etapa - posterior. -- **Manutenibilidade:** alta, porque cada agenda fecha um eixo de lifecycle. - -### Opcao B - Definir agora o contrato conceitual, implementar depois - -- **Abordagem:** fechar uma decisao curta ja dizendo que o orquestrador pertence - ao SystemOS, que `run_cart` nao e userland, e que a execucao depende da - `AGD-0041`; o plano de codigo fica para depois. -- **Pro:** reduz ambiguidade enquanto trabalhamos na `AGD-0041`. -- **Contra:** pode produzir uma decisao com pouca evidencia operacional antes - do contrato de foreground estar fechado. -- **Manutenibilidade:** boa se a decisao for claramente marcada como dependente - da `AGD-0041`. - -### Opcao C - Implementar o orquestrador completo agora - -- **Abordagem:** tentar resolver `Game A -> Home -> Game B` antes ou junto da - `AGD-0041`. -- **Pro:** ataca o fluxo final diretamente. -- **Contra:** mistura pausa/resume, fechamento, cleanup, resolucao de alvo e - falha de load em uma unica frente; alto risco de contrato instavel. -- **Manutenibilidade:** baixa para v1, porque a troca completa depende do - contrato de foreground ainda aberto. - -## Sugestao / Recomendacao - -`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`. - -O contrato sugerido e: - -- 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 - -- [x] Depois da `AGD-0041`, qual estado representa um Game que sera descartado - em vez de retomado? - - 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? - - 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? - - 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? - - 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`? - - 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 - -A agenda pode virar decisao quando: - -- a `AGD-0041` tiver fechado o contrato de foreground/pausa/resume; -- estiver claro que o orquestrador pertence ao SystemOS; -- `run_cart`/loader estiver limitado a etapa interna, nao userland; -- existir regra para fechar/descartar o Game atual; -- existir contrato de limpeza de estado cartridge-scoped; -- existir politica para falha de carregamento do novo Game; -- houver criterio de teste minimo para `Game A -> Home -> Game B`. - -## Discussao - -- 2026-07-03: Agenda criada a partir da separacao entre `AGD-0041` - (`Game -> Home -> mesmo Game`) e `AGD-0003` (`run_cart`/loader nao userland). - 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 - -Pronta para virar decisao, pendente confirmacao explicita do usuario. diff --git a/discussion/workflow/agendas/AGD-0047-hub-suspended-game-kill-affordance.md b/discussion/workflow/agendas/AGD-0047-hub-suspended-game-kill-affordance.md deleted file mode 100644 index 650796cb..00000000 --- a/discussion/workflow/agendas/AGD-0047-hub-suspended-game-kill-affordance.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -id: AGD-0047 -ticket: hub-suspended-game-kill-affordance -title: Hub Suspended Game Kill Affordance -status: accepted -created: 2026-07-05 -resolved: -decision: -tags: [hub, lifecycle, game, ui] ---- - -## Contexto - -A troca entre cartridges agora mata a VM do jogo anterior quando outro jogo e carregado. Ainda assim, voltar para o Hub via Home/ESC pode deixar um jogo residente/suspenso, pronto para retomar pelo fluxo existente. - -Hoje o Hub nao comunica esse estado de forma clara. O usuario pode estar no Hub sem saber que ha um jogo suspenso mantendo task, sessao de VM, estado de pausa/audio e possivelmente recursos associados. A proposta e exibir o nome do jogo suspenso no canto inferior direito, dentro de uma caixa vermelha, e permitir que um clique nessa caixa feche/mate esse jogo. - -## Problema - -Precisamos decidir se esse elemento e apenas um indicador visual ou tambem um controle destrutivo de lifecycle. Se ele mata o jogo, a acao precisa ter contrato explicito: qual entidade e encerrada, quais estados sao limpos, como o Hub atualiza a UI, e se ha confirmacao para evitar kill acidental. - -## Pontos Criticos - -- Fato: o jogo suspenso/residente e uma entidade de lifecycle, nao apenas uma linha visual no Hub. -- Fato: iniciar outro jogo ja mata a VM anterior; esta proposta adiciona um caminho manual para a mesma intencao sem carregar outro cartridge. -- Risco: um clique acidental em uma caixa vermelha pode perder progresso/estado sem aviso. -- Risco: matar somente a task sem limpar sessao/render/audio/assets deixaria estado residual parecido com os bugs recentes de troca de jogo. -- Tradeoff: confirmacao protege o usuario, mas adiciona friccao a um controle que parece operacional/debug. -- Hipotese: limitar o controle a jogos `Game` residentes/suspensos evita misturar shell/system apps no mesmo affordance. - -## Opcoes - -### Opcao A - Indicador com kill imediato - -- **Abordagem:** mostrar uma caixa vermelha no canto inferior direito somente quando houver jogo residente/suspenso; um clique mata imediatamente esse jogo e remove o indicador. -- **Pro:** simples, rapido, combina com a proposta original. -- **Contra:** risco de perda acidental de estado. -- **Manutencao:** baixa complexidade, mas exige testes fortes de cleanup. - -### Opcao B - Indicador com confirmacao em dois passos - -- **Abordagem:** primeiro clique arma a acao ou muda o texto/estado visual; segundo clique confirma kill. -- **Pro:** reduz kill acidental sem exigir modal. -- **Contra:** mais estado no Hub e precisa de feedback visual claro. -- **Manutencao:** moderada; adiciona timeout/estado armado se quisermos evitar confirmacao persistente. - -### Opcao C - Apenas indicador, sem kill - -- **Abordagem:** mostrar o jogo suspenso, mas matar continua ocorrendo apenas ao carregar outro jogo ou por controles futuros. -- **Pro:** menor risco destrutivo. -- **Contra:** nao resolve a necessidade declarada de fechar/matar o jogo pelo Hub. -- **Manutencao:** baixa, mas provavelmente incompleta. - -## Sugestao / Recomendacao - -Seguir com a Opcao A se aceitarmos que o Hub atual e uma superficie operacional/dev e que a caixa vermelha comunica suficientemente a natureza destrutiva da acao. O contrato recomendado: - -- aparece somente para jogo `Game` residente/suspenso; -- mostra somente o nome do jogo; -- fica no canto inferior direito; -- usa vermelho como indicativo de encerramento; -- clique mata a task/sessao residente e limpa o estado relacionado; -- apos o kill, o Hub permanece no Hub e o indicador desaparece. - -Se a prioridade for evitar perda acidental de estado, promover para Opcao B antes da decision. - -## Perguntas em Aberto - -- [ ] O indicador deve aparecer somente para jogos `Game` residentes/suspensos? -- [ ] O clique vermelho deve matar imediatamente ou exigir confirmacao? -- [ ] O kill manual deve reutilizar exatamente o mesmo caminho de encerramento usado antes de carregar outro cartridge? -- [ ] O kill deve limpar assets/compositor imediatamente ou apenas task/session/render/audio? -- [ ] Deve haver evento/log explicito para "resident game killed from Hub"? - -## Criterio para Encerrar - -A agenda pode virar decision quando concordarmos em: - -- quando o indicador aparece; -- qual texto e posicao minima ele usa; -- se a acao e imediata ou confirmada; -- qual contrato de cleanup o kill manual deve cumprir; -- quais testes provam que o jogo suspenso foi morto e nao pode ser retomado. - -## Resolution - -Ainda em aberto. - -## Next Step - -Responder as perguntas em aberto e entao aceitar a agenda para escrever a decision. 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 deleted file mode 100644 index 387a9399..00000000 --- a/discussion/workflow/decisions/DEC-0039-systemos-game-cartridge-switch-orchestrator.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -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/decisions/DEC-0040-hub-suspended-game-kill-affordance.md b/discussion/workflow/decisions/DEC-0040-hub-suspended-game-kill-affordance.md deleted file mode 100644 index 2696065e..00000000 --- a/discussion/workflow/decisions/DEC-0040-hub-suspended-game-kill-affordance.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -id: DEC-0040 -ticket: hub-suspended-game-kill-affordance -title: Hub Suspended Game Kill Affordance -status: accepted -created: 2026-07-05 -ref_agenda: AGD-0047 -tags: [hub, lifecycle, game, ui] ---- - -## Context - -O Hub pode ficar ativo enquanto existe um jogo `Game` residente/suspenso apos Home/ESC. Esse estado e intencional para retomada, mas hoje nao fica visivel o suficiente e nao ha uma acao direta no Hub para matar o jogo sem iniciar outro cartridge. - -A troca de cartridges ja encerra a VM anterior antes de carregar o proximo jogo. Esta decision define o affordance manual equivalente no Hub. - -## Decision - -O Hub MUST exibir um indicador de jogo suspenso quando houver exatamente um jogo `Game` residente/suspenso associado ao lifecycle do SystemOS. - -O indicador MUST: - -- aparecer somente para jogos do perfil `Game`; -- mostrar somente o nome/titulo do jogo suspenso; -- ficar no canto inferior direito do Hub; -- ser apresentado como uma caixa vermelha; -- funcionar como controle destrutivo: um clique MUST matar imediatamente o jogo suspenso; -- desaparecer no mesmo fluxo em que o jogo deixa de ser residente. - -O clique no indicador MUST reutilizar o mesmo caminho de encerramento de jogo residente usado pelo cartridge switching. A implementacao MUST NOT criar um segundo caminho parcial de cleanup. - -Ao matar o jogo pelo Hub, o runtime MUST limpar o estado pertencente ao jogo residente: - -- task/process lifecycle; -- VM session; -- resident game state; -- render ownership retornando ao Shell/Hub; -- game audio pause/lifecycle state; -- Game2D composer binding/cache state; -- cartridge asset manager state and physical memory banks associated with the resident game. - -O Hub MUST permanecer no Hub apos a acao. O jogo morto MUST NOT ser retomavel depois do kill. A acao MUST emitir um log `INFO` explicito, com source `HUB` ou `POS`, equivalente a `Resident game killed from Hub: `. - -Nao havera confirmacao ou segundo clique nesta versao. A cor vermelha e a posicao dedicada sao o affordance de acao destrutiva. - -## Rationale - -O fluxo aprovado privilegia simplicidade operacional. A intencao do controle e fechar uma VM suspensa rapidamente, sem iniciar outro jogo apenas para forcar o encerramento do anterior. - -Limitar a UI a jogos `Game` evita misturar semantics de shell/system apps com cartridge runtime. Reusar o caminho de termination existente reduz risco de divergencia entre "kill por troca de cartridge" e "kill manual pelo Hub", especialmente apos os bugs recentes envolvendo scene/glyph/assets residuais. - -O kill imediato e aceitavel porque o controle e vermelho, posicionado como acao especifica, e opera sobre um jogo que ja esta fora do primeiro plano. Se futuramente houver save-state persistente ou risco maior de perda de progresso, uma nova decision pode revisar este contrato para confirmacao em dois passos. - -## Implications - -- O Hub precisa consultar estado de jogo residente/suspenso de forma explicita. -- A camada de lifecycle precisa expor uma operacao clara de matar jogo residente sem carregar outro cartridge. -- O cleanup manual precisa ter a mesma abrangencia do cleanup usado por switch. -- O render/presentation state nao pode continuar apontando para ownership/frame do jogo morto. -- Testes devem provar que o indicador aparece, que o clique mata, e que o jogo nao pode ser retomado depois. - -## Propagation Targets - -- specs: atualizar contrato de Hub/lifecycle se houver spec canonica aplicavel. -- plans: criar plano de execucao para UI do Hub, facade/lifecycle kill e testes. -- code: `prometeu_hub`, firmware/lifecycle facade, runtime cleanup, render/audio/assets cleanup conforme necessario. -- tests: Hub rendering/click hitbox, lifecycle termination, switch-vs-manual cleanup equivalence, no-resume-after-kill. -- docs: registrar lesson apenas apos execucao publicada. - -## References - -- Agenda: AGD-0047 -- Related: DSC-0043 / DEC-0039 cartridge switch orchestrator 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 deleted file mode 100644 index b8f88cca..00000000 --- a/discussion/workflow/plans/PLN-0157-introduce-systemos-game-switch-target-contract.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: PLN-0157 -ticket: system-os-cartridge-switch-orchestrator -title: Introduce SystemOS Game Switch Target Contract -status: done -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 deleted file mode 100644 index ae4c957f..00000000 --- a/discussion/workflow/plans/PLN-0158-terminate-resident-game-before-switching-cartridges.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: PLN-0158 -ticket: system-os-cartridge-switch-orchestrator -title: Terminate Resident Game Before Switching Cartridges -status: done -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 deleted file mode 100644 index 560a08c4..00000000 --- a/discussion/workflow/plans/PLN-0159-recover-failed-game-switches-back-to-home.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: PLN-0159 -ticket: system-os-cartridge-switch-orchestrator -title: Recover Failed Game Switches Back To Home -status: done -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 deleted file mode 100644 index 80b2ce06..00000000 --- a/discussion/workflow/plans/PLN-0160-add-dummy-boy-visual-switch-test-cartridge.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -id: PLN-0160 -ticket: system-os-cartridge-switch-orchestrator -title: Add Dummy Boy Visual Switch Test Cartridge -status: done -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 deleted file mode 100644 index 110b9565..00000000 --- a/discussion/workflow/plans/PLN-0161-validate-stress-to-dummy-boy-game-switch-end-to-end.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -id: PLN-0161 -ticket: system-os-cartridge-switch-orchestrator -title: Validate Stress To Dummy Boy Game Switch End To End -status: done -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 deleted file mode 100644 index af057ec9..00000000 --- a/discussion/workflow/plans/PLN-0162-specify-game-switch-contract-and-direct-boot-separation.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -id: PLN-0162 -ticket: system-os-cartridge-switch-orchestrator -title: Specify Game Switch Contract And Direct Boot Separation -status: done -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` diff --git a/discussion/workflow/plans/PLN-0163-render-hub-suspended-game-kill-control.md b/discussion/workflow/plans/PLN-0163-render-hub-suspended-game-kill-control.md deleted file mode 100644 index e4d0a707..00000000 --- a/discussion/workflow/plans/PLN-0163-render-hub-suspended-game-kill-control.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -id: PLN-0163 -ticket: hub-suspended-game-kill-affordance -title: Render Hub Suspended Game Kill Control -status: done -created: 2026-07-05 -ref_decisions: [DEC-0040] -tags: [hub, lifecycle, game, ui] ---- - -## Briefing - -DEC-0040 requires the Hub to show a red bottom-right control when a `Game` cartridge is resident/suspended, displaying only the game title and killing the game immediately on click. - -## Objective - -Render and handle the Hub suspended-game kill control using the lifecycle operation from PLN-0164. - -## Dependencies - -- Source decision: DEC-0040. -- Depends on PLN-0164 for the callable resident-game termination operation. - -## Scope - -- Show a red box in the bottom-right of the Hub only when a `Game` is resident/suspended. -- Render only the suspended game's title in that box. -- Register a click/hitbox for the box. -- On click, call the canonical resident-game termination operation. -- Keep the Hub active after the click. -- Remove the indicator immediately after the resident game is no longer present. - -## Non-Goals - -- Do not add confirmation or two-click arming. -- Do not show shell/system apps in this control. -- Do not redesign the Hub layout beyond the minimal bottom-right control. -- Do not add save-state or suspend-state management. - -## Execution Method - -1. Identify the Hub rendering and input code. - - Primary target: `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs`. - - Determine how Hub cards/buttons currently compute layout and hit testing. - -2. Add resident-game status to the Hub view model. - - Read only `Game` resident/suspended state. - - Include the game title needed for display. - - Keep the value absent for shell/system apps and for no resident game. - -3. Render the kill control. - - Position it in the bottom-right of the internal viewport. - - Use a red filled box with restrained dimensions. - - Draw only the game title. - - Keep the text inside the box for long titles by truncating or fitting according to existing Hub text conventions. - -4. Add click handling. - - Use the box hit region. - - On click, call the resident-game termination operation from PLN-0164. - - Do not navigate away from Hub. - - Ensure the next Hub frame no longer renders the control when the resident game is gone. - -## Acceptance Criteria - -- [ ] The control appears in Hub only while a `Game` resident/suspended game exists. -- [ ] The control displays only the game title. -- [ ] The control is visually red and placed in the bottom-right of the Hub. -- [ ] Clicking the control kills the resident game immediately. -- [ ] The Hub remains in Hub after the click. -- [ ] The control disappears after the game is killed. -- [ ] Shell/system apps do not appear in this control. - -## Tests - -- Hub render/unit test for presence when a resident `Game` exists. -- Hub render/unit test for absence when no resident game exists. -- Hub render/unit test for absence for non-Game app modes. -- Hub click/hitbox test proving the termination operation is invoked. -- Test for long title handling if existing Hub layout tests cover text bounds. - -## Affected Artifacts - -- `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs` -- Any Hub facade/view-model modules used by the program -- Hub rendering/input tests diff --git a/discussion/workflow/plans/PLN-0164-expose-resident-game-termination-contract.md b/discussion/workflow/plans/PLN-0164-expose-resident-game-termination-contract.md deleted file mode 100644 index e16d0535..00000000 --- a/discussion/workflow/plans/PLN-0164-expose-resident-game-termination-contract.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -id: PLN-0164 -ticket: hub-suspended-game-kill-affordance -title: Expose Resident Game Termination Contract -status: done -created: 2026-07-05 -ref_decisions: [DEC-0040] -tags: [hub, lifecycle, game, ui] ---- - -## Briefing - -DEC-0040 requires the Hub kill affordance to reuse the same resident-game termination path used by cartridge switching. This plan creates the lifecycle/runtime contract that the Hub UI can call without duplicating cleanup logic. - -## Objective - -Expose a single SystemOS/Firmware operation that terminates the current resident `Game` cartridge from Hub context and performs the complete cleanup required by DEC-0040. - -## Dependencies - -- Source decision: DEC-0040. -- Related lifecycle behavior: DSC-0043 / DEC-0039 cartridge switch orchestrator. -- Must be completed before PLN-0163 can wire the Hub UI click. - -## Scope - -- Add or reuse a resident-game termination operation in SystemOS lifecycle/facade code. -- Ensure the operation closes task/process lifecycle state. -- Ensure the operation removes the VM session and resident game state. -- Ensure render ownership returns to Shell/Hub. -- Ensure game audio pause/lifecycle state is cleared. -- Ensure Game2D composer scene binding/cache state is cleared. -- Ensure cartridge asset manager state and physical memory banks are cleared. -- Emit an explicit `INFO` log for manual Hub kill. - -## Non-Goals - -- Do not change cartridge switching semantics except to reuse the same termination path. -- Do not add Hub UI rendering or hit testing; that belongs to PLN-0163. -- Do not add confirmation semantics; DEC-0040 explicitly rejects confirmation for this version. -- Do not support shell/system app killing through this affordance. - -## Execution Method - -1. Locate the current game switch termination path in firmware/SystemOS lifecycle code. - - Files: `crates/console/prometeu-firmware/src/firmware/`, `crates/console/prometeu-system/src/`. - - Confirm which function currently closes the resident game before switching cartridges. - -2. Extract or expose a named resident-game termination operation. - - The operation must be callable from Hub context without a target cartridge. - - It must return an explicit status: no resident game, terminated game, or failure if the lifecycle cannot close cleanly. - - It must preserve existing switch behavior by making switch call the same operation or a shared internal helper. - -3. Wire complete cleanup into that operation. - - Close task/process lifecycle state. - - Remove the VM session and resident game state. - - Transition render ownership to Shell/Hub. - - Clear game lifecycle audio pause state. - - Unbind `Game2D` scene/composer state. - - Shutdown cartridge assets and clear physical memory banks. - -4. Emit the manual kill log. - - Source must be `HUB` or `POS`. - - Level must be `INFO`. - - Message must include the killed title, equivalent to `Resident game killed from Hub: <title>`. - -## Acceptance Criteria - -- [ ] There is one canonical resident-game termination path used by both cartridge switching and Hub manual kill. -- [ ] Calling the operation with no resident game is harmless and does not mutate unrelated Hub state. -- [ ] Calling the operation with a suspended `Game` closes the task/process and removes the VM session. -- [ ] The runtime cannot resume the killed game after the operation. -- [ ] Render ownership is Shell/Hub after the operation. -- [ ] Game audio pause/lifecycle state is not left active after the operation. -- [ ] Composer and cartridge asset/bank state are cleared. -- [ ] An explicit INFO log is emitted for Hub manual kill. - -## Tests - -- Unit or integration test around the lifecycle operation: - - no resident game is a no-op; - - resident game is terminated; - - VM session lookup returns none after kill; - - resident game state returns none after kill; - - render owner is Shell/Hub after kill. -- Regression test proving cartridge switch still terminates through the same cleanup behavior. -- Asset/composer cleanup assertions should mirror the recent Stress/Dummy switch tests where applicable. - -## Affected Artifacts - -- `crates/console/prometeu-system/src/` -- `crates/console/prometeu-firmware/src/` -- Existing switch tests under firmware/SystemOS test modules diff --git a/discussion/workflow/plans/PLN-0165-validate-hub-kill-flow-end-to-end.md b/discussion/workflow/plans/PLN-0165-validate-hub-kill-flow-end-to-end.md deleted file mode 100644 index 1286688b..00000000 --- a/discussion/workflow/plans/PLN-0165-validate-hub-kill-flow-end-to-end.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -id: PLN-0165 -ticket: hub-suspended-game-kill-affordance -title: Validate Hub Kill Flow End To End -status: done -created: 2026-07-05 -ref_decisions: [DEC-0040] -tags: [hub, lifecycle, game, ui] ---- - -## Briefing - -DEC-0040 requires that the Hub kill affordance fully terminates the suspended game and prevents resume. PLN-0164 and PLN-0163 provide the operation and UI; this plan validates the full flow end to end. - -## Objective - -Add deterministic tests that exercise Home -> suspended game indicator -> Hub kill -> no resume/no residue. - -## Dependencies - -- Source decision: DEC-0040. -- Depends on PLN-0164 for the termination operation. -- Depends on PLN-0163 for Hub UI and click behavior. - -## Scope - -- Cover a real game launch, Home/ESC return to Hub, indicator visibility, click-to-kill, and post-kill cleanup. -- Verify task/session/resident state are gone. -- Verify render ownership and Hub state are correct. -- Verify assets/composer cleanup where observable. -- Verify log emission. - -## Non-Goals - -- Do not test OS-native window manager shell app closure here. -- Do not create new cartridges unless existing Stress/Dummy cartridges cannot cover the scenario. -- Do not use timing sleeps or visual/manual assertions as primary evidence. - -## Execution Method - -1. Extend firmware/SystemOS end-to-end tests. - - Primary file: `crates/console/prometeu-firmware/src/firmware/firmware.rs` or a focused SystemOS runtime test if the existing test harness fits better. - - Launch `Stress Console` or a simple test cartridge. - - Return to Hub through the real Home path. - - Assert the resident game remains suspended before kill. - -2. Simulate Hub click on the bottom-right kill control. - - Use deterministic coordinates from the Hub layout. - - Avoid hard-coded magic numbers if the Hub exposes layout constants/helpers. - -3. Assert lifecycle cleanup. - - Resident game task is closed. - - Process is stopped. - - VM session lookup returns none. - - Resident game state returns none. - - Foreground owner remains Hub/Shell. - - Render owner is Shell/Hub. - -4. Assert resource cleanup. - - Composer is unbound. - - Cartridge asset slots and physical banks are cleared where existing platform test access permits. - - Audio lifecycle pause is not active. - -5. Assert no resume path remains. - - Clicking the old resume area or querying resident state must not restore the killed game. - - The Hub control must be absent on the next frame. - -6. Assert log evidence. - - Recent logs contain an INFO event equivalent to `Resident game killed from Hub: <title>`. - -## Acceptance Criteria - -- [ ] End-to-end test launches a game and returns to Hub with resident game suspended. -- [ ] Test confirms the kill control is present before click. -- [ ] Test clicks the control and remains in Hub. -- [ ] Test proves the game cannot be resumed after kill. -- [ ] Test proves task/session/resident/render/audio/assets/composer cleanup. -- [ ] Test proves the explicit INFO log exists. -- [ ] Existing cartridge switch tests still pass. - -## Tests - -- `cargo test -p prometeu-firmware` -- `cargo test -p prometeu-system` -- `cargo test -p prometeu-host-desktop-winit` if host presentation behavior is touched by implementation. -- `cargo clippy -p prometeu-system -p prometeu-firmware --all-targets -- -D warnings` - -## Affected Artifacts - -- Firmware/SystemOS end-to-end tests -- Hub tests -- Lifecycle/runtime tests diff --git a/discussion/workflow/plans/PLN-0166-publish-hub-kill-contract-spec-and-lesson-hooks.md b/discussion/workflow/plans/PLN-0166-publish-hub-kill-contract-spec-and-lesson-hooks.md deleted file mode 100644 index cff2b5f4..00000000 --- a/discussion/workflow/plans/PLN-0166-publish-hub-kill-contract-spec-and-lesson-hooks.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -id: PLN-0166 -ticket: hub-suspended-game-kill-affordance -title: Publish Hub Kill Contract Spec And Lesson Hooks -status: done -created: 2026-07-05 -ref_decisions: [DEC-0040] -tags: [hub, lifecycle, game, ui] ---- - -## Briefing - -DEC-0040 introduces a user-visible Hub lifecycle control. Any canonical spec covering Hub, lifecycle, resident games, or cartridge switching must reflect the accepted contract before implementation is considered complete. - -## Objective - -Publish the Hub suspended-game kill contract in the appropriate canonical spec location and prepare the discussion thread for post-execution lessons. - -## Dependencies - -- Source decision: DEC-0040. -- Should run after PLN-0164, PLN-0163, and PLN-0165 identify the exact final module boundaries. - -## Scope - -- Locate canonical specs for Hub behavior, SystemOS lifecycle, resident game state, and cartridge switching. -- Add English normative text for the red bottom-right kill affordance. -- Document the cleanup contract at the spec level. -- Document required log/event behavior. -- Leave lesson creation for post-execution housekeeping. - -## Non-Goals - -- Do not create lessons before implementation is complete. -- Do not move discussion artifacts into legacy docs paths. -- Do not reopen DEC-0040 semantics unless implementation proves the contract insufficient. - -## Execution Method - -1. Locate canonical specs. - - Search existing `specs/`, runtime docs, or repository-approved spec paths. - - Do not write new normative text under `discussion/lessons/`. - -2. Update Hub spec text. - - State that Hub shows a bottom-right red control when a `Game` resident/suspended cartridge exists. - - State that the control displays only the game title. - - State that click kills immediately and keeps the user in Hub. - -3. Update lifecycle/spec text. - - State that manual Hub kill uses the same resident-game termination path as cartridge switching. - - State cleanup obligations: task/process, VM session, resident state, render ownership, audio lifecycle, composer, assets, physical banks. - - State that the killed game cannot be resumed. - -4. Update logging/spec text if a logging contract exists. - - Record the required INFO event and message shape. - -5. Prepare housekeeping note. - - After implementation and validation, run discussion housekeeping for DSC-0044 with an English lesson if the implementation yields durable knowledge. - -## Acceptance Criteria - -- [ ] Canonical spec text exists for the Hub kill affordance. -- [ ] Spec text is in English. -- [ ] Spec text includes visibility, layout, click behavior, cleanup, no-resume behavior, and log event requirements. -- [ ] No normative text is added to `discussion/lessons/`. -- [ ] `discussion validate` passes after artifact/spec updates. - -## Tests - -- `discussion validate` -- Documentation/spec review against DEC-0040 -- Any repository doc lint/check if present - -## Affected Artifacts - -- Canonical specs location, to be identified during execution -- `discussion/workflow/plans/` -- Later `discussion/lessons/` only through housekeeping after implementation