# Decision Record - `assets.pa` Autocontained Runtime Contract ## Status Accepted ## Contexto A agenda `023-asset-packer-runtime-facing-contract.md` existia para fechar a fronteira runtime-facing do packer de assets sem misturar essa discussao com o `shipper` do `.pmc`. O ponto de partida atual do runtime ainda e fragmentado: - `manifest.json` carrega `asset_table` e `preload`; - `assets.pa` contem apenas os bytes packed de payload; - o loader le `assets.pa` inteiro para memoria; - o `AssetManager` mantem esse blob inteiro residente. Ao mesmo tempo, a direcao desejada para o projeto ja esta clara: - o `packer` continua responsavel por produzir o artefato de assets; - o `shipper` continua responsavel por publicar `manifest.json` e montar o cart final; - o runtime deve consumir um `assets.pa` autocontido; - `asset_table`, `preload` e payload mantem o mesmo conteudo semantico atual; - o que muda e onde esses artefatos vivem e como o runtime os carrega. O alvo de hardware do PROMETEU e um handheld de baixo custo. Portanto, manter o blob inteiro de assets em RAM como regra geral nao e um baseline aceitavel. ## Decisao ### 1. `assets.pa` passa a ser o contrato runtime-facing de assets O contrato primario de assets consumido pelo runtime passa a ser o proprio `assets.pa`. `manifest.json` deixa de ser a superficie primaria para: - `asset_table`; - `preload`. O runtime continua agnostico a como o `packer` e o `shipper` produzem artefatos auxiliares. ### 2. `assets.pa` v1 e um binario autocontido `assets.pa` v1 deve ser estruturado como: ```text [prelude binario fixo] [header JSON] [payload binario] ``` O prelude binario fixo v1 contem, no minimo: - `magic` - `schema_version` - `header_len` - `payload_offset` Campos opcionais permitidos no prelude v1: - `flags` - `reserved` - `header_checksum` ### 3. O header JSON carrega `asset_table` e `preload` O header JSON de `assets.pa` e a estrutura que carrega: - `asset_table` - `preload` Essa decisao nao redefine o conteudo semantico dessas estruturas. Portanto: - `AssetEntry` permanece a fonte de verdade para identidade, codec, metadata e offsets; - `PreloadEntry` permanece um insumo de boot; - o payload packed continua representando os bytes frios dos assets. ### 4. Offsets da `asset_table` sao relativos ao payload Os `offset`s de `asset_table` permanecem relativos ao inicio da regiao de payload, nao ao inicio do arquivo inteiro. Isso preserva a semantica atual do runtime e evita contaminar `AssetEntry` com detalhes do envelope externo. O runtime resolve cada slice como: ```text payload_base + entry.offset ``` ### 5. Lifecycle de `preload` e `asset_table` no runtime O runtime deve tratar essas duas estruturas de forma diferente: - `preload` e dado transitorio de boot; - `asset_table` e a fonte da verdade para resolucao e carregamento de assets. Contrato operacional: 1. o runtime materializa `manifest.json`; 2. se `Capability::Asset` estiver presente, o runtime exige `assets.pa` valido imediatamente; 3. o runtime abre `assets.pa`, le o prelude e o header JSON; 4. o runtime materializa `asset_table` em memoria; 5. o runtime usa `preload` na fase de boot; 6. apos o boot, `preload` pode ser descartado; 7. `asset_table` permanece viva enquanto o cart estiver rodando. ### 6. Falha antecipada quando `Capability::Asset` exigir `assets.pa` Cart sem `assets.pa` continuam validos. Mas, se o `manifest.json` declarar `Capability::Asset`, a ausencia de `assets.pa` deve falhar o mais cedo possivel, antes da fase de preload. Essa falha pertence ao bootstrap do cart, nao ao lifecycle de `asset.load`. ### 7. Leitura de payload deve ser sob demanda O runtime nao deve manter o payload inteiro de `assets.pa` residente em memoria como comportamento baseline. O contrato de leitura do runtime passa a ser baseado em uma primitiva equivalente a: ```text open_slice(offset, size) ``` Essa primitiva abre uma view limitada para um asset dentro da regiao de payload. ### 8. Pipeline canonico de carregamento de asset O caminho canonico de carregamento passa a ser: ```text ROM -> open_slice -> CODEX/decode -> Bank ``` ou, quando o CODEX exigir materializacao temporaria: ```text ROM -> open_slice -> blob temporario em memoria -> CODEX/decode -> Bank ``` O runtime nunca deve materializar o `assets.pa` inteiro apenas para suportar carregamento de asset. ### 9. `OP_MODE` de consumo do payload O runtime deve encapsular o modo operacional de consumo do payload por asset. Esse `OP_MODE` escolhe entre: - leitura direta da ROM via view limitada; - materializacao temporaria do slice em memoria. Direcao v1: - o `OP_MODE` e derivado do `codec`/CODEX por padrao; - hint explicito adicional so deve ser introduzido se algum codec real admitir mais de um modo operacional viavel. ### 10. Artefatos auxiliares do packer continuam permitidos O `packer` pode continuar emitindo artefatos auxiliares para o `shipper`, por exemplo: - `asset_table.json`; - relatorios de build; - hashes; - inventarios. Mas esses artefatos: - sao derivados; - nao substituem o header interno de `assets.pa`; - nao definem o contrato runtime-facing. ## Rationale Esta decisao fecha a ambiguidade central da agenda `023` sem reabrir a semantica do dominio `asset`. Ela foi escolhida porque: - separa claramente `packer` e `shipper`; - reduz dependencia de metadata de asset espalhada em `manifest.json`; - preserva o shape semantico atual de `asset_table`, `preload` e payload; - melhora a adequacao do runtime para hardware barato; - evita carregar o blob inteiro em RAM; - permite que codecs com diferentes necessidades de IO operem sobre a mesma fronteira de leitura. O uso de prelude binario pequeno + header JSON foi adotado porque: - permite localizar o header com custo fixo; - mantem o header facil de produzir, inspecionar e depurar; - evita transformar o payload em estrutura textual; - reduz complexidade editorial no v1. ## Invariantes / Contrato - `assets.pa` e o contrato runtime-facing de assets. - `asset_table` e `preload` deixam de ser contrato primario de runtime no `manifest.json`. - `asset_table` e carregada do header de `assets.pa` e permanece viva durante toda a execucao do cart. - `preload` e carregado do header de `assets.pa`, usado no boot e descartavel apos a inicializacao. - payload offsets em `AssetEntry` sao relativos ao inicio da regiao de payload. - o runtime deve falhar cedo se `Capability::Asset` exigir `assets.pa` e o artefato nao existir. - o runtime nao deve manter o `assets.pa` inteiro em RAM como baseline. - o runtime deve expor leitura sob demanda por slice. - `OP_MODE` de consumo do slice e resolvido pelo runtime a partir do `codec`/CODEX, salvo decisao futura em contrario. - auxiliares do `packer` para o `shipper` nao tem autoridade normativa sobre o runtime. ## Impactos ### Specs - `13-cartridge.md` deve mover `asset_table` e `preload` para dentro do contrato de `assets.pa`. - `15-asset-management.md` deve descrever `assets.pa` como artefato autocontido, separar lifecycle de `preload` e `asset_table`, e registrar offsets relativos ao payload. - `16-host-abi-and-syscalls.md` so precisa ser tocada se a superficie host/runtime de inicializacao de assets mudar de forma observavel. ### Runtime - `cartridge_loader.rs` deve deixar de ler `assets.pa` inteiro para `Vec` como baseline. - `cartridge.rs` deve parar de tratar `asset_table` e `preload` como dados vindos do `manifest`. - o bootstrap deve checar cedo a presenca de `assets.pa` quando `Capability::Asset` estiver declarada. - o `AssetManager` deve manter `asset_table` viva, aplicar `preload` no boot e ler payload por slice sob demanda. - a leitura atual baseada em `Arc>>` deve evoluir para uma origem de leitura por ROM/view/slice. ### Shipper / Packer - o `packer` deve produzir `assets.pa` com prelude + header JSON + payload. - o `shipper` continua livre para consumir auxiliares JSON, mas deve tratar `assets.pa` como artefato de verdade para assets. - o `manifest.json` publicado pelo `shipper` deixa de carregar `asset_table` e `preload` como contrato primario de runtime. ### Firmware / Boot - a etapa de carga do cart deve abrir `assets.pa`, extrair header e decidir falha cedo antes de preload. - preload deixa de ser atributo editorial do manifest e passa a ser insumo interno do artefato de assets. ## Referencias - `../specs/13-cartridge.md` - `../specs/15-asset-management.md` - `../agendas/008-packed-cartridge-loader-pmc.md` - `../../../studio/docs/packer/Prometeu Packer.md` - `../../crates/console/prometeu-hal/src/cartridge_loader.rs` - `../../crates/console/prometeu-hal/src/cartridge.rs` - `../../crates/console/prometeu-drivers/src/asset.rs` ## Propagacao Necessaria - criar PR/plan para atualizar specs `13` e `15`; - criar PR/plan de codigo para: - mudar o loader de cart para abrir header de `assets.pa`; - mover `asset_table`/`preload` para a leitura do binario de assets; - introduzir leitura sob demanda por slice; - remover o baseline de payload inteiro residente; - falhar cedo quando `Capability::Asset` exigir `assets.pa` ausente; - agenda `023-asset-packer-runtime-facing-contract.md` deve ser considerada fechada e removida da lista de agendas ativas; - agenda `008-packed-cartridge-loader-pmc.md` passa a depender desta decisao como base do artefato de assets.