--- id: AGD-0016 ticket: asset-entry-metadata-normalization-contract title: Asset Entry Metadata Normalization Contract status: open created: 2026-03-27 resolved: decision: tags: [] --- # Asset Entry Metadata Normalization Contract Status: Open Domain Owner: `docs/runtime` Cross-Domain Impact: `../studio/docs/packer`, `shipper`, `asset` loader ## Purpose Normatizar como `AssetEntry.metadata` deve preservar a convergencia entre metadata autoral, metadata de codec e metadata de pipeline sem colapsar tudo num mapa plano ambiguo. ## Problem O lado produtor (`packer`) ja convergiu para um contrato em que o runtime precisa ler campos obrigatorios diretamente de `AssetEntry.metadata`, mas tambem precisa manter segmentacao suficiente para nao perder significado entre: - `asset.json.output.metadata` - `asset.json.output.codec_configuration` - `asset.json.output.pipeline` Sem um contrato explicito no runtime: - o packer pode materializar estruturas diferentes entre formatos; - o loader/runtime pode passar a depender de flattening incidental; - tooling e debug surfaces perdem previsibilidade; - futuros formatos tendem a misturar metadata efetiva com detalhe interno de pipeline. ## Context No ciclo atual de `tile bank`, o produtor ja fechou esta direcao: - `asset.json.output.metadata` -> `AssetEntry.metadata` - `asset.json.output.codec_configuration` -> `AssetEntry.metadata.codec` - `asset.json.output.pipeline` -> `AssetEntry.metadata.pipeline` Ao mesmo tempo, o runtime ainda consome alguns campos obrigatorios do tile bank diretamente no nivel raiz de `AssetEntry.metadata`, em especial: - `tile_size` - `width` - `height` - `palette_count` A agenda precisa fechar se esse shape vira contrato geral de runtime para metadata normalizada de assets, e como o consumidor deve tratar campos obrigatorios format-specific versus subtrees segmentadas. ## Options ### Option A - Flat effective metadata map only Tudo converge para um unico mapa plano em `AssetEntry.metadata`. ### Option B - Root effective metadata plus stable segmented subtrees Campos runtime-obrigatorios ficam legiveis no nivel raiz, enquanto dados de codec e pipeline ficam em subtrees estaveis: - `metadata.` - `metadata.codec.` - `metadata.pipeline.` ### Option C - Fully segmented metadata only Nada fica no nivel raiz; todo consumo passa por subtrees por origem. ## Tradeoffs - Option A simplifica leitura curta, mas perde origem semantica e aumenta risco de colisao. - Option B preserva leitura direta para campos obrigatorios do runtime e mantem segmentacao estavel para evolucao futura. - Option C e semanticamente limpa, mas quebra o consumo direto atual de formatos como `tile bank` e introduz custo de migracao desnecessario agora. ## Recommendation Adotar `Option B`. Direcao recomendada: - campos format-specific obrigatorios para decode/runtime continuam legiveis no nivel raiz de `AssetEntry.metadata`; - `output.codec_configuration` materializa em `AssetEntry.metadata.codec`; - `output.pipeline` materializa em `AssetEntry.metadata.pipeline`; - o runtime nao deve exigir flattening total para consumir metadata segmentada; - specs format-specific devem declarar explicitamente quais campos sao obrigatorios no nivel raiz. ## Open Questions 1. O contrato deve tratar o subtree raiz como semanticamente equivalente a `output.metadata` ou como effective metadata map mais amplo? 2. Quais readers/helpers do runtime devem ser criados para evitar parsing manual disperso de `metadata.codec` e `metadata.pipeline`? ## Expected Follow-up 1. Converter esta agenda em decision no `runtime`. 2. Propagar a decisao para `15-asset-management.md`. 3. Ajustar loaders format-specific para usar helpers consistentes de metadata quando necessario. 4. Alinhar o `packer` e testes de conformance com o shape final.