203 lines
8.1 KiB
Markdown
203 lines
8.1 KiB
Markdown
---
|
|
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`.
|