prometeu-runtime/discussion/workflow/agendas/AGD-0046-vm-context-ownership-for-resident-game-and-vm-backed-shell.md

9.0 KiB

id ticket title status created resolved decision tags
AGD-0046 foreground-stack-game-pause-shell-vm-backed VM Context Ownership for Resident Game and VM-Backed Shell accepted 2026-07-04 DEC-0038
runtime
os
lifecycle
shell
game
vm
foreground
architecture

Contexto

DEC-0037 define que o v1 deve suportar o fluxo Game -> Home/Shell -> same Game, com o Game residente pausado/suspenso enquanto Hub ou Shell possuem o foreground. A implementacao atual ja impede que Shell nativo ticke o Game suspenso, porque Shell nativo nao usa a VM.

A lacuna aparece quando o Shell tambem eh VM-backed. Hoje Firmware possui um unico VirtualMachine global (Firmware.vm). O Game residente e um Shell VM-backed competem por esse mesmo contexto. Se o Shell VM-backed inicializa uma nova cartridge nesse objeto, ele sobrescreve o contexto do Game que deveria permanecer residente/suspenso.

Isso significa que o modelo de foreground/task/process ja avancou, mas o modelo de contexto VM ainda esta acoplado ao firmware global.

Problema

Precisamos decidir onde vive o contexto de execucao VM quando existem, ao mesmo tempo, um Game residente suspenso e um Shell VM-backed foreground.

O problema nao eh apenas pausar ticks. Para coexistencia real, cada VM-backed process precisa preservar seu proprio estado: PC, stack, heap, globals, cartridge identity, runtime services escopados, render ownership metadata e eventos lifecycle pendentes.

Enquanto Firmware.vm for unico, "suspender" um Game VM nao preserva o contexto se outra cartridge VM-backed for carregada.

Pontos Criticos

  • DEC-0037 diz que um Game suspenso nao recebe ticks/input/frame pacing, mas continua residente para voltar ao mesmo Game.
  • Shell nativo nao precisa de VM context proprio, mas Shell VM-backed precisa.
  • SystemOS ja eh autoridade de lifecycle/process/task, entao eh candidato natural para possuir ou localizar contextos VM por sessao.
  • Firmware deve orquestrar macro estados, mas nao deveria ser dono unico do contexto de todos os processos VM-backed.
  • VirtualMachineRuntime contem estado atualmente misto: identidade da cartridge atual, render manager, lifecycle delivery, fs/memcard/open handles e telemetria. Precisamos separar o que eh global do OS do que eh por sessao VM-backed.
  • A solucao deve preservar a restricao v1: no maximo um Game residente e no maximo um Shell foreground. Ela nao deve abrir multitasking geral.
  • Game-to-Game switching continua fora desta agenda e pertence a DSC-0043.

Opcoes

Opcao A - Manter VM global no Firmware e bloquear Shell VM-backed com Game residente

  • Abordagem: documentar que Shell VM-backed nao pode abrir enquanto um Game VM esta residente; apenas Shell nativo coexiste com Game suspenso.
  • Pro: menor implementacao imediata.
  • Contra: contradiz a intencao de coexistencia de VM-backed Shell em DEC-0037 e deixa a arquitetura incompleta.
  • Manutenibilidade: baixa, porque o sistema teria regras diferentes para Shell nativo e Shell VM-backed sem uma fronteira clara de sessao.

Opcao B - Serializar o Game VM ao suspender e restaurar ao resumir

  • Abordagem: ao suspender Game, extrair snapshot do VirtualMachine e do runtime associado; ao resumir, restaurar snapshot depois do Shell VM-backed.
  • Pro: preserva a ideia de um unico VM executor ativo.
  • Contra: exige serializacao profunda e correta de todo o estado VM/runtime, incluindo handles, assets, render state e side effects. Isso eh muito mais complexo que a necessidade v1.
  • Manutenibilidade: baixa a media; snapshots viram contrato dificil e fragil antes de termos necessidade de hibernacao real.

Opcao C - Tornar o contexto VM propriedade da sessao/processo VM-backed

  • Abordagem: cada processo VM-backed possui seu proprio VirtualMachine e seu contexto runtime VM-scoped. O scheduler/firmware seleciona qual sessao recebe tick conforme foreground/lifecycle. Game suspenso simplesmente deixa de ser tickado, mas seu contexto permanece armazenado na sessao Game.
  • Pro: alinha com task/process/lifecycle, suporta Game residente + Shell VM-backed sem sobrescrever contexto, e prepara o terreno para futuras sessoes sem implementar multitasking geral agora.
  • Contra: exige separar estado hoje concentrado em Firmware.vm e SystemOS.vm_runtime, decidindo o que eh global do OS e o que eh por sessao.
  • Manutenibilidade: alta, porque a posse do contexto acompanha o processo que executa a VM.

