194 lines
11 KiB
Markdown
194 lines
11 KiB
Markdown
---
|
|
id: AGD-0029
|
|
ticket: scene-bank-glyph-runtime-binding-leak
|
|
title: Scene Bank vazando glyph bank id runtime para o formato binario
|
|
status: accepted
|
|
created: 2026-04-24
|
|
resolved: 2026-04-24
|
|
decision: DEC-0021
|
|
tags: [gfx, runtime, asset, scene, glyph, format, architecture]
|
|
---
|
|
|
|
## Contexto
|
|
|
|
Hoje o payload binario `SCENE` carrega `glyph_bank_id` por layer e o runtime usa esse valor como chave operacional para resolver o `GlyphBank` residente durante o render.
|
|
|
|
A cadeia atual eh:
|
|
|
|
- o decoder de `SCENE` le `glyph_bank_id` do payload;
|
|
- `SceneLayer` preserva esse campo no modelo canonico carregado;
|
|
- `SceneViewportCache` copia o mesmo id para a cache;
|
|
- o renderer consulta `GlyphBankPoolAccess` por esse slot/id para desenhar a layer.
|
|
|
|
Isso cria um acoplamento direto entre formato frio de asset e topologia de residencia runtime. A suspeita levantada eh que esse campo nao deveria existir no wire-format, porque a referencia correta ao glyph bank deveria ser resolvida apenas pelo runtime.
|
|
|
|
## Problema
|
|
|
|
O contrato atual mistura duas camadas que deveriam permanecer separadas:
|
|
|
|
- o asset `SCENE` como descricao fria de composicao;
|
|
- o binding de slot/banco residente como estado operacional do runtime.
|
|
|
|
Se `glyph_bank_id` realmente for um detalhe exclusivamente runtime, o formato binario atual esta errado e o runtime passou a depender de um identificador que nao deveria ser serializado nem publicado como parte do asset.
|
|
|
|
Isso deixa perguntas abertas sobre:
|
|
|
|
- como uma layer de cena passa a apontar para um glyph source sem carregar um slot runtime no payload;
|
|
- onde esse binding deve viver;
|
|
- como preload, install e bind de cena passam a cooperar sem reintroduzir ambiguidade.
|
|
|
|
## Pontos Criticos
|
|
|
|
- O renderer atual resolve a bank diretamente a partir de `layer_cache.glyph_bank_id`, entao qualquer correcao toca formato, modelo em memoria e caminho de render.
|
|
- O payload `SCENE` ja foi materializado em testes e tooling com esse byte no header da layer, entao a mudanca implica migracao/versionamento ou ruptura controlada.
|
|
- O contrato de asset management enfatiza slots como conceito runtime e resolve contexto de banco via `asset_table` e preload, o que conflita com `SCENE` carregar referencia operacional propria.
|
|
- Precisamos evitar uma "correcao" que apenas mova o mesmo acoplamento para outro nome sem restaurar a fronteira correta entre asset frio e binding runtime.
|
|
|
|
## Opcoes
|
|
|
|
### Opcao 1 - Manter `glyph_bank_id` dentro do formato `SCENE`
|
|
|
|
- **Abordagem:** aceitar explicitamente que cada layer da cena referencia um slot/runtime glyph bank no proprio payload e documentar isso como contrato oficial.
|
|
- **Pros:** menor mudanca imediata; preserva compatibilidade com decoder, tests e tooling atuais.
|
|
- **Contras:** cristaliza o vazamento arquitetural; faz o asset depender de topologia runtime; dificulta relocacao, preload flexivel e reuso de cena em contextos diferentes.
|
|
- **Trade-off:** simples agora, mais rigido e mais fragil como contrato de longo prazo.
|
|
|
|
### Opcao 2 - Remover o id do wire-format e resolver o binding por runtime ao ativar a cena
|
|
|
|
- **Abordagem:** o payload `SCENE` deixa de carregar slot/id de glyph bank; a associacao layer -> fonte grafica passa a ser injetada por metadados de runtime, por preload derivado, ou por um binding explicito durante `bind_scene`.
|
|
- **Pros:** restaura a separacao asset frio vs residencia runtime; permite relocacao de slots e politica de preload sem contaminar o formato.
|
|
- **Contras:** exige definir uma nova fonte de verdade para o binding; impacta decoder, modelo de cena, renderer, specs e ferramentas.
|
|
- **Trade-off:** maior custo de migracao, mas fronteira arquitetural mais coerente.
|
|
|
|
### Opcao 3 - Manter referencia serializada, mas trocar de slot runtime para identidade fria
|
|
|
|
- **Abordagem:** o payload `SCENE` deixa de carregar `glyph_bank_id` runtime e passa a carregar uma referencia fria estavel por layer, como `asset_id` ou handle logico de glyph source; o runtime resolve essa identidade para slot residente quando a cena eh ativada.
|
|
- **Pros:** preserva auto-descricao da cena sem serializar topologia de residencia; reduz dependencia de slot fixo.
|
|
- **Contras:** ainda precisamos decidir se a cena deve conhecer assets frios diretamente; adiciona etapa de resolucao e falha operacional nova.
|
|
- **Trade-off:** melhor que serializar slot runtime, mas ainda pode acoplar demais o asset `SCENE` ao catalogo de assets.
|
|
|
|
## Sugestao / Recomendacao
|
|
|
|
Direcao escolhida nesta agenda:
|
|
|
|
- seguir pela **Opcao 3** com identidade fria por `asset_id`;
|
|
- remover `glyph_bank_id` runtime do formato binario `SCENE`;
|
|
- fazer o `SCENE` carregar, por layer, o `asset_id` do glyph dependency;
|
|
- resolver `asset_id -> glyph slot` no momento de `bind_scene`;
|
|
- falhar operacionalmente se qualquer dependencia grafica da cena nao estiver comprometida em algum slot glyph;
|
|
- a ordem de carregamento dos assets nos bancos nao importa;
|
|
- **sem versionamento e sem compatibilidade retroativa por enquanto**.
|
|
|
|
Motivo:
|
|
|
|
- slot de glyph bank eh conceito runtime e nao deve viver no wire-format;
|
|
- `asset_id` eh identidade fria e estavel dentro do contrato de assets;
|
|
- bind-time resolution preserva a liberdade de preload/commit e evita acoplamento do asset `SCENE` a uma topologia fixa de slots;
|
|
- a falha operacional em `bind_scene` mantem o problema na fronteira correta de ativacao.
|
|
|
|
Cravado nesta agenda:
|
|
|
|
- `SceneBank` canonico nao deve carregar slot runtime de glyph;
|
|
- o payload `SCENE` deve declarar dependencias frias, nao residencia;
|
|
- a vinculacao layer -> glyph slot pertence ao runtime no momento de ativacao da cena;
|
|
- o runtime deve validar dependencias no `bind_scene`, mas nao deve persistir um snapshot resolvido como dado canonico da cena;
|
|
- no draw de cada layer, o runtime pode consultar novamente qual slot contem o `asset_id` referido pela cena;
|
|
- ausencia da dependencia em qualquer ponto relevante do fluxo deve produzir erro operacional.
|
|
- a resolucao `asset_id -> slot` fica interna nesta etapa;
|
|
- a resolucao interna deve ser suportada por indice reverso `asset_id -> slot`, nao depender apenas de scan linear dos slots;
|
|
- o payload `SCENE` deve aumentar a largura do campo para comportar `AssetId = i32`;
|
|
- cada layer publica sua propria dependencia glyph diretamente;
|
|
- falha de dependencia no caminho de draw/composition deve ser tratada como erro fatal da maquina, com log claro.
|
|
- falha de dependencia no `bind_scene` tambem deve ser tratada como erro fatal da maquina, com log claro.
|
|
|
|
## Perguntas em Aberto
|
|
|
|
## Criterio para Encerrar
|
|
|
|
Esta agenda pode ser encerrada quando houver resposta clara e defendivel para:
|
|
|
|
- como o `SCENE` publica dependencias por `asset_id`;
|
|
- como o runtime consulta `asset_id -> slot` durante bind e draw;
|
|
- qual representacao binaria carregara o `asset_id` por layer;
|
|
- como o contrato de erro fatal e log claro se aplica em bind e draw.
|
|
|
|
## Discussao
|
|
|
|
Estado inicial da investigacao:
|
|
|
|
- ha vazamento real hoje no codigo e no tooling;
|
|
- nao encontrei decisao normativa registrada que feche explicitamente esse acoplamento;
|
|
- portanto o tema continua aberto e precisa de decisao arquitetural antes de qualquer correcao de spec ou codigo.
|
|
|
|
Atualizacao de 2026-04-24:
|
|
|
|
O caminho proposto pelo usuario parece tecnicamente viavel com a infraestrutura atual, embora ainda nao exista como contrato explicito.
|
|
|
|
O que ja existe hoje:
|
|
|
|
- o `AssetManager` mantem deduplicacao/residencia por `asset_id`;
|
|
- no commit/preload, cada slot fisico passa a registrar qual `asset_id` esta instalado nele;
|
|
- portanto o runtime ja possui as duas metades da informacao:
|
|
- `asset_id -> resident object`;
|
|
- `slot -> asset_id`.
|
|
|
|
O que ainda nao existe:
|
|
|
|
- uma API canonica `asset_id -> slot` para lookup de um asset ja comprometido em um banco;
|
|
- uma forma de `SceneBank` carregar dependencias por `asset_id` em vez de `glyph_bank_id`;
|
|
- um `bind_scene` capaz de validar todas as dependencias da cena e falhar operacionalmente se alguma nao estiver residente em slot algum.
|
|
|
|
Leitura atual da proposta:
|
|
|
|
- o payload `SCENE` carrega, por layer, o `asset_id` do glyph dependency;
|
|
- `composer.bind_scene(scene_slot)` continua selecionando a cena residente;
|
|
- durante o bind, o runtime resolve cada `asset_id` dependente para o slot glyph atualmente comprometido;
|
|
- durante o draw de cada layer, o runtime pode consultar novamente em qual slot o `asset_id` esta residente;
|
|
- a ordem de carregamento deixa de importar porque a resolucao eh feita contra o estado runtime no momento da operacao;
|
|
- se qualquer dependencia nao estiver carregada em algum slot glyph, `bind_scene` retorna falha operacional e nao ativa a cena.
|
|
|
|
Essa direcao preserva a fronteira correta melhor do que o modelo atual:
|
|
|
|
- o `SCENE` deixa de carregar topologia runtime;
|
|
- a cena continua auto-descritiva o suficiente para declarar suas dependencias frias;
|
|
- o runtime continua dono da residencia e da escolha de slot efetivo.
|
|
|
|
Ponto de atencao:
|
|
|
|
- essa direcao prefere nao manter snapshot resolvido como dado persistido da cena;
|
|
- portanto o contrato precisa dizer com clareza como o sistema reage se uma dependencia desaparecer entre bind e draw.
|
|
|
|
Direcao aceita na discussao atual:
|
|
|
|
- seguir com dependencia fria por `asset_id` no `SCENE`;
|
|
- resolver para slot glyph somente no `bind_scene`;
|
|
- permitir nova consulta `asset_id -> slot` tambem no draw das layers;
|
|
- nao expor lookup como API publica nesta etapa;
|
|
- manter indice reverso interno `asset_id -> slot` desde ja, para evitar acoplamento da solucao a scan linear de poucos slots;
|
|
- aumentar a largura do payload para carregar `AssetId = i32` no `SCENE`;
|
|
- tratar dependencia ausente no `bind_scene` como falha fatal da maquina, com log claro;
|
|
- tratar dependencia ausente no draw/composition como falha fatal da maquina, com log claro;
|
|
- nao fazer versionamento nem camada de compatibilidade nesta etapa.
|
|
|
|
Resposta consolidada do usuario na discussao:
|
|
|
|
- nao devemos materializar esse binding como dado resolvido persistente;
|
|
- devemos checar no bind e tambem quando formos desenhar a layer;
|
|
- a resolucao `asset_id -> slot` pode e deve evoluir para API publica futuramente, mas fica interna por enquanto;
|
|
- como essa resolucao tende a virar API publica, a base interna deve nascer como indice reverso e nao como mero loop sobre 16 slots;
|
|
- como `AssetId` canonico eh `i32`, o payload precisa aumentar a largura do campo serializado;
|
|
- cada layer carrega sua propria dependencia glyph;
|
|
- se a dependencia faltar ou nao puder ser resolvida no `bind_scene`, isso deve quebrar a maquina com log claro;
|
|
- se a dependencia sumir ou nao puder ser resolvida no caminho de draw/composition, isso tambem deve quebrar a maquina com log claro, porque nao ha como prosseguir corretamente sem as dependencias da cena.
|
|
|
|
## Resolution
|
|
|
|
Encerrada em 2026-04-24.
|
|
|
|
Resolucao aceita:
|
|
|
|
- `SCENE` deixa de carregar slot runtime de glyph e passa a carregar `AssetId` por layer;
|
|
- o runtime resolve `asset_id -> slot` via indice reverso interno;
|
|
- falta de dependencia fataliza a maquina tanto no `bind_scene` quanto no draw/composition, com log claro;
|
|
- nao ha versionamento nem compatibilidade retroativa nesta etapa.
|