129 lines
9.5 KiB
Markdown
129 lines
9.5 KiB
Markdown
---
|
|
id: AGD-0024
|
|
ticket: studio-play-stop-cartridge-flow
|
|
title: Play/Stop integration agenda for runtime execution from build using project runtime setup
|
|
status: in_progress
|
|
created: 2026-04-06
|
|
resolved: 2026-04-06
|
|
decision: DEC-0021
|
|
tags: [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
|
|
|
|
- [x] 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.
|
|
- [x] 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`.
|
|
- [x] 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.
|
|
- [x] 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.
|
|
- [x] 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`.
|
|
- [x] 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.
|
|
- [x] 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.
|
|
- [x] 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.
|