dev/runtime-owned-variable-glyph-bank-palette-protocol #37

Merged
bquarkz merged 9 commits from dev/runtime-owned-variable-glyph-bank-palette-protocol into master 2026-07-14 15:25:05 +00:00
10 changed files with 1120 additions and 1 deletions
Showing only changes of commit dc279fe72b - Show all commits

0
discussion/.index.lock Normal file
View File

View 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-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."}
@ -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-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-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":[]}

View File

@ -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.

View File

@ -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`.

View File

@ -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.

View File

@ -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`.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.