prometeu-studio/discussion/workflow/decisions/DEC-0027-studio-composer-sprite-syscall-alignment.md

159 lines
6.3 KiB
Markdown

---
id: DEC-0027
ticket: studio-frame-composer-syscall-and-sprite-alignment
title: Studio MUST Adopt `@sdk:composer` for Sprite Composition and Remove `Gfx.set_sprite`
status: in_progress
created: 2026-04-18
accepted: 2026-04-18
agenda: AGD-0031
plans:
- PLN-0053
- PLN-0054
- PLN-0055
tags:
- studio
- compiler
- pbs
- stdlib
- runtime-alignment
- abi
- syscall
- frame-composer
- sprites
---
## Context
O `../runtime` já convergiu a ownership pública de frame orchestration para `FrameComposer` e já publicou a ABI pública correspondente no domínio `composer.*`.
Para o recorte desta discussão, o ponto normativo relevante é simples:
- sprite composition não pertence mais ao domínio público `gfx.*`;
- o caminho público legado `gfx.set_sprite` já não representa o owner canônico no runtime;
- o Studio ainda expõe esse caminho legado em stdlib, specs, testes, fixtures e exemplos.
Isso cria drift entre:
- a ABI pública real do runtime;
- o contrato que o Studio ensina e emite;
- a superfície que PBS usa como owner visível para composição de sprites.
O usuário fechou explicitamente o escopo desta decisão:
- entra apenas a wave de `@sdk:composer` para sprite composition;
- entra `composer.emit_sprite`;
- entra remoção total de `Gfx.set_sprite`;
- `composer.bind_scene`, `composer.unbind_scene` e `composer.set_camera` ficam para trabalho posterior;
- scene bank e concerns de authoring/editor ficam fora deste ticket.
## Decision
O Studio MUST adotar `@sdk:composer` como a superfície canônica de stdlib/PBS para sprite composition nesta wave.
Mais especificamente:
1. A operação pública de composição de sprites MUST ser exposta por `composer.emit_sprite`.
2. O módulo reservado `@sdk:composer` MUST seguir o mesmo shape editorial hoje usado por `@sdk:gfx`:
- um owner host de baixo nível `LowComposer`;
- uma façade pública `Composer`.
3. Nesta wave, o contrato de retorno de `composer.emit_sprite` MUST permanecer um `int` cru.
4. `Gfx.set_sprite` MUST ser removido integralmente da superfície normativa e executável do Studio.
5. O repositório MUST NOT manter alias, wrapper de compatibilidade, dual path, ou retargeting silencioso que preserve `Gfx.set_sprite` como API pública.
6. `@sdk:gfx` MUST permanecer restrito às operações primitivas/overlay/backend-adjacent que continuarem pertencendo a esse domínio.
7. `composer.bind_scene`, `composer.unbind_scene` e `composer.set_camera` MUST permanecer fora do escopo de implementação desta decisão e SHALL ser adicionados depois por propagação separada, usando o mesmo padrão editorial.
## Rationale
Esta decisão existe para eliminar um dual contract arquitetural que já deixou de ser válido no runtime.
Manter `Gfx.set_sprite` como superfície pública teria três efeitos ruins:
- preservaria o owner errado no contrato ensinado por PBS/stdlib;
- manteria dois modelos mentais concorrentes para a mesma operação;
- empurraria a remoção real do legado para um momento futuro mais caro e mais difícil.
O recorte sprite-only é deliberado.
Ele permite alinhar imediatamente a parte já necessária para o pipeline atual sem misturar:
- rollout de scene binding;
- rollout de camera control;
- ou trabalho de scene bank/editoria de assets.
Também ficou decidido que esta wave não tentará resolver modelagem de status com tipos editoriais novos.
O retorno cru `int` é suficiente para convergir o boundary agora, sem introduzir uma segunda mudança de API no mesmo passo.
## Technical Specification
### 1. Stdlib Surface
O repositório MUST introduzir um módulo reservado `@sdk:composer`.
Esse módulo MUST:
- declarar `LowComposer` com metadata canônica `Host(module = "composer", name = "emit_sprite", version = 1)`;
- declarar a capability canônica correspondente;
- expor `Composer.emit_sprite(...)` como façade pública;
- usar o mesmo padrão estrutural já adotado por `@sdk:gfx`.
O repositório MUST remover de `@sdk:gfx`:
- a declaração host `LowGfx.set_sprite(...)`;
- a façade pública `Gfx.set_sprite(...)`;
- qualquer export relacionado à operação pública antiga.
### 2. Compiler and PBS Propagation
As specs e implementações de PBS/compiler MUST passar a tratar `@sdk:composer` como a superfície canônica para sprite composition.
Isso inclui:
- examples normativos;
- exemplos de import;
- resolução de stdlib;
- fixtures e testes que verificam host metadata;
- testes que hoje afirmam `LowGfx`/`Gfx.set_sprite`.
O lowering MUST emitir identidade canônica de host do domínio `composer`, não do domínio `gfx`, para sprite emission nesta wave.
### 3. Removal Rule
`Gfx.set_sprite` MUST ser tratado como removido, não como deprecated.
Consequências obrigatórias:
- código de teste antigo que use `Gfx.set_sprite` MUST ser migrado;
- fixtures e sample projects SHOULD ser migrados integralmente nesta wave sempre que estiverem dentro do repositório;
- docs MUST deixar de ensinar `Gfx.set_sprite` como caminho válido;
- a implementação MUST NOT deixar fallback oculto para o caminho antigo.
### 4. Documentation Scope
As specs MUST documentar exatamente o que esta wave implementa:
- `@sdk:composer` para sprite emission;
- remoção de `Gfx.set_sprite`;
- permanência de `@sdk:gfx` para primitivas/overlay relevantes.
As specs MUST NOT fingir que scene binding ou camera control já fazem parte desta wave no Studio.
Elas MAY mencionar que:
- `bind_scene`,
- `unbind_scene`,
- `set_camera`
serão adicionados depois seguindo o mesmo padrão, mas sem tratá-los como parte implementada agora.
## Constraints
- Esta decisão MUST ser tratada como normativa e locked até revisão explícita do usuário.
- Qualquer `plan` derivado dela MUST cobrir integralmente a criação de `@sdk:composer`, a propagação para specs/compiler/tests e a remoção total de `Gfx.set_sprite`.
- Nenhum `plan` ou `implement` pode reinterpretar esta decisão como “migrar só internamente” mantendo a API pública antiga.
- Nenhum `plan` ou `implement` pode puxar scene bank, bind/unbind de scene ou camera para dentro deste ticket por conveniência.
- Se surgir ambiguidade sobre assinatura exata de `emit_sprite`, capability metadata, ou pontos concretos de propagação, o próximo estágio MUST esclarecer isso sem reabrir a remoção total do caminho antigo.
## Revision Log
- 2026-04-18: Initial accepted decision from AGD-0031.