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