prometeu-runtime/discussion/workflow/decisions/DEC-0039-systemos-game-cartridge-switch-orchestrator.md

175 lines
7.7 KiB
Markdown

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