8.7 KiB
| id | ticket | title | status | created | resolved | decision | tags | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| AGD-0023 | studio-play-stop-cartridge-flow | Play/Stop integration agenda for build/pack freshness-gated runtime preparation | in_progress | 2026-04-06 | 2026-04-06 | DEC-0020 |
|
Pain
O botão Play do Studio hoje só alterna estado visual no shell.
Ele ainda não aciona um fluxo operacional real para preparar um conjunto executável de artefatos em build/.
Isso deixa o shell com uma affordance de execução sem pipeline correspondente e sem um contrato claro entre:
- Studio shell,
- compiler build,
- compiler,
- packer,
- e a pasta
build/do projeto.
Context
Domain owner: studio.
Subdomínios referenciados: compiler, packer, runtime.
Já existe um ShipperWorkspace no Studio e ele hoje chama BuilderPipelineService.INSTANCE.build(...), mas esse fluxo atual é apenas um scratch inicial.
Na prática, hoje ele está compilando bytecode e não deve ser tratado como o contrato definitivo de preparação de runtime do produto.
O objetivo desta agenda não é fechar um pipeline de shipping nem materializar um cartridge/ separado.
O escopo desta wave é estritamente o mínimo necessário para o botão Play conseguir preparar artefatos rodáveis em build/:
- compilar o PBX necessário;
- executar o packer necessário;
- manter ou regenerar os artefatos de
build/conforme frescor; - gerar
manifest.jsonembuild/.
Essa agenda trata apenas da preparação dos artefatos em build/.
A execução runtime run cartridge ou equivalente apontando para build/ fica em agenda separada dentro da mesma discussion.
Open Questions
- O
Playdeve reutilizar exatamente o mesmo pipeline já acionado peloShipperWorkspace, ou deve haver um service/application layer dedicado para o shell chamar e o workspace apenas consumir? - Resposta proposta:
Playnão deve reaproveitar o scratch atual doShipperWorkspace; ele deve orquestrar chamadas explícitas debuildepack, cada uma com sua própria política de frescor. - Os artefatos rodáveis desta wave devem viver em
cartridge/separado ou no própriobuild/? - Resposta proposta: nesta wave o artifact root runnable deve ser
build/; não há necessidade de materializar umcartridge/separado se o runtime pode consumir o mesmo contrato diretamente debuild/. - Quem decide se é necessário recompilar ou repackar quando o usuário aperta
Play? - Resposta proposta: nesta wave,
Playsempre chamabuildepack; a política fina de drift/freshness fica explicitamente adiada para uma segunda etapa. Quando essa segunda etapa existir, cada domínio será owner de sua própria política de frescor. - Onde deve viver o controle fino de frescor e drift para os artefatos produzidos?
- Resposta proposta: quando a wave de drift existir, o controle fino viverá em arquivos dedicados por domínio sob
.studio/, começando porasset-workspace.jsoneeditor-workspace.json, separados do snapshot principal de restauração. - O
manifest.jsonruntime-facing deve ser derivado doprometeu.jsondo projeto com normalização adicional do Studio, ou copiado quase diretamente com apenas os campos estritamente runtime-facing? - Resposta proposta: o
manifest.jsondeve ser sempre gerado de forma determinística embuild/, a partir do build corrente e do owner metadata do projeto, sem cópia por conveniência. - Como o shell distinguirá falha de build, falha de pack e falha de manifest para refletir estado útil no
Play/Stop? - Resposta proposta: para o
Play, basta distinguirsuccessefailed; logs detalhados das operações devem acompanhar o resultado.buildfalhando bloqueiapack, emanifestsó roda depois do sucesso do build/pack desta wave.
Options
Option A - Play sempre chama build e pack, e drift fica para uma wave posterior
- Approach: Fazer o shell chamar explicitamente
buildepackem toda execução dePlay; nesta wave não há reuse por drift/freshness, apenas execução determinística com logs e geração final demanifest.json. - Pro: Destrava a integração do
Playcom o menor contrato correto, sem antecipar um sistema de freshness ainda não normatizado. - Con: Pode refazer trabalho desnecessário em execuções sucessivas até a wave de drift existir.
- Maintainability: Boa, porque mantém o
Playsimples agora e deixa a otimização para uma agenda própria depois.
Option B - Play inspeciona artefatos existentes e decide por conta própria se pode seguir
- Approach: O shell observa presença ou timestamps de artefatos em
build/e tenta inferir se basta reutilizar o que já existe. - Pro: Menos modelagem inicial de metadata e contratos.
- Con: Move para o shell uma inteligência que pertence aos domínios de compiler e packer, além de abrir espaço para reuse incorreto sob drift parcial do workspace.
- Maintainability: Fraca, porque o
Playvira owner implícito de políticas que não são dele.
Discussion
O ponto central aqui não é apenas "rodar compile + packer". O problema real é separar claramente:
- a orquestração do
Play, - a responsabilidade de
build, - a responsabilidade de
pack, - e a futura política de frescor de cada artefato.
Se o Play inferir por conta própria se precisa rebuildar ou repackar, o shell passa a absorver conhecimento que pertence a outros domínios.
Isso cria uma fronteira errada: o shell deixa de ser apenas o caller de operações e passa a ser o árbitro de drift do projeto.
Ao mesmo tempo, modelar agora um sistema fino de drift adicionaria complexidade antes da própria integração básica do Play existir.
Por isso, esta agenda fecha a wave 1 com execução sempre explícita e adia a otimização de freshness para uma agenda própria.
O contrato mais limpo é:
Playpedebuild;buildexecuta e retornasuccessoufailed, acompanhado de logs;Playpedepack;packexecuta e retornasuccessoufailed, acompanhado de logs;manifest.jsoné sempre regenerado embuild/a partir do build corrente e dos metadados do projeto;Playsó verifica sucesso ou falha dessas operações antes de seguir para a execução.
Os constraints já visíveis no repositório reforçam esse recorte:
- o compiler atual escreve
build/program.pbx; - o packer atual escreve
build/assets.pae companions de tooling, e o spec do packer afirma explicitamente que cartridge assembly não pertence ao domíniopacker; - os projetos de teste já mostram
build/contendoprogram.pbx,assets.pae companions; ProjectLocalStudioSetupjá está carregado naStudioProjectSession, então o shell já possui o owner correto para coordenar preparation + future run sem precisar deduzir drift por presença oportunista de arquivo.
Isso torna a fronteira recomendada mais concreta:
build/é o artifact root runnable desta wave;- compiler e packer continuam donos de seus artefatos dentro de
build/; Playnão usa presença de arquivo como regra de validade;- drift e freshness ficam explicitamente fora do escopo desta wave e poderão viver em arquivos dedicados por domínio sob
.studio/; - o shell avança apenas quando
build,packemanifestreportarem sucesso.
A recomendação inicial desta agenda é:
- fazer
Playchamar explicitamentebuildepack; - manter
buildepackcomo operações domain-owned com logs e resultado binário de sucesso/falha nesta wave; - adiar o controle fino de drift/freshness para uma agenda própria posterior;
- promover
build/como artifact root runnable desta wave; - gerar
manifest.jsonembuild/sempre a partir do build corrente; - tratar o resultado de cada operação como contrato explícito para o
Play, sem heurística oportunista baseada apenas em presença de arquivo.
Resolution
Próximo passo sugerido: fechar uma decision de studio que trave o fluxo de preparação do Play/Stop com estas amarras normativas já explícitas:
Playé apenas o orquestrador debuild,packemanifest;- nesta wave,
buildsempre executa quando chamado peloPlay; - nesta wave,
packsempre executa quando chamado peloPlay, e só é chamado sebuildtiver sucesso; - o artifact root runnable desta wave é
build/, nãocartridge/; manifest.jsoné sempre gerado deterministicamente embuild/, a partir do build corrente, e não copiado por conveniência;- freshness e drift ficam fora do escopo desta wave e, quando tratados, usarão arquivos dedicados por domínio sob
.studio/, comoasset-workspace.jsoneeditor-workspace.json; Playsó segue adiante quando as operações necessárias reportarem sucesso.