prometeu-studio/discussion/workflow/agendas/AGD-0024-studio-play-stop-runtime-run-cartridge.md

9.5 KiB

id ticket title status created resolved decision tags
AGD-0024 studio-play-stop-cartridge-flow Play/Stop integration agenda for runtime execution from build using project runtime setup in_progress 2026-04-06 2026-04-06 DEC-0021
studio
runtime
play-stop
build
process
project-setup

Pain

Mesmo depois que o Studio conseguir preparar build/, o botão Play continuará incompleto sem um contrato claro para executar o runtime configurado no projeto contra esse artifact root.

Hoje o caminho do runtime já existe em .studio/setup.json via ProjectLocalStudioSetup.prometeuRuntimePath, mas esse valor ainda não participa de nenhuma execução real no shell.

Sem essa definição, o Play/Stop corre o risco de virar:

  • um botão que prepara build/ mas não executa nada;
  • ou um launcher improvisado, sem owner claro para processo, logs, lifecycle e falhas.

Context

Domain owner: studio. Subdomínios referenciados: runtime.

O Studio já carrega ProjectLocalStudioSetup na StudioProjectSession. Portanto o runtime configurado por projeto já está disponível para consumo em runtime de aplicação.

Após a decisão DEC-0020, esta agenda passa a assumir explicitamente que:

  • Play prepara build/ como artifact root runnable;
  • manifest.json é gerado em build/;
  • não há cartridge/ separado nesta wave.

O comando desejado pelo usuário é conceitualmente:

runtime run build

usando o runtime configurado no projeto atual.

Esta agenda não rediscute preparação de build/. Ela assume a saída de DEC-0020 como pré-condição e foca no segundo passo do Play: iniciar, observar e interromper o processo de runtime.

Também há um constraint de UX desta wave:

  • ao apertar Play, o usuário deverá ser levado para o futuro DebuggerWorkspace, mesmo que essa surface ainda não esteja construída;
  • até essa surface existir, os logs do runtime precisarão "ficar voando", isto é, viver provisoriamente fora do destino final pretendido;
  • a etapa de pack usada por Play deve preservar seu ciclo de validação antes da execução do runtime;
  • os logs de build e pack também devem convergir para o destino do debugger, porque é nessa surface que o usuário verá falhas de compilação, validação ou packing durante o fluxo do Play.

Também há um constraint de escopo nesta wave:

  • checks adicionais de preflight antes do build, como arquivos do editor ainda não salvos, não entram agora;
  • quando essa wave futura existir, ela deverá bloquear o Play antes do build com erro explícito, em vez de ser tratada como detalhe implícito de runtime.

Open Questions

  • O Play deve falhar imediatamente quando prometeuRuntimePath estiver ausente, ou o shell deve oferecer algum repair path explícito antes de abortar?
  • Resposta proposta: nesta wave, o Play deve falhar imediatamente com erro explícito quando prometeuRuntimePath estiver ausente, inválido, inexistente ou não executável; repair path guiado fica para uma wave posterior.
  • O Studio deve executar o runtime diretamente pelo binário configurado, ou por um wrapper/comando fixo resolvido a partir desse path?
  • Resposta proposta: o Studio deve executar como processo externo o binário configurado em ProjectLocalStudioSetup.prometeuRuntimePath, apontando para build/ e usando o subcomando run nesta wave; uma futura wave de debugger poderá trocar esse subcomando para debug.
  • O Stop deve encerrar apenas o processo de runtime ativo iniciado pelo shell atual, ou também limpar algum estado transitório adicional no Studio?
  • Resposta proposta: Stop deve encerrar apenas o processo de runtime ativo iniciado pelo Play atual; não deve limpar estado transitório adicional além do lifecycle desse processo.
  • Onde os logs de stdout/stderr do runtime devem viver nesta primeira wave: activity feed, shipper logs, uma surface dedicada, ou combinação mínima dessas superfícies?
  • Resposta proposta: o destino final dos logs deve ser o futuro DebuggerWorkspace, e o Play deve navegar para essa surface ao iniciar a execução; até ela existir, stdout/stderr e também os logs de build/pack ficam provisoriamente em uma solução transitória desacoplada, enquanto o Activity Feed recebe apenas eventos resumidos de início, sucesso de término e falha.
  • Como o shell deve serializar múltiplos cliques em Play: ignorar enquanto já está rodando, reiniciar, ou encadear stop + rerun?
  • Resposta proposta: enquanto já houver runtime ativo iniciado pelo shell atual, cliques adicionais em Play devem ser ignorados até o processo sair ou o usuário apertar Stop.
  • O pack usado pelo Play pode empacotar diretamente, ou deve preservar o ciclo de validação antes da execução do runtime?
  • Resposta proposta: o pack usado pelo Play deve preservar seu ciclo de validação antes da execução; se a validação bloquear o pack, o runtime não deve iniciar.
  • Checks extras antes do build, como arquivos não salvos no editor, entram nesta wave?
  • Resposta proposta: não; preflight adicional de build, incluindo arquivos ainda não salvos, fica explicitamente para uma wave posterior e não altera o contrato desta agenda.
  • A execução da agenda 24 deve validar explicitamente a existência de build/manifest.json antes do spawn, ou isso fica implícito pelo sucesso da preparação?
  • Resposta proposta: isso fica implícito pelo sucesso da preparação definida em DEC-0020; a agenda 24 não adiciona check redundante de existência de manifest.json antes do spawn.

