prometeu-runtime/discussion/workflow/agendas/AGD-0019-asset-entry-codec-enum-with-metadata.md

184 lines
9.4 KiB
Markdown

---
id: AGD-0019
ticket: asset-entry-codec-enum-with-metadata
title: Agenda - Asset Entry Codec as Enum with Metadata
status: accepted
created: 2026-04-09
resolved: 2026-04-09
decision: DEC-0005
tags: [asset, runtime, codec, metadata]
---
# Agenda - Asset Entry Codec as Enum with Metadata
## Contexto
A `DSC-0017` consolidou a normalizacao de `AssetEntry.metadata`, separando campos criticos na raiz e empurrando detalhes tecnicos para subarvores como `codec` e `pipeline`.
Isso resolveu a organizacao do contrato, mas nao fechou a representacao tipada de `codec` dentro do runtime. Hoje o dado ainda e percebido mais como JSON dinamico do que como parte explicita do modelo de dominio.
O tema desta agenda e decidir se `codec` em `AssetEntry` deve deixar de ser apenas um blob/subarvore e passar a ser um enum tipado, capaz de carregar os metadados pertinentes a cada codec.
## Problema
Quando `codec` e tratado como JSON generico ou como informacao frouxa em metadados, o runtime perde:
- clareza sobre quais codecs existem de fato;
- validacao estrutural forte por variante;
- ergonomia para loaders e drivers;
- separacao nitida entre metadata do banco e metadata do codec.
Ao mesmo tempo, tipar `codec` cedo demais ou de forma larga demais pode misturar responsabilidades e transformar o enum em um deposito generico de qualquer detalhe tecnico do asset.
## Pontos Criticos
1. Limite de responsabilidade.
`codec` deve carregar apenas dados necessarios para decodificacao, nao toda a metadata do asset.
2. Compatibilidade com a normalizacao anterior.
A agenda nao deve reabrir a decisao de segmentar metadata; ela deve apenas fechar como o segmento `codec` vira modelo tipado no runtime.
3. Evolucao de formato.
O modelo precisa permitir codecs sem payload adicional e codecs com configuracao especifica, sem cair em campos opcionais demais.
4. Unknown/forward compatibility.
Precisamos decidir se codecs desconhecidos falham no parse, se ficam preservados como raw JSON, ou se existe modo hibrido.
5. Impacto nos callers.
A mudanca afeta serializacao/deserializacao, helpers, validacao de cart e ergonomia dos loaders.
## Opcoes
### Opcao A - Manter `codec` como JSON dinamico
- **Abordagem:** manter `codec` como subarvore em `metadata` ou como `serde_json::Value`, usando helpers tipados apenas nos pontos de consumo.
- **Pro:** menor migracao imediata e maior flexibilidade para formatos experimentais.
- **Con:** o contrato real continua implicito, com checagens espalhadas e mais risco de drift entre parser e consumidores.
- **Tradeoff:** adia a decisao de dominio e preserva a ambiguidade exatamente no ponto onde o runtime precisa de semantica forte.
### Opcao B - Tornar `codec` um enum tipado com payload por variante
- **Abordagem:** introduzir algo como `AssetCodec`, com variantes explicitas (`None`, `Png { ... }`, `Jpeg { ... }`, etc.) carregando apenas os metadados do proprio codec.
- **Pro:** o runtime ganha exaustividade, parse centralizado e um modelo de dominio mais honesto.
- **Con:** exige decidir fronteiras claras entre metadata do codec e metadata do banco/asset; tambem aumenta custo de evolucao quando novos codecs surgem.
- **Tradeoff:** troca flexibilidade irrestrita por contrato forte e melhor ergonomia operacional.
### Opcao C - Separar `codec_kind` de um payload opcional tipado
- **Abordagem:** usar um enum leve para o tipo de codec e um campo separado para configuracao adicional.
- **Pro:** reduz acoplamento do discriminante com o payload e pode simplificar alguns formatos.
- **Con:** reintroduz estados invalidos (`kind` e payload divergentes), exigindo validacao cruzada manual.
- **Tradeoff:** parece mais flexivel, mas perde a principal vantagem de um tagged enum: coerencia estrutural por construcao.
## Sugestao / Recomendacao
Seguir com a **Opcao B**.
`codec` em `AssetEntry` deveria ser um enum tipado e capaz de carregar os metadados estritamente relativos a ele. Isso fecha melhor o modelo de dominio: o runtime deixa de tratar codec como detalhe textual solto e passa a reconhece-lo como parte semantica do contrato do asset.
A recomendacao, no entanto, vem com uma fronteira explicita:
- metadata especifica de decodificacao fica dentro do enum do codec;
- metadata do banco/formato de consumo continua fora dele;
- metadata editorial ou operacional do asset tambem continua fora dele.
Em outras palavras, a discussao nao e "colocar toda metadata dentro de `codec`", e sim "dar ao segmento `codec` uma representacao tipada, exaustiva e com payload por variante quando necessario".
Com as respostas atuais, a recomendacao fica mais concreta:
- o JSON serializado pelo Studio dentro de `asset.pa` pode manter `codec` como string opaca;
- o runtime Rust deve desserializar essa string diretamente para um enum em `AssetEntry`;
- o nome canonico de cada codec no JSON deve seguir o contrato definido pelo runtime, e o Studio/paker deve se conformar exatamente a ele;
- a variante inicial canonica e apenas `None`;
- `Raw` deve ser considerada removida do modelo;
- codec desconhecido no runtime e erro fatal de carregamento e deve impedir a execucao do cartucho;
- `pipeline` nao deve sobreviver no runtime e pode ser descartado completamente desse lado.
## Perguntas em Aberto
- Como o modelo evolui quando surgir o primeiro codec real com payload adicional sem perder a separacao entre o discriminante string no JSON e a interpretacao tipada no runtime?
## Discussao
### Direcao fechada ate aqui
1. **Serializacao no Studio**
O JSON serializado pelo Studio dentro de `asset.pa` deve expor `codec` como string opaca.
2. **Desserializacao no runtime**
O runtime Rust deve carregar essa string diretamente em um enum no proprio `AssetEntry`. O wire format continua string, mas o modelo carregado no runtime passa a ser tipado.
3. **Canon do nome**
O nome textual do codec no JSON nao e arbitrario por produtor. Ele deve seguir exatamente o canon definido pelo contrato. O canon fechado para este tema e `SCREAMING_SNAKE_CASE`, alinhado a `BankType`, e o packer deve seguir esse formato sem aliases livres.
4. **Variante inicial**
O unico codec canonico agora e `None`.
5. **Fim de `Raw`**
`Raw` nao deve mais existir como conceito no modelo.
6. **Codecs desconhecidos**
Nao devem ser empacotados. Se mesmo assim chegarem ao runtime, isso e erro de validacao do `AssetEntry` e o cartucho deve ser fechado antes de seguir.
7. **Escopo atual de codecs**
Como ainda nao existe codec real implementado, a primeira versao do enum pode ser minima e conter apenas `None`.
8. **Destino de `pipeline`**
`pipeline` nao tem valor operacional no runtime atual e pode ser descartado completamente desse lado.
### Leitura arquitetural dessas respostas
As respostas empurram a agenda para um contrato bem mais estrito do que o texto inicial sugeria:
- `codec` existe como conceito de dominio mesmo antes de haver codecs concretos alem de `None`;
- o JSON de `asset.pa` pode manter um discriminante simples e opaco, enquanto o runtime desserializa isso diretamente para enum e usa esse valor para escolher a interpretacao tipada de `metadata.codec`;
- a autoridade sobre o spelling do codec pertence ao contrato compartilhado, nao ao Studio isoladamente;
- o runtime nao deve carregar extensibilidade aberta para codecs desconhecidos;
- a compatibilidade futura deve ser dirigida pelo Studio e pelo empacotamento, nao por tolerancia dinamica no runtime;
- `pipeline` deixa de disputar espaco conceitual com `codec` no runtime.
Isso favorece um modelo de enum fechado, validado cedo e com semantica fail-fast.
## Criterio para Encerrar
Esta agenda pode ser encerrada quando houver consenso escrito sobre:
- o papel exato de `codec` no modelo de dominio do `AssetEntry`;
- a fronteira entre payload do codec e restante da metadata;
- a estrategia para codecs sem metadata adicional e para codecs desconhecidos;
- o shape string de `codec` no JSON e sua relacao com o enum carregado no runtime e com `metadata.codec`;
- o proximo passo normativo para transformar isso em decisao sem reabrir `DSC-0017`.
## Resolucao Provisoria
Ha consenso provisoriamente estabelecido sobre os seguintes pontos:
- `codec` deve existir como enum tipado no modelo do runtime;
- a variante inicial unica e `None`;
- `Raw` sai do contrato;
- codecs desconhecidos sao invalidos e devem falhar de forma fatal no carregamento do cartucho;
- `pipeline` pode ser descartado do runtime;
- o JSON de `asset.pa` deve serializar `codec` como string opaca;
- o runtime Rust deve desserializar essa string diretamente para enum no `AssetEntry`;
- o nome textual do codec no JSON deve seguir `SCREAMING_SNAKE_CASE`, e o Studio deve se conformar exatamente a ele;
- codec desconhecido deve falhar na validacao do `AssetEntry`, antes de qualquer carga efetiva.
O unico ponto em aberto passa a ser a politica de evolucao para o primeiro codec real com payload, preservando a distincao entre:
- discriminante string no JSON do asset; e
- shape tipado de `metadata.codec` no runtime.
## Resolucao
A agenda fica encerrada com a seguinte orientacao:
- `codec` permanece `string` no JSON de `asset.pa`;
- o runtime Rust deve desserializar essa string diretamente para enum no `AssetEntry`;
- o nome textual do codec segue `SCREAMING_SNAKE_CASE`, alinhado a `BankType`;
- `None` e a unica variante inicial;
- `Raw` sai do contrato;
- codec desconhecido falha na validacao do `AssetEntry` e fecha o cartucho;
- `pipeline` e descartado do runtime.
A evolucao para codecs com payload adicional fica explicitamente adiada para uma decisao futura motivada por um codec real.