Opcao D - Criar apenas dois slots VM fixos: Game VM e Shell VM

  • Abordagem: manter um slot game_vm e um slot shell_vm, em vez de uma VM por processo/sessao.
  • Pro: mais simples que uma tabela geral de sessoes.
  • Contra: codifica uma limitacao acidental. Ainda precisariamos decidir ownership, runtime scoped state e lifecycle por slot. Pode virar refactor duplo quando mais de um Shell ou Game switching aparecer.
  • Manutenibilidade: media; aceitavel como stepping stone somente se modelado internamente como sessao, nao como campos especiais permanentes.

Sugestao / Recomendacao

Seguir a Opcao C: contexto VM deve pertencer a uma sessao/processo VM-backed, nao ao Firmware global.

Para v1, a implementacao pode continuar limitada a uma sessao Game residente e uma sessao Shell foreground, mas o modelo deve ser "session-owned VM context". Isso permite que Shell VM-backed rode enquanto o Game fica suspenso sem perder PC/stack/heap/estado runtime.

O firmware deve deixar de possuir a VM como estado global de todos os apps e passar a pedir ao SystemOS/runtime scheduler o contexto VM ativo para o owner foreground. SystemOS deve continuar sendo a autoridade de lifecycle; o runtime deve separar estado VM-scoped de estado global de OS/render/telemetria conforme necessario.

Perguntas em Aberto

  • Qual objeto deve representar a sessao VM-backed: Process, novo VmSession, ou uma tabela separada ligada a ProcessId/TaskId?
  • Quais campos de VirtualMachineRuntime sao por sessao VM-backed e quais devem permanecer globais em SystemOS?
  • O render manager fica global por foreground owner ou dentro de cada contexto VM com handoff global?
  • Handles de FS, memcard, assets e open files devem ser por sessao, por app_id, ou globais com namespace por processo?
  • Como LoadCartridgeStep deve mudar: criar sessao VM nova, ativar sessao existente, ou delegar tudo para uma facade de sessions?
  • Como preservar os testes e invariantes de DEC-0037 durante a migracao incremental sem abrir multitasking geral?
  • Como processos background-capable, como um player de musica, entram no modelo sem confundir foreground visual ownership com elegibilidade de execucao?
  • Cada Shell VM-backed deve ter uma VM propria, mesmo quando existe mais de um Shell em memoria no futuro?

Criterio para Encerrar

Esta agenda pode virar decision quando definirmos:

  • o proprietario canonico do contexto VM;
  • a fronteira entre estado VM-scoped e estado global do OS;
  • como firmware seleciona/ticka a sessao VM ativa;
  • como Game residente suspenso e Shell VM-backed foreground coexistem;
  • quais restricoes v1 permanecem explicitamente fora de escopo.

Discussion

  • 2026-07-04: Aberta a partir da observacao de que Shell nativo coexiste com Game suspenso, mas Shell VM-backed ainda conflita com o Firmware.vm unico.
  • 2026-07-04: Discussao adicional separou foreground ownership de background execution. A recomendacao atual eh que todo processo VM-backed tenha sua propria VmSession; processos background-capable devem ser modelados como sessoes com classe/politica de scheduling propria, nao como foreground owners.

Resolution

Resolvido em 2026-07-04:

  • O modelo deve seguir a Opcao C: todo processo VM-backed deve possuir uma VmSession propria, ligada ao lifecycle/task/process, em vez de depender de um Firmware.vm global.
  • Cada Shell VM-backed deve ter sua propria sessao VM. Ele pode compartilhar a engine/runtime e caches imutaveis, mas nao stack, heap, PC, globals, handles ou identidade mutavel de execucao.
  • O Game residente suspenso preserva seu contexto porque sua VmSession continua viva; ele apenas deixa de ser elegivel para ticks normais enquanto Hub/Shell possui foreground.
  • Foreground ownership e background execution sao conceitos separados. Foreground ownership decide input visual, render ownership e frame pacing normal. Execution eligibility decide quais sessoes podem receber ticks sem serem foreground.
  • Background execution, como player de musica ou background services, nao entra na primeira implementacao desta agenda. Mesmo assim, o modelo de VmSession deve ser obrigatoriamente compativel com essa evolucao em um futuro proximo.
  • Render ownership permanece autoridade global do SystemOS. Sessoes VM-backed produzem frames, mas nao decidem se podem apresentar.
  • LoadCartridgeStep nao deve inicializar uma VM global diretamente. Ele deve delegar criacao/ativacao de sessao para uma facade de sessions/scheduler.

Esta agenda esta pronta para virar decision normativa.