implements PLN-0167 variable glyph palette specs

This commit is contained in:
bQUARKz 2026-07-14 15:42:11 +01:00
parent dc279fe72b
commit c89116b6f8
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
4 changed files with 32 additions and 10 deletions

View File

@ -44,4 +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":[]}
{"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":"done","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

@ -2,7 +2,8 @@
id: PLN-0167
ticket: runtime-owned-variable-glyph-bank-palette-protocol
title: Spec Contract Update for Variable Glyph Palettes
status: open
status: done
completed: 2026-07-14
created: 2026-07-14
ref_decisions: [DEC-0041]
tags: [runtime, gfx, assets, glyph-bank, palette-serialization, protocol, specs]

View File

@ -625,7 +625,8 @@ Each tilemap cell contains:
Runtime-facing validity rule for v1:
- `palette_id` values are valid only in the range `0..63`
- `palette_id` values are valid only when `palette_id < palette_count` for the
resolved resident glyph bank
#### Sprite
@ -640,7 +641,8 @@ Each sprite draw contains:
Runtime-facing validity rule for v1:
- `palette_id` values are valid only in the range `0..63`
- `palette_id` values are valid only when `palette_id < palette_count` for the
referenced resident glyph bank
---
@ -649,7 +651,7 @@ Runtime-facing validity rule for v1:
The pipeline works like this:
1. Read indexed pixel from tile (value 0..15)
2. Resolve:
2. Validate and resolve:
- real_color = palette[palette_id][index]
3. Apply:
- flip
@ -667,6 +669,9 @@ else:
draw_or_blend(color)
```
The `palette_id` lookup above is valid only after the runtime has established
that the referenced resident glyph bank contains that palette.
---
### 19.7. Organization of Tile Banks
@ -766,6 +771,7 @@ Rules:
- missing glyph dependencies referenced by a resident scene are not a passive `status:int` case;
- if scene activation discovers that a layer dependency cannot be resolved to a committed glyph asset, the machine MUST fail fatally and emit a clear log;
- if scene composition later discovers that a layer dependency can no longer be resolved, the machine MUST fail fatally and emit a clear log;
- if scene activation or composition discovers that a tile references `palette_id >= palette_count` for its resolved glyph bank, the machine MUST fail explicitly and MUST NOT substitute transparent, black, or default color;
- runtime MUST NOT continue canonical scene composition after such a dependency failure.
### 20.2 `composer.emit_sprite`
@ -774,7 +780,7 @@ Rules:
ABI:
1. `glyph_id: int` — glyph index within the bank
2. `palette_id: int` — palette index
2. `palette_id: int` — palette index within the referenced bank; valid only when `palette_id < palette_count` for that resident glyph bank
3. `x: int` — x coordinate
4. `y: int` — y coordinate
5. `layer: int` — composition layer reference
@ -797,4 +803,5 @@ Operational notes:
- the canonical public sprite contract is frame-emission based;
- no caller-provided sprite index exists in the v1 canonical ABI;
- no `active` flag exists in the v1 canonical ABI;
- `palette_id >= palette_count` for the referenced glyph bank is an explicit invalid palette reference and MUST NOT be rendered through transparent, black, or default color substitution;
- overflow remains non-fatal and must not escalate to trap in v1.

View File

@ -115,7 +115,7 @@ For `BankType::GLYPH`, the v1 runtime-facing contract is:
- `codec = NONE`
- serialized pixels use packed `u4` palette indices
- serialized palettes use `RGBA8888` with canonical RGBA channel order
- `palette_count = 64`
- `palette_count` is the number of serialized and resident palettes and must be in `1..=64`
- runtime materialization may expand pixel indices to one `u8` per pixel
For `GLYPH`, `NONE` means there is no additional generic codec layer beyond the bank contract itself.
@ -136,7 +136,7 @@ Required effective metadata fields for `GLYPH` at the root level:
- `tile_size`: tile edge in pixels; valid values are `8`, `16`, or `32`
- `width`: total sheet width in pixels
- `height`: total sheet height in pixels
- `palette_count`: number of serialized palettes for the bank
- `palette_count`: number of serialized palettes and resident runtime palettes for the bank
Optional informative subtrees:
@ -145,7 +145,7 @@ Optional informative subtrees:
Validation rules for `GLYPH` v1:
- `palette_count` must be `64`
- `palette_count` must be in the inclusive range `1..=64`
- `width * height` defines the number of logical indexed pixels in the decoded sheet
- extra metadata may exist, but the runtime contract must not depend on it to reconstruct the in-memory bank unless that data is defined at the root as an effective field.
@ -158,7 +158,16 @@ The tile-bank payload therefore separates serialized storage form from runtime m
- serialized pixel plane: packed `4bpp`
- decoded pixel plane: expanded `u8` indices, one entry per pixel
- palette table: `64 * 16` colors in RGBA8888 channel order
- palette table: `palette_count * 16` colors in RGBA8888 channel order
For `GLYPH` v1:
```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
```
For `GLYPH` v1:
@ -172,6 +181,11 @@ before they are loaded by the runtime.
Palette indices are ordinary indices. Transparency is represented by the alpha
channel of the resolved RGBA8888 palette entry, not by reserving index `0`.
`palette_id` is valid only when it is lower than the referenced resident glyph
bank's `palette_count`. Canonical runtime composition MUST NOT substitute
transparent, black, or any other default color for `palette_id >=
palette_count`.
### 4.2 `SCENE` asset contract in v1
For `BankType::SCENE`, the v1 runtime-facing contract is: