dev/runtime-owned-variable-glyph-bank-palette-protocol #37
0
discussion/.index.lock
Normal file
0
discussion/.index.lock
Normal file
@ -1,4 +1,4 @@
|
|||||||
{"type":"meta","next_id":{"DSC":46,"AGD":49,"DEC":41,"PLN":167,"LSN":55,"CLSN":1}}
|
{"type":"meta","next_id":{"DSC":47,"AGD":50,"DEC":42,"PLN":173,"LSN":55,"CLSN":1}}
|
||||||
{"type":"discussion","id":"DSC-0044","status":"done","ticket":"hub-suspended-game-kill-affordance","title":"Hub Suspended Game Kill Affordance","created_at":"2026-07-05","updated_at":"2026-07-05","tags":["hub","lifecycle","game","ui"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0054","file":"discussion/lessons/DSC-0044-hub-suspended-game-kill-affordance/LSN-0054-manual-hub-kill-must-share-game-termination-cleanup.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]}
|
{"type":"discussion","id":"DSC-0044","status":"done","ticket":"hub-suspended-game-kill-affordance","title":"Hub Suspended Game Kill Affordance","created_at":"2026-07-05","updated_at":"2026-07-05","tags":["hub","lifecycle","game","ui"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0054","file":"discussion/lessons/DSC-0044-hub-suspended-game-kill-affordance/LSN-0054-manual-hub-kill-must-share-game-termination-cleanup.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]}
|
||||||
{"type":"discussion","id":"DSC-0043","status":"done","ticket":"system-os-cartridge-switch-orchestrator","title":"SystemOS Cartridge Switch Orchestrator","created_at":"2026-07-03","updated_at":"2026-07-05","tags":["runtime","os","lifecycle","game","cartridge","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0053","file":"discussion/lessons/DSC-0043-system-os-cartridge-switch-orchestrator/LSN-0053-game-switching-is-lifecycle-replacement-not-loader-work.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]}
|
{"type":"discussion","id":"DSC-0043","status":"done","ticket":"system-os-cartridge-switch-orchestrator","title":"SystemOS Cartridge Switch Orchestrator","created_at":"2026-07-03","updated_at":"2026-07-05","tags":["runtime","os","lifecycle","game","cartridge","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0053","file":"discussion/lessons/DSC-0043-system-os-cartridge-switch-orchestrator/LSN-0053-game-switching-is-lifecycle-replacement-not-loader-work.md","status":"done","created_at":"2026-07-05","updated_at":"2026-07-05"}]}
|
||||||
{"type":"discussion","id":"DSC-0039","status":"abandoned","ticket":"render-pipeline-family-and-future-3d","title":"Render Pipeline Family and Future 3D","created_at":"2026-06-04","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","architecture","pipeline"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-render-pipeline-family-and-future-3d.md","status":"abandoned","created_at":"2026-06-04","updated_at":"2026-06-04","_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}],"decisions":[],"plans":[],"lessons":[],"_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}
|
{"type":"discussion","id":"DSC-0039","status":"abandoned","ticket":"render-pipeline-family-and-future-3d","title":"Render Pipeline Family and Future 3D","created_at":"2026-06-04","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","architecture","pipeline"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-render-pipeline-family-and-future-3d.md","status":"abandoned","created_at":"2026-06-04","updated_at":"2026-06-04","_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}],"decisions":[],"plans":[],"lessons":[],"_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}
|
||||||
@ -44,3 +44,4 @@
|
|||||||
{"type":"discussion","id":"DSC-0033","status":"done","ticket":"system-os-service-ownership-and-module-layout","title":"Agenda - SystemOS Service Ownership and Module Layout","created_at":"2026-05-14","updated_at":"2026-05-15","tags":["runtime","os","services","module-layout","vm","window-manager","logging"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0042","file":"discussion/lessons/DSC-0033-system-os-service-ownership-and-module-layout/LSN-0042-systemos-service-ownership-boundary.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
{"type":"discussion","id":"DSC-0033","status":"done","ticket":"system-os-service-ownership-and-module-layout","title":"Agenda - SystemOS Service Ownership and Module Layout","created_at":"2026-05-14","updated_at":"2026-05-15","tags":["runtime","os","services","module-layout","vm","window-manager","logging"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0042","file":"discussion/lessons/DSC-0033-system-os-service-ownership-and-module-layout/LSN-0042-systemos-service-ownership-boundary.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]}
|
||||||
{"type":"discussion","id":"DSC-0036","status":"done","ticket":"prometeu-hub-ui-direction","title":"Agenda - Prometeu Hub UI Direction","created_at":"2026-05-15","updated_at":"2026-05-22","tags":["hub","ui","shell","system-apps","lifecycle","design-system"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0045","file":"discussion/lessons/DSC-0036-prometeu-hub-ui-direction/LSN-0045-hub-ui-slices-should-prove-os-boundaries.md","status":"done","created_at":"2026-05-22","updated_at":"2026-05-22"}]}
|
{"type":"discussion","id":"DSC-0036","status":"done","ticket":"prometeu-hub-ui-direction","title":"Agenda - Prometeu Hub UI Direction","created_at":"2026-05-15","updated_at":"2026-05-22","tags":["hub","ui","shell","system-apps","lifecycle","design-system"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0045","file":"discussion/lessons/DSC-0036-prometeu-hub-ui-direction/LSN-0045-hub-ui-slices-should-prove-os-boundaries.md","status":"done","created_at":"2026-05-22","updated_at":"2026-05-22"}]}
|
||||||
{"type":"discussion","id":"DSC-0037","status":"done","ticket":"rgba8888-framebuffer-and-pixel-format-direction","title":"Agenda - RGBA8888 Framebuffer and Pixel Format Direction","created_at":"2026-05-22","updated_at":"2026-05-23","tags":["gfx","framebuffer","rgb565","rgba8888","renderer","assets","host","backend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0046","file":"discussion/lessons/DSC-0037-rgba8888-framebuffer-and-pixel-format-direction/LSN-0046-pixel-format-contracts-must-move-as-one-surface.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23"}]}
|
{"type":"discussion","id":"DSC-0037","status":"done","ticket":"rgba8888-framebuffer-and-pixel-format-direction","title":"Agenda - RGBA8888 Framebuffer and Pixel Format Direction","created_at":"2026-05-22","updated_at":"2026-05-23","tags":["gfx","framebuffer","rgb565","rgba8888","renderer","assets","host","backend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0046","file":"discussion/lessons/DSC-0037-rgba8888-framebuffer-and-pixel-format-direction/LSN-0046-pixel-format-contracts-must-move-as-one-surface.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23"}]}
|
||||||
|
{"type":"discussion","id":"DSC-0046","status":"in_progress","ticket":"runtime-owned-variable-glyph-bank-palette-protocol","title":"Runtime-Owned Variable Glyph Bank Palette Protocol","created_at":"2026-07-14","updated_at":"2026-07-14","tags":["runtime","gfx","assets","glyph-bank","palette-serialization","protocol"],"agendas":[{"id":"AGD-0049","file":"AGD-0049-runtime-owned-variable-glyph-bank-palette-protocol.md","status":"accepted","created_at":"2026-07-14","updated_at":"2026-07-14"}],"decisions":[{"id":"DEC-0041","file":"DEC-0041-variable-glyph-bank-palette-protocol.md","status":"accepted","created_at":"2026-07-14","updated_at":"2026-07-14","ref_agenda":"AGD-0049"}],"plans":[{"id":"PLN-0167","file":"PLN-0167-spec-contract-update-for-variable-glyph-palettes.md","status":"open","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0168","file":"PLN-0168-glyphbank-variable-palette-resident-model.md","status":"open","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0169","file":"PLN-0169-asset-decode-validation-for-variable-glyph-palettes.md","status":"open","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0170","file":"PLN-0170-composer-palette-reference-failure-semantics.md","status":"open","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0171","file":"PLN-0171-variable-glyph-palette-tests-fixtures-and-residue-scan.md","status":"open","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]},{"id":"PLN-0172","file":"PLN-0172-runtime-spec-handoff-to-packer-and-studio.md","status":"open","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0041"]}],"lessons":[]}
|
||||||
|
|||||||
@ -0,0 +1,220 @@
|
|||||||
|
---
|
||||||
|
id: AGD-0049
|
||||||
|
ticket: runtime-owned-variable-glyph-bank-palette-protocol
|
||||||
|
title: Runtime-Owned Variable Glyph Bank Palette Protocol
|
||||||
|
status: accepted
|
||||||
|
created: 2026-07-14
|
||||||
|
resolved: 2026-07-14
|
||||||
|
decision:
|
||||||
|
tags:
|
||||||
|
- runtime
|
||||||
|
- gfx
|
||||||
|
- assets
|
||||||
|
- glyph-bank
|
||||||
|
- palette-serialization
|
||||||
|
- protocol
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
A agenda `../studio/discussion/workflow/agendas/AGD-0005-variable-tile-bank-palette-serialization.md`
|
||||||
|
levantou o desperdicio do payload atual de `GLYPH/indexed_v1`: todo glyph bank
|
||||||
|
carrega `64 * 16 * 4 = 4096` bytes de paletas RGBA8888, mesmo quando o asset
|
||||||
|
usa poucas paletas.
|
||||||
|
|
||||||
|
Esse problema toca o `packer`, mas a decisao do protocolo pertence ao
|
||||||
|
`runtime`. A especificacao final deve ser definida aqui, no contrato runtime,
|
||||||
|
e o `packer` deve seguir a spec quando ela estiver pronta. A agenda de `studio`
|
||||||
|
serve como entrada factual e motivacao, nao como autoridade normativa sobre o
|
||||||
|
payload, a memoria residente ou a semantica de `palette_id`.
|
||||||
|
|
||||||
|
Estado atual no runtime:
|
||||||
|
|
||||||
|
- `docs/specs/runtime/15-asset-management.md` documenta `palette_count = 64`;
|
||||||
|
- `docs/specs/runtime/04-gfx-peripheral.md` documenta `palette_id` em `0..63`;
|
||||||
|
- `crates/console/prometeu-hal/src/glyph_bank.rs` materializa paletas como
|
||||||
|
`[[Color; 16]; 64]`;
|
||||||
|
- `crates/console/prometeu-drivers/src/asset.rs` rejeita metadata cujo
|
||||||
|
`palette_count` nao seja `64`;
|
||||||
|
- o decode de glyph bank le um bloco fixo de `64 * 16 * 4` bytes em
|
||||||
|
`assets.pa`;
|
||||||
|
- testes de asset e VM ainda calculam payload e decoded size com o bloco fixo.
|
||||||
|
|
||||||
|
Decisoes anteriores relevantes:
|
||||||
|
|
||||||
|
- `DSC-0022` estabeleceu `GlyphBank` como nome canonico do artefato grafico;
|
||||||
|
- `DSC-0037` estabeleceu RGBA8888 como contrato runtime, com alpha como dado de
|
||||||
|
cor e sem indice magico reservado.
|
||||||
|
|
||||||
|
## Problema
|
||||||
|
|
||||||
|
O runtime precisa decidir se `GLYPH/indexed_v1` continua sendo um contrato de
|
||||||
|
64 paletas fixas ou se passa a aceitar uma quantidade variavel de paletas
|
||||||
|
serializadas.
|
||||||
|
|
||||||
|
Essa decisao nao e apenas uma otimizacao de tamanho de cartucho. Ela muda:
|
||||||
|
|
||||||
|
- o significado de `palette_count`;
|
||||||
|
- a validacao de `palette_id`;
|
||||||
|
- a formula de `size` e `decoded_size`;
|
||||||
|
- a representacao residente de `GlyphBank`;
|
||||||
|
- o comportamento quando uma cena referencia uma paleta nao carregada;
|
||||||
|
- a fronteira entre contrato de asset, HAL, composer, testes e tooling.
|
||||||
|
|
||||||
|
## Pontos Criticos
|
||||||
|
|
||||||
|
- Autoridade: o runtime decide o protocolo publicado; o `packer` segue.
|
||||||
|
- Compatibilidade: o projeto ainda esta em v1, entao nao ha obrigacao
|
||||||
|
presumida de preservar o padding fixo antigo.
|
||||||
|
- Identidade: `palette_id` pode continuar sendo uma identidade direta ou pode
|
||||||
|
virar indice em uma tabela compactada, mas nao pode ter dois significados.
|
||||||
|
- Materializacao: economizar bytes no payload nao implica automaticamente
|
||||||
|
economizar memoria residente, mas manter uma tabela fixa pode preservar
|
||||||
|
semantica simples para renderizacao e cenas.
|
||||||
|
- Falhas: se `palette_id` apontar para uma paleta ausente, o runtime precisa
|
||||||
|
definir se isso falha no load, na composicao, ou se resolve para cor default.
|
||||||
|
- Propagacao: qualquer decisao precisa mover specs, decode, HAL, fixtures e
|
||||||
|
testes juntos, como ocorreu na migracao RGBA8888.
|
||||||
|
|
||||||
|
## Opcoes
|
||||||
|
|
||||||
|
### Opcao A - Manter 64 paletas fixas no protocolo runtime
|
||||||
|
|
||||||
|
- **Abordagem:** Preservar `palette_count = 64`, bloco fixo de 4096 bytes e
|
||||||
|
tabela residente fixa.
|
||||||
|
- **Pro:** Mantem decode, composicao e limites de `palette_id` simples.
|
||||||
|
- **Contra:** O runtime continua publicando um custo obrigatorio de payload que
|
||||||
|
nao representa a maioria dos assets.
|
||||||
|
- **Manutencao:** Boa para estabilidade local, fraca para alinhamento entre
|
||||||
|
metadata autoral e payload real.
|
||||||
|
|
||||||
|
### Opcao B - Payload variavel, memoria residente fixa de 64 slots
|
||||||
|
|
||||||
|
- **Abordagem:** Fazer `palette_count` representar o numero de paletas
|
||||||
|
serializadas, mas expandir para uma tabela residente fixa de 64 paletas no
|
||||||
|
load. Paletas nao serializadas ficam em valor default, e `palette_id` continua
|
||||||
|
sendo identidade direta `0..63`.
|
||||||
|
- **Pro:** Reduz payload mantendo o contrato de composicao e cena simples.
|
||||||
|
- **Contra:** Requer decidir se referencias a paletas nao serializadas sao
|
||||||
|
invalidas no load, invalidas na composicao ou simplesmente resolvem para a
|
||||||
|
paleta default.
|
||||||
|
- **Manutencao:** Boa se a spec declarar que `palette_count` mede somente o
|
||||||
|
prefixo serializado e que o runtime ainda materializa capacidade fixa.
|
||||||
|
|
||||||
|
### Opcao C - Payload variavel e memoria residente variavel
|
||||||
|
|
||||||
|
- **Abordagem:** Fazer `palette_count` controlar tanto o payload quanto a
|
||||||
|
quantidade residente de paletas. `palette_id >= palette_count` passa a ser
|
||||||
|
invalido para aquele glyph bank.
|
||||||
|
- **Pro:** O contrato fica mais fiel ao asset carregado e reduz memoria
|
||||||
|
residente por banco.
|
||||||
|
- **Contra:** A composicao precisa carregar limite por banco e transformar
|
||||||
|
validacao de `palette_id` em regra dependente do asset.
|
||||||
|
- **Manutencao:** Forte se o runtime quiser que o banco carregado seja a unica
|
||||||
|
fonte de verdade; mais invasiva no HAL/composer.
|
||||||
|
|
||||||
|
### Opcao D - Paletas compactadas com remapeamento de identidade
|
||||||
|
|
||||||
|
- **Abordagem:** Serializar somente paletas usadas em uma tabela densa e
|
||||||
|
introduzir um mapa entre identidade autoral/esparsa e indice residente.
|
||||||
|
- **Pro:** Pode minimizar payload mesmo quando indices autorais sao esparsos.
|
||||||
|
- **Contra:** Introduz um segundo contrato de identidade e exige metadata extra
|
||||||
|
ou reescrita de cenas/assets dependentes.
|
||||||
|
- **Manutencao:** Fraca para v1 unless haja uma necessidade clara de preservar
|
||||||
|
indices esparsos sem preencher lacunas.
|
||||||
|
|
||||||
|
## Sugestao / Recomendacao
|
||||||
|
|
||||||
|
Adotar a **Opcao C**.
|
||||||
|
|
||||||
|
`palette_count` deve ser o contrato real do glyph bank carregado: se o payload
|
||||||
|
serializa `N` paletas, o runtime materializa `N` paletas e `palette_id >= N`
|
||||||
|
e invalido para aquele banco.
|
||||||
|
|
||||||
|
A **Opcao B** fica descartada porque manter memoria residente fixa preservaria
|
||||||
|
uma segunda nocao de capacidade que nao corresponde ao asset carregado. A
|
||||||
|
**Opcao D** tambem fica descartada porque introduzir remapeamento de identidade
|
||||||
|
transformaria um protocolo simples em uma camada adicional de metadata.
|
||||||
|
|
||||||
|
## Perguntas em Aberto
|
||||||
|
|
||||||
|
- [x] `palette_count` deve definir tambem a quantidade residente de paletas, ou
|
||||||
|
apenas o prefixo serializado no payload?
|
||||||
|
- Resolucao: define tambem a quantidade residente.
|
||||||
|
- [x] `palette_id` deve ser validado contra `palette_count` por glyph bank ou
|
||||||
|
continuar limitado globalmente a `0..63`?
|
||||||
|
- Resolucao: validar contra `palette_count` por glyph bank, mantendo um
|
||||||
|
limite maximo global separado.
|
||||||
|
- [x] Quando uma cena referencia uma paleta ausente, o erro deve ocorrer no
|
||||||
|
load do glyph bank, no load/decode da scene, ou na composicao?
|
||||||
|
- Resolucao: o glyph bank carrega se o proprio payload e valido. A referencia
|
||||||
|
ausente falha quando uma scene/sprite tenta usar `palette_id >=
|
||||||
|
palette_count` contra o banco real; o runtime deve tratar isso como erro
|
||||||
|
explicito, nao como fallback silencioso para transparente/default.
|
||||||
|
- [x] O limite maximo de paletas por glyph bank continua sendo `64` em v1?
|
||||||
|
- Resolucao: sim. A variabilidade deve reduzir `N`, nao abrir uma
|
||||||
|
quantidade ilimitada de paletas em v1.
|
||||||
|
- [x] `decoded_size` deve contar apenas paletas materializadas ou manter alguma
|
||||||
|
nocao de capacidade residente?
|
||||||
|
- Resolucao: contar apenas paletas materializadas:
|
||||||
|
`width * height + palette_count * 16 * 4`.
|
||||||
|
- [x] A mudanca deve manter o nome `GLYPH/indexed_v1` como correcao
|
||||||
|
incompativel de v1, ou o runtime exige uma nova versao de payload?
|
||||||
|
- Resolucao: manter `GLYPH/indexed_v1` como correcao incompativel, sem
|
||||||
|
compatibilidade com o padding fixo antigo.
|
||||||
|
|
||||||
|
## Criterio para Encerrar
|
||||||
|
|
||||||
|
A agenda pode virar decisao quando o runtime escolher:
|
||||||
|
|
||||||
|
- o significado normativo de `palette_count`;
|
||||||
|
- a relacao entre payload serializado e memoria residente;
|
||||||
|
- a regra de validade de `palette_id`;
|
||||||
|
- o ponto de falha para paletas referenciadas mas ausentes;
|
||||||
|
- a estrategia de versao para `GLYPH/indexed_v1`;
|
||||||
|
- a lista de specs, crates e testes que precisam ser propagados no plano.
|
||||||
|
|
||||||
|
## Discussion
|
||||||
|
|
||||||
|
Entrada do usuario em 2026-07-14: o runtime deve decidir o protocolo com base
|
||||||
|
no que for melhor para o runtime; o `packer` deve seguir a spec quando pronta.
|
||||||
|
|
||||||
|
Entrada do usuario em 2026-07-14: preferencia pela Opcao C, se possivel.
|
||||||
|
|
||||||
|
Analise atual: a Opcao C e viavel, mas transforma `palette_id` em validacao
|
||||||
|
dependente do glyph bank carregado. O codigo atual ja centraliza parte desse
|
||||||
|
risco em `GlyphBank::resolve_color`, que hoje retorna transparente quando a
|
||||||
|
paleta nao existe. Para a Opcao C virar contrato robusto, a decisao nao deve
|
||||||
|
depender de fallback silencioso: precisa escolher um ponto explicito de falha
|
||||||
|
para `palette_id >= palette_count`.
|
||||||
|
|
||||||
|
Entrada do usuario em 2026-07-14: aceitar a recomendacao e seguir com a Opcao
|
||||||
|
C.
|
||||||
|
|
||||||
|
## Resolution
|
||||||
|
|
||||||
|
Fechar a agenda em favor da **Opcao C - Payload variavel e memoria residente
|
||||||
|
variavel**.
|
||||||
|
|
||||||
|
Contrato a levar para decisao:
|
||||||
|
|
||||||
|
- o runtime e a autoridade do protocolo `GLYPH/indexed_v1`;
|
||||||
|
- o `packer` deve seguir a spec runtime quando ela estiver publicada;
|
||||||
|
- `palette_count` significa o numero de paletas RGBA8888 serializadas e
|
||||||
|
materializadas no glyph bank carregado;
|
||||||
|
- `palette_count` deve estar no intervalo `1..=64`;
|
||||||
|
- cada paleta continua tendo 16 cores RGBA8888;
|
||||||
|
- `palette_id` e uma identidade direta dentro do glyph bank carregado, valida
|
||||||
|
somente quando `palette_id < palette_count`;
|
||||||
|
- o runtime nao deve remapear paletas esparsas para outra identidade;
|
||||||
|
- `decoded_size` deve contar apenas as paletas materializadas:
|
||||||
|
`width * height + palette_count * 16 * 4`;
|
||||||
|
- a mudanca permanece em `GLYPH/indexed_v1` como correcao incompativel de v1;
|
||||||
|
- payloads antigos com padding fixo e `palette_count = 64` so continuam
|
||||||
|
validos se tambem satisfizerem o novo contrato por coincidencia, nao por uma
|
||||||
|
regra de compatibilidade separada;
|
||||||
|
- referencias a paletas ausentes devem falhar explicitamente quando
|
||||||
|
scene/sprite/composer tentarem usar `palette_id >= palette_count` contra o
|
||||||
|
banco real;
|
||||||
|
- o plano posterior deve propagar specs, `GlyphBank`, decode de assets,
|
||||||
|
validacao de scene/sprite/composer, fixtures e testes.
|
||||||
@ -0,0 +1,202 @@
|
|||||||
|
---
|
||||||
|
id: DEC-0041
|
||||||
|
ticket: runtime-owned-variable-glyph-bank-palette-protocol
|
||||||
|
title: Variable Glyph Bank Palette Protocol
|
||||||
|
status: accepted
|
||||||
|
created: 2026-07-14
|
||||||
|
accepted: 2026-07-14
|
||||||
|
ref_agenda: AGD-0049
|
||||||
|
tags: [runtime, gfx, assets, glyph-bank, palette-serialization, protocol]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted.
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
`AGD-0049` resolved that the runtime must own the `GLYPH/indexed_v1` palette
|
||||||
|
serialization protocol. `studio` and `packer` may motivate the change, but
|
||||||
|
they do not define the runtime wire contract. Once this decision is accepted,
|
||||||
|
the packer must follow the published runtime spec.
|
||||||
|
|
||||||
|
The current runtime still contains fixed-palette assumptions:
|
||||||
|
|
||||||
|
- `docs/specs/runtime/15-asset-management.md` says `palette_count = 64` and
|
||||||
|
validates `palette_count` as exactly `64`;
|
||||||
|
- `docs/specs/runtime/04-gfx-peripheral.md` documents `palette_id` as a
|
||||||
|
runtime-facing palette index;
|
||||||
|
- `crates/console/prometeu-hal/src/glyph_bank.rs` stores palettes as
|
||||||
|
`[[Color; 16]; 64]`;
|
||||||
|
- `crates/console/prometeu-drivers/src/asset.rs` rejects any glyph metadata
|
||||||
|
whose `palette_count` is not `64`;
|
||||||
|
- glyph decode reads a fixed `64 * 16 * 4` byte palette block;
|
||||||
|
- tests and fixtures calculate glyph payload and decoded size with the fixed
|
||||||
|
palette block.
|
||||||
|
|
||||||
|
Prior decisions remain in force:
|
||||||
|
|
||||||
|
- `DSC-0022` established `GlyphBank` as the canonical artifact name;
|
||||||
|
- `DSC-0037` established RGBA8888 as the runtime color contract, with alpha as
|
||||||
|
color data and no reserved magic palette index.
|
||||||
|
|
||||||
|
## Decisao
|
||||||
|
|
||||||
|
The runtime SHALL adopt variable glyph-bank palette serialization for
|
||||||
|
`GLYPH/indexed_v1`.
|
||||||
|
|
||||||
|
For `BankType::GLYPH` in v1:
|
||||||
|
|
||||||
|
- `palette_count` MUST mean the number of RGBA8888 palettes serialized in the
|
||||||
|
payload and materialized in the resident `GlyphBank`;
|
||||||
|
- `palette_count` MUST be in the inclusive range `1..=64`;
|
||||||
|
- each palette MUST contain exactly `16` RGBA8888 colors in canonical `R, G, B,
|
||||||
|
A` byte order;
|
||||||
|
- the serialized payload MUST contain only `palette_count` palettes, not a
|
||||||
|
fixed 64-palette block;
|
||||||
|
- resident runtime memory MUST materialize exactly `palette_count` palettes for
|
||||||
|
the bank;
|
||||||
|
- `palette_id` MUST be interpreted as a direct palette identity within the
|
||||||
|
loaded glyph bank;
|
||||||
|
- `palette_id` MUST be valid only when `palette_id < palette_count` for the
|
||||||
|
loaded glyph bank being referenced;
|
||||||
|
- the runtime MUST NOT remap sparse authored palette identities into a separate
|
||||||
|
dense identity space;
|
||||||
|
- missing palettes MUST NOT silently resolve to transparent, black, or any
|
||||||
|
other default color in canonical scene/sprite composition;
|
||||||
|
- references to `palette_id >= palette_count` MUST fail explicitly when
|
||||||
|
scene/sprite/composer logic attempts to use that palette against the loaded
|
||||||
|
bank;
|
||||||
|
- the format name remains `GLYPH/indexed_v1`; this is an incompatible v1
|
||||||
|
correction, not a new v2 format.
|
||||||
|
|
||||||
|
The v1 payload size formulas SHALL be:
|
||||||
|
|
||||||
|
```text
|
||||||
|
serialized_pixel_bytes = ceil(width * height / 2)
|
||||||
|
palette_bytes = palette_count * 16 * 4
|
||||||
|
size = serialized_pixel_bytes + palette_bytes
|
||||||
|
decoded_size = (width * height) + palette_bytes
|
||||||
|
```
|
||||||
|
|
||||||
|
`width * height` is the number of logical indexed pixels. Serialized pixels
|
||||||
|
remain packed `u4`; decoded runtime pixels may remain expanded to one `u8`
|
||||||
|
index per pixel.
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
This makes `palette_count` a real runtime contract instead of a decorative
|
||||||
|
metadata field. If a glyph bank carries `N` palettes, runtime storage, payload
|
||||||
|
validation, `decoded_size`, and palette lookup all agree on `N`.
|
||||||
|
|
||||||
|
Keeping a fixed 64-slot resident table while trimming only the payload would
|
||||||
|
preserve two meanings for palette capacity: serialized count and resident
|
||||||
|
capacity. That would keep the ambiguity this decision is intended to remove.
|
||||||
|
|
||||||
|
Adding sparse-to-dense palette remapping is also rejected. It would introduce a
|
||||||
|
second identity layer and force scenes, sprites, packer output, and runtime
|
||||||
|
lookup to coordinate additional metadata. V1 should keep `palette_id` as a
|
||||||
|
direct identity inside the loaded glyph bank.
|
||||||
|
|
||||||
|
Keeping the name `GLYPH/indexed_v1` is acceptable because the project is still
|
||||||
|
in v1 and there is no required compatibility owner for the old fixed-padding
|
||||||
|
payload. The runtime should correct the v1 contract now instead of publishing a
|
||||||
|
second format solely to remove padding.
|
||||||
|
|
||||||
|
## Invariantes / Contrato
|
||||||
|
|
||||||
|
- The runtime is the protocol authority for `GLYPH/indexed_v1`.
|
||||||
|
- The packer is a producer of runtime-conforming payloads, not the source of
|
||||||
|
truth for the protocol.
|
||||||
|
- RGBA8888 remains the only valid glyph palette color encoding.
|
||||||
|
- Palette index `0` remains an ordinary palette index.
|
||||||
|
- Color index `0` remains an ordinary color index inside a palette.
|
||||||
|
- Transparency is represented by the RGBA alpha channel.
|
||||||
|
- `palette_count` is both serialized palette count and resident palette count.
|
||||||
|
- `palette_count` has a maximum of `64` in v1.
|
||||||
|
- `palette_id` validity is bank-dependent: `palette_id < palette_count`.
|
||||||
|
- No compatibility mode for the old fixed 64-palette padding is introduced.
|
||||||
|
- Old payloads with `palette_count = 64` remain valid only if they satisfy the
|
||||||
|
new contract directly, not because of a special legacy branch.
|
||||||
|
|
||||||
|
## Impactos
|
||||||
|
|
||||||
|
### Specs
|
||||||
|
|
||||||
|
- `docs/specs/runtime/15-asset-management.md` must remove the exact
|
||||||
|
`palette_count = 64` requirement and define `palette_count` as `1..=64`.
|
||||||
|
- The same spec must align `size` and `decoded_size` formulas with variable
|
||||||
|
`palette_count`.
|
||||||
|
- `docs/specs/runtime/04-gfx-peripheral.md` must define `palette_id` validity
|
||||||
|
as dependent on the loaded glyph bank's `palette_count`, not as a standalone
|
||||||
|
global `0..63` acceptance rule.
|
||||||
|
- Any public wording that suggests fixed resident `64` palettes per glyph bank
|
||||||
|
must be updated or marked historical.
|
||||||
|
|
||||||
|
### Runtime Code
|
||||||
|
|
||||||
|
- `GlyphBank` must stop exposing a fixed `[[Color; 16]; 64]` resident palette
|
||||||
|
table as the canonical representation.
|
||||||
|
- Glyph decode must accept `palette_count` in `1..=64`.
|
||||||
|
- Glyph decode must read exactly `palette_count * 16 * 4` palette bytes.
|
||||||
|
- Glyph decode must validate `size` and `decoded_size` using the variable
|
||||||
|
formulas.
|
||||||
|
- Palette lookup must expose enough information for scene/sprite/composer logic
|
||||||
|
to fail invalid `palette_id` explicitly instead of silently resolving a
|
||||||
|
default color.
|
||||||
|
|
||||||
|
### Scene, Sprite, and Composer
|
||||||
|
|
||||||
|
- Scene and sprite composition must treat `palette_id >= palette_count` for the
|
||||||
|
referenced glyph bank as an explicit invalid reference.
|
||||||
|
- The implementation plan must choose the concrete status/fault path for this
|
||||||
|
invalid reference using existing runtime error semantics where possible.
|
||||||
|
- Canonical composition must not continue by substituting transparent/default
|
||||||
|
colors for invalid palette references.
|
||||||
|
|
||||||
|
### Firmware / Host / Tooling
|
||||||
|
|
||||||
|
- Firmware/system surfaces that expose asset metadata or debug information must
|
||||||
|
report the variable `palette_count`.
|
||||||
|
- Packer/studio fixtures must emit runtime-conforming `GLYPH/indexed_v1`
|
||||||
|
payloads after the runtime spec is updated.
|
||||||
|
- Tooling must not generate sparse-to-dense remapping metadata for v1 unless a
|
||||||
|
later decision introduces that feature.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
- Tests must cover minimum and maximum valid palette counts: `1` and `64`.
|
||||||
|
- Tests must reject `palette_count = 0` and `palette_count > 64`.
|
||||||
|
- Tests must validate serialized and decoded size formulas for non-64 counts.
|
||||||
|
- Tests must verify palette bytes are read in RGBA order for variable counts.
|
||||||
|
- Tests must cover invalid `palette_id >= palette_count` behavior for scene or
|
||||||
|
sprite composition.
|
||||||
|
- Residue scans must check for fixed `64 * 16 * 4` payload assumptions that are
|
||||||
|
still active contract text or code.
|
||||||
|
|
||||||
|
## Referencias
|
||||||
|
|
||||||
|
- Agenda: `AGD-0049`
|
||||||
|
- Runtime naming precedent: `DSC-0022`
|
||||||
|
- RGBA8888 contract precedent: `DSC-0037`
|
||||||
|
- Spec target: `docs/specs/runtime/15-asset-management.md`
|
||||||
|
- Spec target: `docs/specs/runtime/04-gfx-peripheral.md`
|
||||||
|
- Code target: `crates/console/prometeu-hal/src/glyph_bank.rs`
|
||||||
|
- Code target: `crates/console/prometeu-drivers/src/asset.rs`
|
||||||
|
|
||||||
|
## Propagacao Necessaria
|
||||||
|
|
||||||
|
This decision must be followed by an executable plan before spec or code
|
||||||
|
changes.
|
||||||
|
|
||||||
|
The plan must separate:
|
||||||
|
|
||||||
|
- spec edits;
|
||||||
|
- runtime decode/materialization changes;
|
||||||
|
- scene/sprite/composer invalid-palette handling;
|
||||||
|
- tests and fixtures;
|
||||||
|
- downstream packer/studio alignment after the runtime spec is updated.
|
||||||
|
|
||||||
|
## Revision Log
|
||||||
|
|
||||||
|
- 2026-07-14: Initial decision draft from `AGD-0049`.
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0167
|
||||||
|
ticket: runtime-owned-variable-glyph-bank-palette-protocol
|
||||||
|
title: Spec Contract Update for Variable Glyph Palettes
|
||||||
|
status: open
|
||||||
|
created: 2026-07-14
|
||||||
|
ref_decisions: [DEC-0041]
|
||||||
|
tags: [runtime, gfx, assets, glyph-bank, palette-serialization, protocol, specs]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
`DEC-0041` accepts variable glyph-bank palette serialization for
|
||||||
|
`GLYPH/indexed_v1`. The runtime specs must become the canonical source before
|
||||||
|
code and tooling are changed.
|
||||||
|
|
||||||
|
## Decisions de Origem
|
||||||
|
|
||||||
|
- `DEC-0041` - Variable Glyph Bank Palette Protocol
|
||||||
|
|
||||||
|
## Alvo
|
||||||
|
|
||||||
|
Publish the runtime contract for variable glyph-bank palettes in the canonical
|
||||||
|
runtime specs.
|
||||||
|
|
||||||
|
## Escopo
|
||||||
|
|
||||||
|
- Update `docs/specs/runtime/15-asset-management.md`.
|
||||||
|
- Update `docs/specs/runtime/04-gfx-peripheral.md`.
|
||||||
|
- Remove or reword active spec text that requires exactly 64 serialized or
|
||||||
|
resident palettes per glyph bank.
|
||||||
|
- Define `palette_count` as serialized and resident palette count.
|
||||||
|
- Define `palette_count` as `1..=64`.
|
||||||
|
- Define `palette_id` validity as `palette_id < palette_count` for the loaded
|
||||||
|
glyph bank.
|
||||||
|
- Preserve RGBA8888, alpha-as-data, and ordinary index `0` semantics.
|
||||||
|
|
||||||
|
## Fora de Escopo
|
||||||
|
|
||||||
|
- Runtime code changes.
|
||||||
|
- Packer or studio code changes.
|
||||||
|
- New `GLYPH/indexed_v2` format text.
|
||||||
|
- Sparse-to-dense palette remapping.
|
||||||
|
|
||||||
|
## Plano de Execucao
|
||||||
|
|
||||||
|
### Step 1 - Update asset metadata contract
|
||||||
|
|
||||||
|
**What:** Change the `GLYPH` v1 metadata contract.
|
||||||
|
|
||||||
|
**How:** In `docs/specs/runtime/15-asset-management.md`, replace the exact
|
||||||
|
`palette_count = 64` requirement with `palette_count` in `1..=64`. State that
|
||||||
|
the field is both serialized palette count and resident palette count.
|
||||||
|
|
||||||
|
**Files:** `docs/specs/runtime/15-asset-management.md`
|
||||||
|
|
||||||
|
### Step 2 - Update payload and decoded-size formulas
|
||||||
|
|
||||||
|
**What:** Make payload size formulas variable.
|
||||||
|
|
||||||
|
**How:** Define `palette_bytes = palette_count * 16 * 4`, then define
|
||||||
|
`size = ceil(width * height / 2) + palette_bytes` and
|
||||||
|
`decoded_size = width * height + palette_bytes`.
|
||||||
|
|
||||||
|
**Files:** `docs/specs/runtime/15-asset-management.md`
|
||||||
|
|
||||||
|
### Step 3 - Update GFX palette reference semantics
|
||||||
|
|
||||||
|
**What:** Document bank-dependent `palette_id` validity.
|
||||||
|
|
||||||
|
**How:** In `docs/specs/runtime/04-gfx-peripheral.md`, make scene and sprite
|
||||||
|
composition text state that `palette_id` is valid only when it is lower than
|
||||||
|
the referenced glyph bank's `palette_count`.
|
||||||
|
|
||||||
|
**Files:** `docs/specs/runtime/04-gfx-peripheral.md`
|
||||||
|
|
||||||
|
### Step 4 - Document explicit failure
|
||||||
|
|
||||||
|
**What:** Remove fallback ambiguity for missing palettes.
|
||||||
|
|
||||||
|
**How:** State that canonical composition must not substitute transparent,
|
||||||
|
black, or default colors for `palette_id >= palette_count`.
|
||||||
|
|
||||||
|
**Files:** `docs/specs/runtime/04-gfx-peripheral.md`,
|
||||||
|
`docs/specs/runtime/15-asset-management.md`
|
||||||
|
|
||||||
|
### Step 5 - Run spec residue scan
|
||||||
|
|
||||||
|
**What:** Verify no active spec contradicts `DEC-0041`.
|
||||||
|
|
||||||
|
**How:** Search specs for fixed palette phrases and validate remaining hits are
|
||||||
|
historical or explicitly bounded maximums.
|
||||||
|
|
||||||
|
**Files:** `docs/specs/runtime/*.md`
|
||||||
|
|
||||||
|
## Criterios de Aceite
|
||||||
|
|
||||||
|
- [ ] `15-asset-management.md` defines `palette_count` as `1..=64`.
|
||||||
|
- [ ] `15-asset-management.md` uses variable size formulas.
|
||||||
|
- [ ] `04-gfx-peripheral.md` defines bank-dependent `palette_id` validity.
|
||||||
|
- [ ] Specs do not describe fixed 64 serialized palettes as the active
|
||||||
|
contract.
|
||||||
|
- [ ] No v2 format is introduced.
|
||||||
|
|
||||||
|
## Tests / Validacao
|
||||||
|
|
||||||
|
- Run `rg -n "palette_count|64 \\* 16|4096|palette_id" docs/specs/runtime`.
|
||||||
|
- Run `discussion validate`.
|
||||||
|
|
||||||
|
## Riscos
|
||||||
|
|
||||||
|
- The specs already contain mixed fixed and variable wording; partial edits may
|
||||||
|
preserve contradiction.
|
||||||
|
- `palette_id` failure semantics may overlap with existing scene dependency
|
||||||
|
fatal-failure text and must be worded consistently.
|
||||||
@ -0,0 +1,118 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0168
|
||||||
|
ticket: runtime-owned-variable-glyph-bank-palette-protocol
|
||||||
|
title: GlyphBank Variable Palette Resident Model
|
||||||
|
status: open
|
||||||
|
created: 2026-07-14
|
||||||
|
ref_decisions: [DEC-0041]
|
||||||
|
tags: [runtime, gfx, assets, glyph-bank, hal]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
`DEC-0041` requires resident `GlyphBank` memory to materialize exactly
|
||||||
|
`palette_count` palettes. The current HAL model exposes a fixed
|
||||||
|
`[[Color; 16]; 64]` table and must be changed before decode and composition can
|
||||||
|
enforce bank-dependent palette validity cleanly.
|
||||||
|
|
||||||
|
## Decisions de Origem
|
||||||
|
|
||||||
|
- `DEC-0041` - Variable Glyph Bank Palette Protocol
|
||||||
|
|
||||||
|
## Alvo
|
||||||
|
|
||||||
|
Replace the fixed resident palette table with a variable resident palette model
|
||||||
|
that preserves direct `palette_id` identity.
|
||||||
|
|
||||||
|
## Escopo
|
||||||
|
|
||||||
|
- Update `crates/console/prometeu-hal/src/glyph_bank.rs`.
|
||||||
|
- Keep `GLYPH_BANK_COLORS_PER_PALETTE = 16`.
|
||||||
|
- Replace the fixed palette table with a variable representation.
|
||||||
|
- Expose palette count and palette validation helpers.
|
||||||
|
- Ensure `resolve_color` no longer hides invalid palette references in
|
||||||
|
canonical paths.
|
||||||
|
- Update local HAL tests and call sites that construct `GlyphBank` directly.
|
||||||
|
|
||||||
|
## Fora de Escopo
|
||||||
|
|
||||||
|
- Asset payload decode changes.
|
||||||
|
- Composer status/fault policy.
|
||||||
|
- Packer/studio changes.
|
||||||
|
- Sparse palette remapping.
|
||||||
|
|
||||||
|
## Plano de Execucao
|
||||||
|
|
||||||
|
### Step 1 - Introduce variable palette storage
|
||||||
|
|
||||||
|
**What:** Replace fixed palette storage.
|
||||||
|
|
||||||
|
**How:** Change `GlyphBank::palettes` from
|
||||||
|
`[[Color; GLYPH_BANK_COLORS_PER_PALETTE]; GLYPH_BANK_PALETTE_COUNT_V1]` to a
|
||||||
|
variable collection such as `Vec<[Color; GLYPH_BANK_COLORS_PER_PALETTE]>`.
|
||||||
|
Keep a separate maximum constant for v1 if useful.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-hal/src/glyph_bank.rs`
|
||||||
|
|
||||||
|
### Step 2 - Update constructors
|
||||||
|
|
||||||
|
**What:** Make constructors explicit about palette count.
|
||||||
|
|
||||||
|
**How:** Add or update constructors so tests and loaders can create a bank with
|
||||||
|
a chosen palette count. Default constructors used only for empty test banks
|
||||||
|
must choose a valid count and not imply fixed 64 capacity.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-hal/src/glyph_bank.rs`
|
||||||
|
|
||||||
|
### Step 3 - Add validation helpers
|
||||||
|
|
||||||
|
**What:** Provide canonical palette validity APIs.
|
||||||
|
|
||||||
|
**How:** Add methods such as `palette_count()`, `contains_palette(palette_id)`,
|
||||||
|
and a fallible color lookup that distinguishes invalid palette references from
|
||||||
|
transparent colors.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-hal/src/glyph_bank.rs`
|
||||||
|
|
||||||
|
### Step 4 - Update direct palette mutations in tests
|
||||||
|
|
||||||
|
**What:** Fix tests that write directly into fixed array slots.
|
||||||
|
|
||||||
|
**How:** Replace direct `bank.palettes[id][color] = value` call sites with
|
||||||
|
helpers or ensure the test bank was created with enough palettes first.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/frame_composer.rs`,
|
||||||
|
`crates/console/prometeu-drivers/src/gfx.rs`,
|
||||||
|
`crates/console/prometeu-system/src/services/vm_runtime/tests.rs`
|
||||||
|
|
||||||
|
### Step 5 - Keep direct identity
|
||||||
|
|
||||||
|
**What:** Preserve `palette_id` identity.
|
||||||
|
|
||||||
|
**How:** Do not introduce maps, compaction tables, or translated palette ids.
|
||||||
|
Index `N` in the vector is palette identity `N`.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-hal/src/glyph_bank.rs`
|
||||||
|
|
||||||
|
## Criterios de Aceite
|
||||||
|
|
||||||
|
- [ ] Resident `GlyphBank` stores exactly the loaded palette count.
|
||||||
|
- [ ] `GlyphBank` exposes bank-dependent palette validity.
|
||||||
|
- [ ] Invalid palette lookup can be detected separately from a transparent
|
||||||
|
color.
|
||||||
|
- [ ] No sparse-to-dense remapping structure is added.
|
||||||
|
- [ ] Direct test constructors no longer rely on implicit 64 palette capacity.
|
||||||
|
|
||||||
|
## Tests / Validacao
|
||||||
|
|
||||||
|
- Run HAL and driver unit tests that cover glyph bank construction and color
|
||||||
|
lookup.
|
||||||
|
- Add focused tests for `palette_count = 1` and `palette_count = 64`.
|
||||||
|
- Add a test proving invalid palette lookup is not silently equivalent to
|
||||||
|
transparent color.
|
||||||
|
|
||||||
|
## Riscos
|
||||||
|
|
||||||
|
- Many tests directly mutate `palettes[id]`; the migration can be noisy.
|
||||||
|
- Existing renderer paths may rely on `resolve_color` returning transparent for
|
||||||
|
invalid ids, which conflicts with `DEC-0041`.
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0169
|
||||||
|
ticket: runtime-owned-variable-glyph-bank-palette-protocol
|
||||||
|
title: Asset Decode Validation for Variable Glyph Palettes
|
||||||
|
status: open
|
||||||
|
created: 2026-07-14
|
||||||
|
ref_decisions: [DEC-0041]
|
||||||
|
tags: [runtime, assets, glyph-bank, decode, validation]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
`DEC-0041` changes glyph-bank decode from a fixed 4096-byte palette block to a
|
||||||
|
variable `palette_count * 16 * 4` block. The asset manager is the runtime gate
|
||||||
|
that must reject malformed glyph payloads before residency.
|
||||||
|
|
||||||
|
## Decisions de Origem
|
||||||
|
|
||||||
|
- `DEC-0041` - Variable Glyph Bank Palette Protocol
|
||||||
|
|
||||||
|
## Alvo
|
||||||
|
|
||||||
|
Update glyph asset layout validation and decode to accept `palette_count` in
|
||||||
|
`1..=64` and materialize exactly that many palettes.
|
||||||
|
|
||||||
|
## Escopo
|
||||||
|
|
||||||
|
- Update `crates/console/prometeu-drivers/src/asset.rs`.
|
||||||
|
- Replace exact `palette_count == 64` validation.
|
||||||
|
- Replace fixed `GLYPH_BANK_PALETTE_BYTES_V1` usage in decode.
|
||||||
|
- Validate `size` and `decoded_size` using variable formulas.
|
||||||
|
- Read exactly `palette_count * 16 * 4` bytes.
|
||||||
|
- Preserve RGBA byte order.
|
||||||
|
|
||||||
|
## Fora de Escopo
|
||||||
|
|
||||||
|
- HAL storage changes except as required by `PLN-0168`.
|
||||||
|
- Composer invalid-reference behavior.
|
||||||
|
- Packer output changes.
|
||||||
|
|
||||||
|
## Plano de Execucao
|
||||||
|
|
||||||
|
### Step 1 - Change layout return data
|
||||||
|
|
||||||
|
**What:** Carry palette count through layout validation.
|
||||||
|
|
||||||
|
**How:** Update `decode_glyph_bank_layout` to return `palette_count` and
|
||||||
|
palette byte count along with tile size, dimensions, and serialized pixel byte
|
||||||
|
count.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/asset.rs`
|
||||||
|
|
||||||
|
### Step 2 - Replace exact palette-count validation
|
||||||
|
|
||||||
|
**What:** Accept only the DEC-0041 range.
|
||||||
|
|
||||||
|
**How:** Reject `palette_count = 0` and `palette_count > 64`; accept all values
|
||||||
|
in `1..=64`.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/asset.rs`
|
||||||
|
|
||||||
|
### Step 3 - Use variable size formulas
|
||||||
|
|
||||||
|
**What:** Align entry validation with the spec.
|
||||||
|
|
||||||
|
**How:** Compute `palette_bytes = palette_count * 16 * size_of::<u32>()`,
|
||||||
|
`serialized_size = packed_pixels + palette_bytes`, and
|
||||||
|
`decoded_size = logical_pixels + palette_bytes`.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/asset.rs`
|
||||||
|
|
||||||
|
### Step 4 - Decode variable palette data
|
||||||
|
|
||||||
|
**What:** Read only materialized palettes.
|
||||||
|
|
||||||
|
**How:** In buffer and reader decode paths, slice/read exactly `palette_bytes`.
|
||||||
|
Populate the new variable `GlyphBank` palette representation in order.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/asset.rs`
|
||||||
|
|
||||||
|
### Step 5 - Remove fixed-byte assumptions
|
||||||
|
|
||||||
|
**What:** Retire the fixed payload block from active decode.
|
||||||
|
|
||||||
|
**How:** Replace helper functions and tests that assume
|
||||||
|
`GLYPH_BANK_PALETTE_BYTES_V1` is always in the payload. Keep a maximum constant
|
||||||
|
only if it is named as a maximum, not a payload size.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/asset.rs`
|
||||||
|
|
||||||
|
## Criterios de Aceite
|
||||||
|
|
||||||
|
- [ ] Decode accepts valid `palette_count` values from `1` through `64`.
|
||||||
|
- [ ] Decode rejects `palette_count = 0`.
|
||||||
|
- [ ] Decode rejects `palette_count > 64`.
|
||||||
|
- [ ] `size` and `decoded_size` validation use variable palette bytes.
|
||||||
|
- [ ] Buffer and reader decode paths behave consistently.
|
||||||
|
- [ ] RGBA channel order remains unchanged.
|
||||||
|
|
||||||
|
## Tests / Validacao
|
||||||
|
|
||||||
|
- Add unit tests for `palette_count = 1`, an intermediate count, and `64`.
|
||||||
|
- Add rejection tests for `0`, `65`, short palette data, oversized metadata
|
||||||
|
size, and mismatched `decoded_size`.
|
||||||
|
- Run the crate tests that cover asset manager glyph decode.
|
||||||
|
|
||||||
|
## Riscos
|
||||||
|
|
||||||
|
- Existing tests may use generated glyph payload helpers with fixed 64-palette
|
||||||
|
size.
|
||||||
|
- Reader and buffer paths can drift if only one path receives the variable-size
|
||||||
|
change.
|
||||||
@ -0,0 +1,125 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0170
|
||||||
|
ticket: runtime-owned-variable-glyph-bank-palette-protocol
|
||||||
|
title: Composer Palette Reference Failure Semantics
|
||||||
|
status: open
|
||||||
|
created: 2026-07-14
|
||||||
|
ref_decisions: [DEC-0041]
|
||||||
|
tags: [runtime, gfx, composer, scene, sprite, validation]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
`DEC-0041` requires invalid palette references to fail explicitly when
|
||||||
|
scene/sprite/composer logic uses `palette_id >= palette_count` against a loaded
|
||||||
|
glyph bank. Current color resolution can silently return transparent for
|
||||||
|
missing palettes, which is no longer canonical behavior.
|
||||||
|
|
||||||
|
## Decisions de Origem
|
||||||
|
|
||||||
|
- `DEC-0041` - Variable Glyph Bank Palette Protocol
|
||||||
|
|
||||||
|
## Alvo
|
||||||
|
|
||||||
|
Define and implement explicit runtime failure behavior for invalid palette
|
||||||
|
references in canonical composition paths.
|
||||||
|
|
||||||
|
## Escopo
|
||||||
|
|
||||||
|
- Inspect scene binding, scene composition, sprite emission, and render
|
||||||
|
resolution paths.
|
||||||
|
- Choose existing status/fault behavior where it fits the current ABI.
|
||||||
|
- Prevent canonical composition from substituting transparent/default color for
|
||||||
|
invalid palette references.
|
||||||
|
- Update tests for scene and sprite invalid palette references.
|
||||||
|
|
||||||
|
## Fora de Escopo
|
||||||
|
|
||||||
|
- Adding new public ABI status values unless existing statuses cannot represent
|
||||||
|
the error.
|
||||||
|
- Packer or scene authoring validation.
|
||||||
|
- Sparse palette remapping.
|
||||||
|
|
||||||
|
## Plano de Execucao
|
||||||
|
|
||||||
|
### Step 1 - Map current composition paths
|
||||||
|
|
||||||
|
**What:** Identify where palette ids are consumed.
|
||||||
|
|
||||||
|
**How:** Trace `composer.emit_sprite`, scene binding/composition, frame
|
||||||
|
composer packet creation, and software GFX resolution from `Glyph` to
|
||||||
|
`GlyphBank::resolve_color`.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs`,
|
||||||
|
`crates/console/prometeu-drivers/src/frame_composer.rs`,
|
||||||
|
`crates/console/prometeu-drivers/src/gfx.rs`,
|
||||||
|
`crates/console/prometeu-hal/src/glyph_bank.rs`
|
||||||
|
|
||||||
|
### Step 2 - Select explicit failure behavior
|
||||||
|
|
||||||
|
**What:** Choose the runtime-visible failure route.
|
||||||
|
|
||||||
|
**How:** Use existing semantics where possible: status-returning sprite calls
|
||||||
|
should use an existing invalid status if it accurately describes the failure;
|
||||||
|
scene dependency failures that occur during binding/composition should follow
|
||||||
|
the existing fatal dependency-failure model documented in the GFX spec.
|
||||||
|
|
||||||
|
**Files:** `docs/specs/runtime/04-gfx-peripheral.md`,
|
||||||
|
`crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs`,
|
||||||
|
`crates/console/prometeu-drivers/src/frame_composer.rs`
|
||||||
|
|
||||||
|
### Step 3 - Validate sprite references
|
||||||
|
|
||||||
|
**What:** Prevent invalid sprite palette references.
|
||||||
|
|
||||||
|
**How:** When `emit_sprite` has access to the target glyph bank, reject
|
||||||
|
`palette_id >= palette_count` before the sprite is accepted for canonical
|
||||||
|
composition.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-system/src/services/vm_runtime/dispatch.rs`,
|
||||||
|
`crates/console/prometeu-drivers/src/frame_composer.rs`,
|
||||||
|
`crates/console/prometeu-drivers/src/hardware.rs`
|
||||||
|
|
||||||
|
### Step 4 - Validate scene references
|
||||||
|
|
||||||
|
**What:** Prevent invalid scene palette references.
|
||||||
|
|
||||||
|
**How:** During scene bind or scene composition, validate tile palette ids
|
||||||
|
against each referenced loaded glyph bank. Fail explicitly if a scene layer
|
||||||
|
references a palette not present in its glyph dependency.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/gfx.rs`,
|
||||||
|
`crates/console/prometeu-hal/src/scene_viewport_cache.rs`,
|
||||||
|
`crates/console/prometeu-hal/src/scene_viewport_resolver.rs`
|
||||||
|
|
||||||
|
### Step 5 - Remove silent fallback from canonical paths
|
||||||
|
|
||||||
|
**What:** Stop hiding invalid palette ids as transparent.
|
||||||
|
|
||||||
|
**How:** Use fallible palette lookup in canonical render paths. Transparent is
|
||||||
|
valid only when produced by an actual RGBA palette entry with alpha `0`.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/gfx.rs`,
|
||||||
|
`crates/console/prometeu-hal/src/glyph_bank.rs`
|
||||||
|
|
||||||
|
## Criterios de Aceite
|
||||||
|
|
||||||
|
- [ ] Invalid sprite `palette_id` is rejected before canonical composition.
|
||||||
|
- [ ] Invalid scene tile `palette_id` fails explicitly against the loaded bank.
|
||||||
|
- [ ] Canonical render paths do not use invalid palette lookup as transparent.
|
||||||
|
- [ ] Valid transparent RGBA palette entries still render as transparent.
|
||||||
|
- [ ] The selected status/fault behavior is documented in the spec.
|
||||||
|
|
||||||
|
## Tests / Validacao
|
||||||
|
|
||||||
|
- Add sprite test for `palette_id == palette_count`.
|
||||||
|
- Add scene test for a tile palette id above the referenced bank's count.
|
||||||
|
- Add regression test proving alpha `0` in a valid palette still works.
|
||||||
|
- Run VM runtime and GFX driver tests.
|
||||||
|
|
||||||
|
## Riscos
|
||||||
|
|
||||||
|
- Some paths may not have easy access to the loaded glyph bank when accepting a
|
||||||
|
sprite packet.
|
||||||
|
- Existing ABI statuses may be less precise than a new status, but adding a new
|
||||||
|
status has wider compatibility cost.
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0171
|
||||||
|
ticket: runtime-owned-variable-glyph-bank-palette-protocol
|
||||||
|
title: Variable Glyph Palette Tests Fixtures and Residue Scan
|
||||||
|
status: open
|
||||||
|
created: 2026-07-14
|
||||||
|
ref_decisions: [DEC-0041]
|
||||||
|
tags: [runtime, tests, fixtures, glyph-bank, palette-serialization]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
`DEC-0041` changes a cross-cutting asset contract. Tests and fixtures must be
|
||||||
|
updated as a dedicated pass so fixed 64-palette assumptions do not survive in
|
||||||
|
helpers, generated data, or residue.
|
||||||
|
|
||||||
|
## Decisions de Origem
|
||||||
|
|
||||||
|
- `DEC-0041` - Variable Glyph Bank Palette Protocol
|
||||||
|
|
||||||
|
## Alvo
|
||||||
|
|
||||||
|
Convert runtime tests and fixtures to exercise variable glyph palette counts
|
||||||
|
and prove fixed-padding assumptions are gone from active behavior.
|
||||||
|
|
||||||
|
## Escopo
|
||||||
|
|
||||||
|
- Update test helpers that build glyph payloads.
|
||||||
|
- Add minimum, maximum, and intermediate palette-count tests.
|
||||||
|
- Add invalid palette-count tests.
|
||||||
|
- Add invalid palette-reference tests once `PLN-0170` is implemented.
|
||||||
|
- Run residue scans for fixed palette payload assumptions.
|
||||||
|
|
||||||
|
## Fora de Escopo
|
||||||
|
|
||||||
|
- Production decode implementation.
|
||||||
|
- Production composer implementation.
|
||||||
|
- Packer/studio fixture generation.
|
||||||
|
|
||||||
|
## Plano de Execucao
|
||||||
|
|
||||||
|
### Step 1 - Inventory glyph payload helpers
|
||||||
|
|
||||||
|
**What:** Find all runtime test helpers with fixed glyph palette sizes.
|
||||||
|
|
||||||
|
**How:** Search for `GLYPH_BANK_PALETTE_COUNT_V1`,
|
||||||
|
`GLYPH_BANK_PALETTE_BYTES_V1`, `64 * 16 * 4`, `4096`, and helper names such as
|
||||||
|
`test_glyph_asset_data`.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/asset.rs`,
|
||||||
|
`crates/console/prometeu-system/src/services/vm_runtime/tests.rs`,
|
||||||
|
`crates/console/prometeu-system/src/services/vm_runtime/tests_asset_bank.rs`
|
||||||
|
|
||||||
|
### Step 2 - Create variable payload builders
|
||||||
|
|
||||||
|
**What:** Make tests express palette count deliberately.
|
||||||
|
|
||||||
|
**How:** Replace fixed helpers with helpers that accept `palette_count`, build
|
||||||
|
exactly `palette_count * 16 * 4` palette bytes, and compute matching `size` and
|
||||||
|
`decoded_size`.
|
||||||
|
|
||||||
|
**Files:** Runtime test modules that construct glyph assets.
|
||||||
|
|
||||||
|
### Step 3 - Add decode boundary coverage
|
||||||
|
|
||||||
|
**What:** Prove valid and invalid counts.
|
||||||
|
|
||||||
|
**How:** Add tests for `palette_count = 1`, an intermediate value, `64`, `0`,
|
||||||
|
and `65`.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/asset.rs`
|
||||||
|
|
||||||
|
### Step 4 - Add composition coverage
|
||||||
|
|
||||||
|
**What:** Prove invalid palette references fail.
|
||||||
|
|
||||||
|
**How:** After `PLN-0170`, add scene and sprite tests where
|
||||||
|
`palette_id == palette_count` and confirm explicit failure behavior.
|
||||||
|
|
||||||
|
**Files:** `crates/console/prometeu-drivers/src/gfx.rs`,
|
||||||
|
`crates/console/prometeu-drivers/src/frame_composer.rs`,
|
||||||
|
`crates/console/prometeu-system/src/services/vm_runtime/tests.rs`
|
||||||
|
|
||||||
|
### Step 5 - Run residue scan
|
||||||
|
|
||||||
|
**What:** Catch leftover active fixed-palette assumptions.
|
||||||
|
|
||||||
|
**How:** Scan code, tests, and specs for fixed palette byte formulas. Keep only
|
||||||
|
maximum-bound constants and historical documentation.
|
||||||
|
|
||||||
|
**Files:** `crates/`, `docs/specs/runtime/`, `discussion/`
|
||||||
|
|
||||||
|
## Criterios de Aceite
|
||||||
|
|
||||||
|
- [ ] Tests no longer need a fixed 4096-byte palette payload for every glyph
|
||||||
|
bank.
|
||||||
|
- [ ] Decode tests cover `1`, intermediate counts, `64`, `0`, and `65`.
|
||||||
|
- [ ] Composition tests cover invalid palette references.
|
||||||
|
- [ ] Residue scan finds no active fixed serialized palette block assumption.
|
||||||
|
- [ ] Historical or maximum-bound uses of `64` are clearly named.
|
||||||
|
|
||||||
|
## Tests / Validacao
|
||||||
|
|
||||||
|
- Run targeted crate tests for asset decode, GFX, frame composer, and VM asset
|
||||||
|
bank flows.
|
||||||
|
- Run `rg -n "4096|64 \\* 16|GLYPH_BANK_PALETTE_BYTES_V1|palette_count"`
|
||||||
|
against `crates`, `docs/specs/runtime`, and active discussion artifacts.
|
||||||
|
- Run `discussion validate`.
|
||||||
|
|
||||||
|
## Riscos
|
||||||
|
|
||||||
|
- Residue scans can produce legitimate hits for the v1 maximum of `64`; those
|
||||||
|
must be classified instead of mechanically removed.
|
||||||
|
- Test helper churn can obscure the behavioral assertions if not kept focused.
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
---
|
||||||
|
id: PLN-0172
|
||||||
|
ticket: runtime-owned-variable-glyph-bank-palette-protocol
|
||||||
|
title: Runtime Spec Handoff to Packer and Studio
|
||||||
|
status: open
|
||||||
|
created: 2026-07-14
|
||||||
|
ref_decisions: [DEC-0041]
|
||||||
|
tags: [runtime, packer, studio, handoff, glyph-bank, palette-serialization]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
`DEC-0041` makes runtime the authority for `GLYPH/indexed_v1`. After the
|
||||||
|
runtime spec and implementation are updated, packer and studio must align as
|
||||||
|
downstream producers of runtime-conforming assets.
|
||||||
|
|
||||||
|
## Decisions de Origem
|
||||||
|
|
||||||
|
- `DEC-0041` - Variable Glyph Bank Palette Protocol
|
||||||
|
|
||||||
|
## Alvo
|
||||||
|
|
||||||
|
Prepare a clear runtime-owned handoff for packer/studio without moving protocol
|
||||||
|
authority out of the runtime repository.
|
||||||
|
|
||||||
|
## Escopo
|
||||||
|
|
||||||
|
- Summarize the accepted runtime contract for downstream repositories.
|
||||||
|
- Identify exact spec sections packer/studio must follow.
|
||||||
|
- Identify fixture and payload requirements.
|
||||||
|
- Capture any compatibility note needed for old fixed-padding payloads.
|
||||||
|
- Update runtime discussion artifacts with handoff status when implementation
|
||||||
|
is complete.
|
||||||
|
|
||||||
|
## Fora de Escopo
|
||||||
|
|
||||||
|
- Editing `../studio` or packer code from this plan.
|
||||||
|
- Reopening `AGD-0005` in `../studio`.
|
||||||
|
- Defining a v2 payload.
|
||||||
|
- Adding producer-specific runtime exceptions.
|
||||||
|
|
||||||
|
## Plano de Execucao
|
||||||
|
|
||||||
|
### Step 1 - Wait for runtime spec publication
|
||||||
|
|
||||||
|
**What:** Use runtime specs as handoff source.
|
||||||
|
|
||||||
|
**How:** Do not send or encode downstream requirements until `PLN-0167` has
|
||||||
|
landed. The published runtime spec is the contract.
|
||||||
|
|
||||||
|
**Files:** `docs/specs/runtime/15-asset-management.md`,
|
||||||
|
`docs/specs/runtime/04-gfx-peripheral.md`
|
||||||
|
|
||||||
|
### Step 2 - Write downstream contract summary
|
||||||
|
|
||||||
|
**What:** Produce a concise handoff note.
|
||||||
|
|
||||||
|
**How:** Summarize `palette_count`, payload layout, size formulas,
|
||||||
|
`palette_id` validity, absence of remapping, and incompatibility with the old
|
||||||
|
padding contract.
|
||||||
|
|
||||||
|
**Files:** Runtime discussion plan or follow-up note as appropriate.
|
||||||
|
|
||||||
|
### Step 3 - Identify downstream fixture updates
|
||||||
|
|
||||||
|
**What:** Define what packer/studio fixtures must prove.
|
||||||
|
|
||||||
|
**How:** Require fixtures with `palette_count = 1`, an intermediate count, and
|
||||||
|
`64`, plus rejection or regeneration of fixed-padding assumptions where the
|
||||||
|
metadata does not match the payload.
|
||||||
|
|
||||||
|
**Files:** Handoff note only; actual downstream files are outside this repo.
|
||||||
|
|
||||||
|
### Step 4 - Preserve runtime authority
|
||||||
|
|
||||||
|
**What:** Prevent downstream divergence.
|
||||||
|
|
||||||
|
**How:** State that packer/studio metadata such as authored palette count is
|
||||||
|
informative unless the runtime spec defines it as effective metadata.
|
||||||
|
|
||||||
|
**Files:** Handoff note; runtime spec references.
|
||||||
|
|
||||||
|
### Step 5 - Close loop after downstream acknowledgment
|
||||||
|
|
||||||
|
**What:** Track completion.
|
||||||
|
|
||||||
|
**How:** Once packer/studio work is done elsewhere, update discussion lessons or
|
||||||
|
housekeeping artifacts from the runtime side without adding new normative text
|
||||||
|
to lessons.
|
||||||
|
|
||||||
|
**Files:** `discussion/lessons/` only after implementation is complete.
|
||||||
|
|
||||||
|
## Criterios de Aceite
|
||||||
|
|
||||||
|
- [ ] Runtime specs are updated before downstream handoff.
|
||||||
|
- [ ] Handoff states that runtime owns the protocol.
|
||||||
|
- [ ] Handoff lists exact payload formulas and validity rules.
|
||||||
|
- [ ] Handoff states that no sparse-to-dense remapping exists in v1.
|
||||||
|
- [ ] Handoff states that old fixed-padding payloads are not compatibility
|
||||||
|
inputs unless they satisfy the new contract directly.
|
||||||
|
|
||||||
|
## Tests / Validacao
|
||||||
|
|
||||||
|
- Verify handoff references the final spec sections, not agenda text.
|
||||||
|
- Verify no downstream instruction contradicts `DEC-0041`.
|
||||||
|
- Run `discussion validate`.
|
||||||
|
|
||||||
|
## Riscos
|
||||||
|
|
||||||
|
- Downstream repositories may still treat `metadata.palette_authored` as
|
||||||
|
authoritative; this plan must make runtime-effective metadata explicit.
|
||||||
|
- Creating handoff text too early could freeze pre-implementation details.
|
||||||
Loading…
x
Reference in New Issue
Block a user