Hub Suspended Game Kill Affordance
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good
Intrepid/Prometeu/Runtime/pipeline/pr-master This commit looks good

This commit is contained in:
bQUARKz 2026-07-05 16:27:05 +01:00
parent 49cb16b6cb
commit de53eb5ad7
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
17 changed files with 142 additions and 1413 deletions

View File

@ -1,6 +1,6 @@
{"type":"meta","next_id":{"DSC":45,"AGD":48,"DEC":41,"PLN":167,"LSN":53,"CLSN":1}} {"type":"meta","next_id":{"DSC":45,"AGD":48,"DEC":41,"PLN":167,"LSN":55,"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-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":"in_progress","ticket":"system-os-cartridge-switch-orchestrator","title":"SystemOS Cartridge Switch Orchestrator","created_at":"2026-07-03","updated_at":"2026-07-05","tags":["runtime","os","lifecycle","game","cartridge","architecture"],"agendas":[{"id":"AGD-0044","file":"AGD-0044-systemos-cartridge-switch-orchestrator.md","status":"accepted","created_at":"2026-07-03","updated_at":"2026-07-05"}],"decisions":[{"id":"DEC-0039","file":"DEC-0039-systemos-game-cartridge-switch-orchestrator.md","status":"accepted","created_at":"2026-07-05","updated_at":"2026-07-05","ref_agenda":"AGD-0044"}],"plans":[{"id":"PLN-0157","file":"PLN-0157-introduce-systemos-game-switch-target-contract.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0158","file":"PLN-0158-terminate-resident-game-before-switching-cartridges.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0159","file":"PLN-0159-recover-failed-game-switches-back-to-home.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0160","file":"PLN-0160-add-dummy-boy-visual-switch-test-cartridge.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0161","file":"PLN-0161-validate-stress-to-dummy-boy-game-switch-end-to-end.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]},{"id":"PLN-0162","file":"PLN-0162-specify-game-switch-contract-and-direct-boot-separation.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05","ref_decisions":["DEC-0039"]}],"lessons":[]} {"type":"discussion","id":"DSC-0043","status":"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-0039","status":"abandoned","ticket":"render-pipeline-family-and-future-3d","title":"Render Pipeline Family and Future 3D","created_at":"2026-06-04","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","architecture","pipeline"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-render-pipeline-family-and-future-3d.md","status":"abandoned","created_at":"2026-06-04","updated_at":"2026-06-04","_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}],"decisions":[],"plans":[],"lessons":[],"_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}
{"type":"discussion","id":"DSC-0040","status":"done","ticket":"vm-render-parallel-execution-boundary","title":"VM and Render Parallel Execution Boundary","created_at":"2026-06-04","updated_at":"2026-06-06","tags":["runtime","renderer","vm","concurrency","architecture","perf"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0048","file":"discussion/lessons/DSC-0040-vm-render-parallel-execution-boundary/LSN-0048-render-workers-need-a-closed-packet-contract.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-06"}]} {"type":"discussion","id":"DSC-0040","status":"done","ticket":"vm-render-parallel-execution-boundary","title":"VM and Render Parallel Execution Boundary","created_at":"2026-06-04","updated_at":"2026-06-06","tags":["runtime","renderer","vm","concurrency","architecture","perf"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0048","file":"discussion/lessons/DSC-0040-vm-render-parallel-execution-boundary/LSN-0048-render-workers-need-a-closed-packet-contract.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-06"}]}
{"type":"discussion","id":"DSC-0041","status":"done","ticket":"foreground-stack-game-pause-shell-vm-backed","title":"Foreground Stack, Game Pause, and VM-Backed Shell Coexistence","created_at":"2026-06-05","updated_at":"2026-07-05","tags":["runtime","os","lifecycle","shell","game","vm","foreground","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0052","file":"discussion/lessons/DSC-0041-foreground-stack-game-pause-shell-vm-backed/LSN-0052-foreground-ownership-and-vm-session-ownership-are-separate.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]} {"type":"discussion","id":"DSC-0041","status":"done","ticket":"foreground-stack-game-pause-shell-vm-backed","title":"Foreground Stack, Game Pause, and VM-Backed Shell Coexistence","created_at":"2026-06-05","updated_at":"2026-07-05","tags":["runtime","os","lifecycle","shell","game","vm","foreground","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0052","file":"discussion/lessons/DSC-0041-foreground-stack-game-pause-shell-vm-backed/LSN-0052-foreground-ownership-and-vm-session-ownership-are-separate.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]}

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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: <title>`.
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

View File

@ -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`

View File

@ -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`

View File

@ -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`

View File

@ -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

View File

@ -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

View File

@ -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`

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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