Options

Option A - Play/Stop controla um processo único de runtime do projeto ativo

  • Approach: O shell resolve o runtime configurado no ProjectLocalStudioSetup, executa diretamente o binário configurado contra build/ como processo do projeto ativo, mantém handle desse processo e usa Stop para encerrar exatamente esse processo.
  • Pro: O comportamento do botão fica simples, previsível e diretamente alinhado ao modelo visual de toggle.
  • Con: Exige que o Studio introduza ownership explícito de processo, logs e cleanup, em vez de só alternar estado visual.
  • Maintainability: Boa, porque o shell passa a ter um contrato único de execução por projeto e um lifecycle claro.

Option B - Play delega a execução ao workspace ou a um launcher externo sem handle direto no shell

  • Approach: O shell apenas dispara uma ação indireta e considera-se "running" sem possuir o processo como first-class state próprio.
  • Pro: Menor acoplamento inicial entre shell e camada de processo.
  • Con: O Stop fica semanticamente fraco ou enganoso, porque o shell não controla de verdade o processo que diz estar executando.
  • Maintainability: Fraca, porque o toggle visual deixa de corresponder ao lifecycle real da execução.

Discussion

O ponto mais importante desta agenda é alinhar o significado de Stop. Se o shell não possui o processo de runtime como state explícito, o botão vira só uma fantasia visual.

Como o runtime path já é project-local setup carregado na sessão, o Studio já tem o owner certo para resolver o binário configurado. O que falta é explicitar o contrato operacional:

  1. validar que o runtime configurado existe e é executável;
  2. executar build;
  3. executar a validação de pack;
  4. executar pack somente quando a validação permitir;
  5. enviar os logs de build e pack para a surface de debugger/logs da execução;
  6. rodar como processo externo o runtime configurado contra build/ no contexto do projeto ativo, usando run nesta wave;
  7. capturar stdout/stderr;
  8. refletir running/stopped/failure no shell;
  9. interromper o processo correto quando o usuário apertar Stop.

A execução do runtime nesta agenda confia no contrato de preparação anterior. Portanto, esta wave não introduz preflight redundante para verificar novamente a existência de build/manifest.json antes do spawn.

A recomendação inicial desta agenda é:

  1. fazer o shell ser owner de um único runtime-process handle por projeto ativo;
  2. resolver o comando a partir de ProjectLocalStudioSetup.prometeuRuntimePath;
  3. falhar de forma explícita quando o runtime do projeto estiver ausente ou inválido;
  4. definir Stop como término do processo iniciado pelo Play atual, e não como reset genérico de UI;
  5. ignorar novo Play enquanto o processo atual ainda estiver rodando;
  6. preservar a validação de pack antes do pack efetivo na preparação do Play;
  7. tratar o futuro DebuggerWorkspace como destino canônico da execução e dos logs de runtime, build e pack;
  8. enquanto o DebuggerWorkspace não existir, manter stdout/stderr e logs de preparação em uma solução transitória, usando o Activity Feed apenas para sinais resumidos de lifecycle;
  9. deixar checks extras de preflight antes do build, como arquivos não salvos, fora desta wave;
  10. fixar run como o subcomando de execução desta wave, deixando debug para uma futura wave de debugger;
  11. confiar no sucesso da preparação anterior sem adicionar preflight redundante de manifest.json antes do spawn.

Resolution

Próximo passo sugerido: fechar uma decision de studio que defina ownership de processo para Play/Stop, preserve o ciclo de validação + pack antes da execução do runtime, fixe a execução como processo externo do runtime configurado usando run contra build/, trate o DebuggerWorkspace como destino futuro da sessão de execução e explicite que checks extras de preflight do build ficam para uma wave posterior.