From ad2ae00f3988b114d890dae120d8f204a948ab06 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Tue, 14 Jul 2026 16:53:20 +0100 Subject: [PATCH] Variable Glyph Bank Palette Serialization --- discussion/index.ndjson | 4 +- ...ime-owned-variable-glyph-palette-counts.md | 126 +++++++++++ ...ariable-tile-bank-palette-serialization.md | 185 ---------------- ...riable-glyph-bank-palette-serialization.md | 208 ------------------ ...variable-glyph-palette-spec-propagation.md | 132 ----------- ...-glyph-palette-metadata-and-count-model.md | 140 ------------ ...te-payload-emission-and-size-accounting.md | 140 ------------ ...projections-for-variable-glyph-palettes.md | 147 ------------- ...tte-tests-fixtures-and-final-validation.md | 167 -------------- 9 files changed, 128 insertions(+), 1121 deletions(-) create mode 100644 discussion/lessons/DSC-0005-variable-glyph-bank-palette-serialization/LSN-0054-runtime-owned-variable-glyph-palette-counts.md delete mode 100644 discussion/workflow/agendas/AGD-0005-variable-tile-bank-palette-serialization.md delete mode 100644 discussion/workflow/decisions/DEC-0038-variable-glyph-bank-palette-serialization.md delete mode 100644 discussion/workflow/plans/PLN-0087-variable-glyph-palette-spec-propagation.md delete mode 100644 discussion/workflow/plans/PLN-0088-variable-glyph-palette-metadata-and-count-model.md delete mode 100644 discussion/workflow/plans/PLN-0089-variable-glyph-palette-payload-emission-and-size-accounting.md delete mode 100644 discussion/workflow/plans/PLN-0090-studio-and-packer-projections-for-variable-glyph-palettes.md delete mode 100644 discussion/workflow/plans/PLN-0091-variable-glyph-palette-tests-fixtures-and-final-validation.md diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 47e97515..18e1fe0b 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,4 +1,4 @@ -{"type":"meta","next_id":{"DSC":39,"AGD":42,"DEC":39,"PLN":92,"LSN":54,"CLSN":1}} +{"type":"meta","next_id":{"DSC":39,"AGD":42,"DEC":39,"PLN":92,"LSN":55,"CLSN":1}} {"type":"discussion","id":"DSC-0038","status":"done","ticket":"studio-packer-rgba8888-asset-pipeline","title":"Studio and Packer RGBA8888 Asset Pipeline Alignment","created_at":"2026-05-23","updated_at":"2026-07-14","tags":["studio","packer","assets","glyph-bank","palette","rgba8888","runtime-alignment"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0053","file":"discussion/lessons/DSC-0038-studio-packer-rgba8888-asset-pipeline/LSN-0053-rgba8888-is-the-canonical-studio-packer-palette-contract.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14"}]} {"type":"discussion","id":"DSC-0037","status":"done","ticket":"pbs-autocomplete-parameter-names","title":"PBS autocomplete parameter names for stdlib and method calls","created_at":"2026-05-08","updated_at":"2026-05-14","tags":["compiler-pbs","studio","lsp","autocomplete","signature-help","stdlib"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0052","file":"discussion/lessons/DSC-0037-pbs-autocomplete-parameter-names/LSN-0052-canonical-callable-parameter-names-through-pbs-editor-assistance.md","status":"done","created_at":"2026-05-14","updated_at":"2026-05-14"}]} {"type":"discussion","id":"DSC-0036","status":"open","ticket":"pbs-symbol-documentation-and-hover-markdown","title":"Modelo de documentacao de simbolos em PBS e consumo markdown no hover","created_at":"2026-05-08","updated_at":"2026-05-08","tags":["compiler","compiler-pbs","studio","lsp","vscode","editor","hover","documentation","markdown"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-pbs-symbol-documentation-and-hover-markdown.md","status":"open","created_at":"2026-05-08","updated_at":"2026-05-08"}],"decisions":[],"plans":[],"lessons":[]} @@ -18,7 +18,7 @@ {"type":"discussion","id":"DSC-0002","status":"done","ticket":"palette-management-in-studio","title":"Palette Management in Studio","created_at":"2026-03-26","updated_at":"2026-04-23","tags":["studio","legacy-import","palette-management","tile-bank","packer-boundary"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0042","file":"discussion/lessons/DSC-0002-palette-management-in-studio/LSN-0042-schema-driven-palette-authoring-and-local-metadata-events.md","status":"done","created_at":"2026-04-23","updated_at":"2026-04-23"}]} {"type":"discussion","id":"DSC-0003","status":"done","ticket":"packer-docs-import","title":"Import docs/packer into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0009","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0009-mental-model-packer-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0010","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0010-asset-identity-and-runtime-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0011","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0011-foundations-workspace-runtime-and-build-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0012","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0012-runtime-ownership-and-studio-boundary-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0013","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0013-metadata-convergence-and-runtime-sink-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0014","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0014-pack-wizard-summary-validation-and-pack-execution-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0015","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0015-tile-bank-packing-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0017","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0017-packer-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]} {"type":"discussion","id":"DSC-0004","status":"abandoned","ticket":"tilemap-and-metatile-runtime-binary-layout","title":"Tilemap and Metatile Runtime Binary Layout","created_at":"2026-03-26","updated_at":"2026-04-24","tags":["packer","legacy-import","tilemap","metatile","runtime-layout"],"agendas":[{"id":"AGD-0004","file":"AGD-0004-tilemap-and-metatile-runtime-binary-layout.md","status":"abandoned","created_at":"2026-03-26","updated_at":"2026-04-24","_override_reason":"Explicit user request on 2026-04-24 to abandon AGD-0004 because the agenda is no longer valid."}],"decisions":[],"plans":[],"lessons":[]} -{"type":"discussion","id":"DSC-0005","status":"open","ticket":"variable-tile-bank-palette-serialization","title":"Variable Glyph Bank Palette Serialization","created_at":"2026-03-26","updated_at":"2026-07-14","tags":["packer","legacy-import","glyph-bank","palette-serialization","rgba8888","runtime-alignment"],"agendas":[{"id":"AGD-0005","file":"AGD-0005-variable-tile-bank-palette-serialization.md","status":"accepted","created_at":"2026-03-26","updated_at":"2026-07-14"}],"decisions":[{"id":"DEC-0038","file":"DEC-0038-variable-glyph-bank-palette-serialization.md","status":"accepted","created_at":"2026-07-14","updated_at":"2026-07-14","ref_agenda":"AGD-0005"}],"plans":[{"id":"PLN-0087","file":"PLN-0087-variable-glyph-palette-spec-propagation.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]},{"id":"PLN-0088","file":"PLN-0088-variable-glyph-palette-metadata-and-count-model.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]},{"id":"PLN-0089","file":"PLN-0089-variable-glyph-palette-payload-emission-and-size-accounting.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]},{"id":"PLN-0090","file":"PLN-0090-studio-and-packer-projections-for-variable-glyph-palettes.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]},{"id":"PLN-0091","file":"PLN-0091-variable-glyph-palette-tests-fixtures-and-final-validation.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0005","status":"done","ticket":"variable-tile-bank-palette-serialization","title":"Variable Glyph Bank Palette Serialization","created_at":"2026-03-26","updated_at":"2026-07-14","tags":["packer","legacy-import","glyph-bank","palette-serialization","rgba8888","runtime-alignment"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0054","file":"discussion/lessons/DSC-0005-variable-glyph-bank-palette-serialization/LSN-0054-runtime-owned-variable-glyph-palette-counts.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14"}]} {"type":"discussion","id":"DSC-0006","status":"done","ticket":"pbs-game-facing-asset-refs-and-call-result-discard","title":"PBS Game-Facing Asset References and Ignored Call Result Lowering","created_at":"2026-03-27","updated_at":"2026-03-30","tags":["compiler","pbs","ergonomics","lowering","runtime","asset-identity","expression-statements"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0024","file":"discussion/lessons/DSC-0006-pbs-game-facing-asset-refs-and-call-result-discard/LSN-0024-addressable-surface-host-metadata-and-ignored-value-discipline.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30"}]} {"type":"discussion","id":"DSC-0007","status":"done","ticket":"pbs-learn-to-discussion-lessons-migration","title":"Migrate PBS Learn Documents into Discussion Lessons","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["compiler","pbs","migration","discussion-framework","lessons","learn-prune"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0018","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0018-pbs-ast-and-parser-contract-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0019","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0019-pbs-name-resolution-and-linking-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0020","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0020-pbs-runtime-values-identity-memory-boundaries-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0021","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0021-pbs-diagnostics-and-conformance-governance-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0022","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0022-pbs-globals-lifecycle-and-published-entrypoint-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]} {"type":"discussion","id":"DSC-0008","status":"done","ticket":"pbs-low-level-asset-manager-surface","title":"PBS Low-Level Asset Manager Surface for Runtime AssetManager","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["compiler","pbs","runtime","asset-manager","host-abi","stdlib","asset"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0023","file":"discussion/lessons/DSC-0008-pbs-low-level-asset-manager-surface/LSN-0023-lowassets-runtime-aligned-sdk-surface.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]} diff --git a/discussion/lessons/DSC-0005-variable-glyph-bank-palette-serialization/LSN-0054-runtime-owned-variable-glyph-palette-counts.md b/discussion/lessons/DSC-0005-variable-glyph-bank-palette-serialization/LSN-0054-runtime-owned-variable-glyph-palette-counts.md new file mode 100644 index 00000000..a8b0e406 --- /dev/null +++ b/discussion/lessons/DSC-0005-variable-glyph-bank-palette-serialization/LSN-0054-runtime-owned-variable-glyph-palette-counts.md @@ -0,0 +1,126 @@ +--- +id: LSN-0054 +ticket: variable-tile-bank-palette-serialization +title: Runtime-Owned Variable Glyph Palette Counts +created: 2026-07-14 +tags: + - packer + - studio + - glyph-bank + - palette-serialization + - rgba8888 + - runtime-alignment +--- + +# Runtime-Owned Variable Glyph Palette Counts + +### Original Problem + +The first RGBA8888 alignment wave made Studio and packer emit palette colors in +the runtime channel order, but it deliberately kept the old fixed glyph-bank +palette payload shape. Every `GLYPH/indexed_v1` payload still reserved room for +64 palettes, so the emitted palette block was always `64 * 16 * 4 = 4096` +bytes even when the bank used one or a few palettes. + +That fixed shape left two problems: + +- packer output was larger than the runtime needed; +- `palette_count` could not be trusted as the effective runtime resident count, + because the payload still looked like a 64-palette bank. + +Runtime later accepted the variable-palette protocol for +`GLYPH/indexed_v1`. Studio and packer had to follow that runtime-owned wire +contract instead of keeping a stale producer-side convention. + +### Consolidated Decision + +Runtime owns the `GLYPH/indexed_v1` protocol. Studio and packer are downstream +producers of runtime-conforming `assets.pa` payloads. + +The accepted rule is: + +1. `palette_count` is the effective serialized and resident palette count. +2. `palette_count` must be in the inclusive range `1..=64`. +3. Palette bytes are exactly `palette_count * 16 * 4`. +4. `size = ceil(width * height / 2) + palette_count * 16 * 4`. +5. `decoded_size = width * height + palette_count * 16 * 4`. +6. Palette bytes remain RGBA8888 in `R`, `G`, `B`, `A` order. +7. `GLYPH/indexed_v1` remains the format name. This change does not introduce + `GLYPH/indexed_v2`. +8. There is no compatibility mode for the old fixed 64-palette padding. +9. Palette IDs remain direct. There is no sparse-to-dense remapping metadata in + v1. +10. `palette_authored`, when present, is informative tooling metadata only. + +### Implementation Result + +The packer specs now define `palette_count` as runtime-effective metadata for +glyph banks and describe the variable palette payload in the build-artifact +contract. Studio-facing asset workspace docs now keep `palette_count` distinct +from any authored or tooling-only palette count. + +The packer metadata model derives and validates effective palette count instead +of hard-coding `64`. Sparse direct palette IDs are preserved by materializing +intermediate palette slots up to the highest referenced ID; those slots are not +a remapping table. + +Payload emission now writes exactly the effective number of palette slots. Size +and decoded-size accounting use the same formula as the runtime contract, so +metadata, asset-table entries, and payload lengths agree. + +Tests and fixtures cover `palette_count = 1`, intermediate counts, `64`, sparse +direct identity, invalid counts above `64`, RGBA8888 byte order, and payload +size accounting. Final validation passed with: + +- `discussion validate`; +- `./gradlew :prometeu-packer:prometeu-packer-v1:test`; +- `./gradlew build`. + +### Practical Examples + +A 256 by 256 glyph bank with one palette has: + +```text +pixel bytes = ceil(256 * 256 / 2) = 32768 +palette bytes = 1 * 16 * 4 = 64 +size = 32768 + 64 = 32832 +decoded_size = 256 * 256 + 64 = 65600 +``` + +A bank that references palette ID `6` has an effective `palette_count` of at +least `7`. Palette slots `0` through `6` exist in the serialized palette block. +If some lower slots were not authored directly, they are deterministic +placeholders; palette `6` is not remapped to palette `0`. + +### Common Pitfalls and Anti-patterns + +- Do not infer runtime payload length from the maximum allowed palette count. + `64` is the upper bound, not the default emitted count. +- Do not use `palette_authored` as a runtime-effective field. It may describe a + tool view, but runtime loads `palette_count`. +- Do not preserve fixed 4096-byte palette padding for banks with fewer than 64 + effective palettes. +- Do not create `GLYPH/indexed_v2` to carry this change. The accepted runtime + protocol keeps the v1 format name. +- Do not introduce sparse-to-dense palette remapping metadata. Existing scene, + sprite, packer, and runtime references use direct palette identity. +- Do not combine RGBA8888 channel-order work with palette-count semantics. + RGBA8888 defines each color value; `palette_count` defines how many palettes + are serialized and resident. + +### References + +- Runtime decision: + `../runtime/discussion/workflow/decisions/DEC-0041-variable-glyph-bank-palette-protocol.md`. +- Studio/packer decision: + `discussion/workflow/decisions/DEC-0038-variable-glyph-bank-palette-serialization.md`. +- `PLN-0087`: Variable glyph palette spec propagation. +- `PLN-0088`: Variable glyph palette metadata and count model. +- `PLN-0089`: Variable glyph palette payload emission and size accounting. +- `PLN-0090`: Studio and packer projections for variable glyph palettes. +- `PLN-0091`: Variable glyph palette tests, fixtures, and final validation. +- Prior lesson: + `discussion/lessons/DSC-0038-studio-packer-rgba8888-asset-pipeline/LSN-0053-rgba8888-is-the-canonical-studio-packer-palette-contract.md`. +- `docs/specs/packer/3. Asset Declaration and Virtual Asset Contract Specification.md`. +- `docs/specs/packer/4. Build Artifacts and Deterministic Packing Specification.md`. +- `docs/specs/studio/4. Assets Workspace Specification.md`. diff --git a/discussion/workflow/agendas/AGD-0005-variable-tile-bank-palette-serialization.md b/discussion/workflow/agendas/AGD-0005-variable-tile-bank-palette-serialization.md deleted file mode 100644 index a41c2ed6..00000000 --- a/discussion/workflow/agendas/AGD-0005-variable-tile-bank-palette-serialization.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -id: AGD-0005 -ticket: variable-tile-bank-palette-serialization -title: Variable Glyph Bank Palette Serialization -status: accepted -created: 2026-03-26 -resolved: 2026-07-14 -decision: DEC-0038 -tags: - - packer - - legacy-import - - glyph-bank - - palette-serialization - - rgba8888 - - runtime-alignment ---- - -## Pain - -Domain owner: `packer`, with runtime-facing impact through `assets.pa`. - -The current `GLYPH/indexed_v1` glyph-bank contract serializes a fixed block of -`64` palettes even when an asset authors far fewer palettes. - -After `DSC-0038`, each palette entry is RGBA8888, so the fixed palette block is -now `64 * 16 * 4 = 4096` bytes. That keeps decoding simple, but it wastes -cartridge space and leaves a deliberate mismatch between authored palette count -and serialized palette count. - -## Context - -Legacy source: `docs/packer/agendas/Variable Tile Bank Palette Serialization Agenda.md` - -Cross-domain dependency: - -- runtime - -Runtime follow-up: - -- `../runtime/discussion/workflow/decisions/DEC-0041-variable-glyph-bank-palette-protocol.md` - is accepted and normative for the runtime side. -- Runtime `DSC-0046` keeps `GLYPH/indexed_v1`, adopts variable glyph-bank - palette serialization, and treats this as an incompatible v1 correction. -- Runtime plans `PLN-0167` through `PLN-0172` are done and publish the - downstream handoff. - -Current runtime-owned `GLYPH/indexed_v1` contract: - -- pixels are serialized as packed `u4`; -- palettes are serialized as RGBA8888 values in runtime `R`, `G`, `B`, `A` - byte order; -- `palette_count` is the number of serialized and resident palettes; -- `palette_count` must be in `1..=64`; -- payload size includes exactly `palette_count * 16 * 4` palette bytes; -- palette index `0` is ordinary; -- each palette has 16 usable colors; -- transparency is represented by alpha, not by a reserved index or magenta - color-key; -- resident runtime memory materializes exactly `palette_count` palettes; -- `palette_id` is a direct palette identity inside the loaded glyph bank and is - valid only when `palette_id < palette_count`; -- sparse-to-dense palette remapping is not part of v1; -- missing palettes must fail explicitly in scene/sprite/composer use, not - silently resolve to a default color. - -Downstream producers must emit: - -- root effective metadata fields `tile_size`, `width`, `height`, and - `palette_count`; -- `size = ceil(width * height / 2) + palette_count * 16 * 4`; -- `decoded_size = width * height + palette_count * 16 * 4`; -- exactly `palette_count * 16 * 4` RGBA8888 palette bytes; -- no `GLYPH/indexed_v2` payload for this change; -- no fixed 64-palette padding unless `palette_count = 64` and the payload - directly satisfies the runtime v1 contract; -- no effective runtime behavior based on `palette_authored`. - -`DSC-0038` intentionally did not solve variable palette-count serialization. -It changed the color encoding from RGB565-era semantics to RGBA8888 and kept -the fixed 64-palette model stable for that wave. - -Runtime `DEC-0041` now closes the cross-domain protocol questions that this -agenda previously carried as open. The remaining Studio/packer work is -downstream alignment with the runtime-owned contract. - -## Open Questions - -- [x] Should variable palette serialization arrive as a new payload version or - as an incompatible change to the current one? - - Runtime `DEC-0041` resolves this as an incompatible correction to - `GLYPH/indexed_v1`, with no v2 format. -- [x] If `palette_count` becomes variable, should runtime still materialize a - 64-slot resident bank, or truly shrink in-memory representation too? - - Runtime `DEC-0041` resolves this: resident runtime memory materializes - exactly `palette_count` palettes. -- [x] Should sparse authored palette indices remain sparse in serialization, or - be canonicalized into a dense runtime block? - - Runtime `DEC-0041` rejects sparse-to-dense remapping. `palette_id` remains - direct identity inside the loaded glyph bank. -- [x] Should this repository create the owner agenda/decision for the runtime - side, or should a matching runtime `discussion/` artifact be opened before - implementation planning? - - Runtime `DSC-0046` now owns the protocol through accepted `DEC-0041`. - Studio/packer must follow that handoff. -- [x] Which domain owns compatibility for existing cartridges: `packer`, - `runtime`, or `shipper`? - - Runtime `DEC-0041` introduces no compatibility mode. Old payloads with - `palette_count = 64` remain valid only when they satisfy the new contract - directly. - -## Options - -### Option A - Keep fixed 64-palette serialization in v1 -- **Approach:** Preserve the current fixed v1 payload with zero-filled unused palette slots. -- **Pro:** No runtime change and current specs/tests remain stable. -- **Con:** Every glyph bank keeps paying the full 4096-byte palette cost. -- **Maintainability:** Medium. - -### Option B - Align packer output with runtime variable palette serialization -- **Approach:** Keep the `GLYPH/indexed_v1` format name, serialize only - `palette_count` palettes, and make packer metadata, payload sizes, fixtures, - and Studio projections follow runtime `DEC-0041`. -- **Pro:** Removes fixed padding while the project is still in v1, keeps the - public format vocabulary stable, and makes runtime metadata match the payload. -- **Con:** Requires coordinated packer/spec/test changes and fixture - regeneration because the current producer still emits the old fixed-padding - shape. -- **Maintainability:** Strong if implemented as an explicit contract update, - weak if done as an incidental size tweak. Runtime has already closed the - protocol questions. - -### Option C - Keep fixed external metadata but trim trailing palettes -- **Approach:** Keep some 64-slot assumptions in metadata or runtime memory, but - serialize only a shortened trailing subset of palettes in the payload. -- **Pro:** Can reduce cartridge size while limiting some runtime changes. -- **Con:** Creates a split-brain contract where serialized count, logical count, - and resident count can disagree. -- **Maintainability:** Weak. It preserves the ambiguity this agenda is trying - to remove. - -## Discussion - -The retained concern is still valid after `DSC-0038`, but runtime `DEC-0041` -has now closed the protocol. The problem is no longer an open cross-domain -design question; it is a downstream producer-alignment task for Studio/packer. - -The old recommendation favored a versioned follow-up because compatibility and -runtime stability were treated as constraints. Runtime `DEC-0041` removes that -constraint: the project is still in v1, keeps `GLYPH/indexed_v1`, and does not -need compatibility for the old fixed 64-palette payload. - -That makes Option B the required direction for this repository. Runtime already -changed the contract directly; Studio/packer must now emit the runtime-owned -shape and stop treating `palette_authored` or the old 64-padding model as -effective runtime behavior. - -Option C should be avoided because it preserves multiple meanings for palette -count. If the payload becomes variable, `palette_count` should mean the number -of serialized palettes, not an unrelated fixed resident capacity. - -## Resolution - -Recommended direction: adopt **Option B**. - -Updated recommendation: - -1. keep the format name `GLYPH/indexed_v1`; -2. follow runtime `DEC-0041` as the protocol authority; -3. remove the fixed 64-palette payload block from packer output; -4. make packer `palette_count` describe the serialized and resident RGBA8888 - palette count; -5. emit exactly `palette_count * 16 * 4` palette bytes; -6. update `size` and `decoded_size` formulas to use variable `palette_count`; -7. do not create a v2 format solely for this change; -8. do not preserve compatibility with the old fixed-padding payload; -9. do not introduce sparse-to-dense palette remapping metadata; -10. treat `palette_authored` as informative only unless a later runtime - decision promotes it to effective metadata; -11. add downstream fixture coverage for `palette_count = 1`, an intermediate - count, and `palette_count = 64`; -12. add a negative producer validation case for metadata/payload mismatch. - -Next step suggestion: convert this agenda into a Studio/packer decision that -references runtime `DEC-0041` and scopes implementation to specs, packer -payload emission, Studio projections if needed, tests, and fixtures. diff --git a/discussion/workflow/decisions/DEC-0038-variable-glyph-bank-palette-serialization.md b/discussion/workflow/decisions/DEC-0038-variable-glyph-bank-palette-serialization.md deleted file mode 100644 index e8998c37..00000000 --- a/discussion/workflow/decisions/DEC-0038-variable-glyph-bank-palette-serialization.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -id: DEC-0038 -ticket: variable-tile-bank-palette-serialization -title: Variable Glyph Bank Palette Serialization for Studio and Packer -status: accepted -created: 2026-07-14 -accepted: 2026-07-14 -ref_agenda: AGD-0005 -plans: - - PLN-0087 - - PLN-0088 - - PLN-0089 - - PLN-0090 - - PLN-0091 -tags: - - packer - - studio - - glyph-bank - - palette-serialization - - rgba8888 - - runtime-alignment ---- - -## Status - -Accepted. Drafted from accepted agenda `AGD-0005` and accepted on -2026-07-14. - -## Context - -This decision belongs to the `packer` domain, with Studio-facing projection and -fixture impact. Runtime protocol ownership remains in `../runtime`. - -Studio/packer already aligned glyph-bank colors with RGBA8888 through -`DSC-0038`. That work kept the `GLYPH/indexed_v1` format name and changed the -palette color encoding from RGB565-era data to RGBA8888 in runtime channel -order. It deliberately preserved the fixed 64-palette payload model for that -wave. - -Runtime `DEC-0041` now changes the authoritative `GLYPH/indexed_v1` contract: - -- `palette_count` is the number of serialized and resident palettes; -- `palette_count` MUST be in `1..=64`; -- payloads contain exactly `palette_count * 16 * 4` RGBA8888 palette bytes; -- `size = ceil(width * height / 2) + palette_count * 16 * 4`; -- `decoded_size = width * height + palette_count * 16 * 4`; -- resident runtime memory materializes exactly `palette_count` palettes; -- `palette_id` is direct identity within the loaded glyph bank and is valid - only when `palette_id < palette_count`; -- v1 has no sparse-to-dense palette remapping metadata; -- this remains `GLYPH/indexed_v1`, not a new v2 payload. - -Studio/packer must now follow that runtime-owned contract as downstream -producers of runtime-conforming `assets.pa` payloads. - -## Decision - -Studio and packer SHALL adopt variable glyph-bank palette serialization for -`GLYPH/indexed_v1`, following runtime `DEC-0041` as the protocol authority. - -Packer MUST stop emitting a fixed 64-palette block for glyph banks unless the -effective `palette_count` is actually `64`. - -Packer MUST emit exactly `palette_count * 16 * 4` palette bytes for each -`GLYPH/indexed_v1` glyph-bank payload. - -Packer MUST compute glyph-bank `size` as: - -```text -size = ceil(width * height / 2) + palette_count * 16 * 4 -``` - -Packer MUST compute glyph-bank `decoded_size` as: - -```text -decoded_size = width * height + palette_count * 16 * 4 -``` - -Packer MUST publish root effective metadata fields required by runtime: - -- `tile_size` -- `width` -- `height` -- `palette_count` - -For `GLYPH/indexed_v1`, `palette_count` MUST describe the number of serialized -RGBA8888 palettes and the number of resident palettes expected by runtime. -`palette_count` MUST be in the inclusive range `1..=64`. - -Packer and Studio MUST NOT introduce `GLYPH/indexed_v2` for this change. - -Packer and Studio MUST NOT preserve compatibility with the old fixed-padding -payload shape as a special mode. - -Packer and Studio MUST NOT introduce sparse-to-dense palette remapping metadata -for v1. - -`palette_authored`, when present in tooling or pipeline metadata, is -informative only. It MUST NOT be treated as effective runtime metadata unless a -later runtime decision promotes it. - -Palette bytes SHALL remain RGBA8888 in runtime `R`, `G`, `B`, `A` byte order. -Palette index `0` and color index `0` remain ordinary indices. Transparency -remains represented by the alpha channel of the resolved RGBA8888 color. - -## Rationale - -Runtime owns the `GLYPH/indexed_v1` wire contract. Once runtime `DEC-0041` -accepted variable palette serialization, keeping packer output fixed at 64 -palettes would make Studio/packer produce stale runtime payloads. - -Making `palette_count` the effective serialized and resident count removes the -old mismatch between authored palette count and payload shape. The packer no -longer needs to pad every glyph bank to 4096 palette bytes unless the bank -really uses all 64 palettes. - -Keeping the existing format name is correct because the project is still in v1 -and runtime explicitly accepted this as an incompatible v1 correction. A v2 -name would add migration surface without protecting any required compatibility -contract. - -Rejecting sparse-to-dense remapping keeps `palette_id` direct. Scene, sprite, -packer output, and runtime lookup all refer to the same palette identity inside -the loaded glyph bank. - -## Implications - -### Specs - -Packer specs MUST be updated so `GLYPH/indexed_v1` no longer describes a fixed -`64 * 16 * 4 = 4096` palette block as the normal payload shape. - -Packer specs MUST define `palette_count` as the effective serialized palette -count for glyph banks, constrained to `1..=64`. - -Studio specs MUST be updated only where Studio-facing projections, asset -details, pack wizard behavior, or fixtures expose the old fixed-padding model. - -### Code - -Packer payload emission MUST write only `palette_count` palettes. - -Packer payload validation/materialization helpers MUST compute size and decoded -size from variable `palette_count`. - -Packer metadata projection and Studio-facing read/detail APIs MUST expose the -runtime-effective `palette_count` correctly. - -Studio code MUST NOT treat `palette_authored` as the runtime-effective count. - -### Tests and Fixtures - -Tests MUST cover: - -- `palette_count = 1`; -- an intermediate `palette_count`; -- `palette_count = 64`; -- size and decoded-size formulas for variable counts; -- emitted RGBA8888 palette byte count; -- metadata/payload mismatch rejection or producer validation. - -Fixtures that encode the old fixed-padding assumption MUST be regenerated or -updated unless they intentionally use `palette_count = 64` and satisfy the new -runtime contract directly. - -### Non-goals - -This decision does not change RGBA8888 channel order. - -This decision does not change the packed `u4` indexed pixel plane. - -This decision does not change scene `palette_id` payload shape. - -This decision does not introduce v2, compatibility branches, or palette -identity remapping. - -## Propagation Targets - -- Specs: - - `docs/specs/packer/3. Asset Declaration and Virtual Asset Contract Specification.md` - - `docs/specs/packer/4. Build Artifacts and Deterministic Packing Specification.md` - - `docs/specs/studio/4. Assets Workspace Specification.md`, if Studio-facing - palette count projection is documented there. -- Code: - - packer glyph-bank payload emission; - - packer asset walking/materialization; - - packer read/detail projections; - - Studio asset details or pack wizard surfaces if they expose palette counts. -- Tests: - - packer parser, walker, materializer, workspace service, and fixture tests; - - Studio tests if Studio projections or UI logic expose palette counts. -- Docs: - - downstream implementation plans derived from this decision. - -## References - -- Agenda: `AGD-0005` -- Runtime decision: - `../runtime/discussion/workflow/decisions/DEC-0041-variable-glyph-bank-palette-protocol.md` -- Runtime handoff: - `../runtime/discussion/workflow/plans/PLN-0172-runtime-spec-handoff-to-packer-and-studio.md` -- Prior Studio/packer RGBA8888 lesson: - `discussion/lessons/DSC-0038-studio-packer-rgba8888-asset-pipeline/LSN-0053-rgba8888-is-the-canonical-studio-packer-palette-contract.md` - -## Revision Log - -- 2026-07-14: Initial accepted decision from `AGD-0005`, aligned with runtime - `DEC-0041`. diff --git a/discussion/workflow/plans/PLN-0087-variable-glyph-palette-spec-propagation.md b/discussion/workflow/plans/PLN-0087-variable-glyph-palette-spec-propagation.md deleted file mode 100644 index 6c59a310..00000000 --- a/discussion/workflow/plans/PLN-0087-variable-glyph-palette-spec-propagation.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -id: PLN-0087 -ticket: variable-tile-bank-palette-serialization -title: Variable Glyph Palette Spec Propagation -status: done -created: 2026-07-14 -completed: 2026-07-14 -ref_decisions: - - DEC-0038 -tags: - - specs - - packer - - studio - - glyph-bank - - palette-serialization ---- - -## Objective - -Propagate `DEC-0038` into the canonical Studio and packer specifications before -code changes start. - -## Background - -Runtime `DEC-0041` makes `palette_count` the serialized and resident palette -count for `GLYPH/indexed_v1`. Studio/packer `DEC-0038` adopts that runtime -contract downstream. Current packer specs still describe a fixed -`64 * 16 * 4 = 4096` palette block and `palette_count = 64`. - -## Scope - -### Included - -- Update packer specs for glyph-bank metadata, payload layout, and size formulas. -- Update Studio specs only where Studio-facing palette count projection or asset - details are documented. -- Preserve RGBA8888 channel order, packed `u4` pixels, and `GLYPH/indexed_v1`. - -### Excluded - -- Code changes. -- Fixture regeneration. -- Runtime spec changes. -- Any `GLYPH/indexed_v2` design. - -## Execution Steps - -### Step 1 - Update asset declaration metadata rules - -**What:** Define `palette_count` as the effective runtime metadata field. - -**How:** Update glyph-bank declaration language so `palette_count` means the -number of serialized and resident RGBA8888 palettes, constrained to `1..=64`. -State that `palette_authored`, if present, is informative and not runtime -effective. - -**File(s):** - -- `docs/specs/packer/3. Asset Declaration and Virtual Asset Contract Specification.md` - -### Step 2 - Update glyph payload layout - -**What:** Replace fixed 4096-byte palette block text. - -**How:** Change the layout to `palette_count * 16 * 4` palette bytes and update -formulas to: - -```text -size = ceil(width * height / 2) + palette_count * 16 * 4 -decoded_size = width * height + palette_count * 16 * 4 -``` - -**File(s):** - -- `docs/specs/packer/4. Build Artifacts and Deterministic Packing Specification.md` - -### Step 3 - Preserve v1 boundaries - -**What:** Explicitly prohibit v2, compatibility padding, and remapping. - -**How:** Add rules that this remains `GLYPH/indexed_v1`, old fixed-padding is -not a compatibility mode, and v1 has no sparse-to-dense palette remapping. - -**File(s):** - -- `docs/specs/packer/4. Build Artifacts and Deterministic Packing Specification.md` - -### Step 4 - Update Studio-facing spec text - -**What:** Align Studio projections if they mention palette count or fixed bank -shape. - -**How:** Search the Studio asset workspace spec for palette projection, details, -or pack wizard language and update only stale fixed-count wording. - -**File(s):** - -- `docs/specs/studio/4. Assets Workspace Specification.md` - -## Test Requirements - -### Unit Tests - -- Not applicable for this spec-only plan. - -### Integration Tests - -- Not applicable for this spec-only plan. - -### Manual Verification - -- Search specs for stale normal-path `palette_count = 64`, `4096`, fixed - 64-palette block, `GLYPH/indexed_v2`, and remapping language. - -## Acceptance Criteria - -- [x] Packer specs define `palette_count` as runtime-effective `1..=64`. -- [x] Packer specs use variable palette byte and size formulas. -- [x] Specs keep `GLYPH/indexed_v1` and reject v2 for this change. -- [x] Specs reject fixed-padding compatibility and sparse-to-dense remapping. -- [x] Studio specs contain no stale fixed 64-palette projection wording. - -## Dependencies - -- Depends on accepted `DEC-0038`. -- Should complete before code plans. - -## Risks - -- Leaving stale fixed 4096-byte examples will make implementation review - ambiguous. -- Over-editing Studio specs could imply UI behavior not required by `DEC-0038`. diff --git a/discussion/workflow/plans/PLN-0088-variable-glyph-palette-metadata-and-count-model.md b/discussion/workflow/plans/PLN-0088-variable-glyph-palette-metadata-and-count-model.md deleted file mode 100644 index 00790618..00000000 --- a/discussion/workflow/plans/PLN-0088-variable-glyph-palette-metadata-and-count-model.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: PLN-0088 -ticket: variable-tile-bank-palette-serialization -title: Variable Glyph Palette Metadata and Count Model -status: done -created: 2026-07-14 -completed: 2026-07-14 -ref_decisions: - - DEC-0038 -tags: - - packer - - metadata - - glyph-bank - - palette-count ---- - -## Objective - -Make packer metadata compute and expose runtime-effective glyph-bank -`palette_count` from declared palette data instead of hard-coding `64`. - -## Background - -`DEC-0038` requires `palette_count` to describe the number of serialized and -resident palettes expected by runtime. Current packer code emits -`palette_count = 64` and uses `palette_authored` for the actual authored count. -That makes the informative count and effective runtime count diverge. - -## Scope - -### Included - -- Compute effective glyph palette count from declared `output.pipeline.palettes`. -- Validate `palette_count` in `1..=64`. -- Keep palette identity direct; do not remap sparse authored indices. -- Stop using `palette_authored` as a runtime-effective field. - -### Excluded - -- Binary payload byte emission. -- Size formula changes. -- Studio UI changes except compile-safe DTO/projection adjustments. - -## Execution Steps - -### Step 1 - Add a runtime-effective palette count helper - -**What:** Centralize effective glyph palette count calculation. - -**How:** Add or update helper logic so packer derives `palette_count` from -declared palette indices. Because v1 has no remapping, the effective count must -cover the highest direct palette id: `max(index) + 1`. Reject no palettes, -negative indices, duplicate indices, and any effective count above `64`. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerAssetWalker.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerAssetDeclarationParser.java` - -### Step 2 - Replace fixed runtime metadata - -**What:** Stop writing `palette_count = 64` unconditionally. - -**How:** Replace runtime metadata emission so glyph-bank entries publish the -computed runtime-effective `palette_count`. Keep `palette_authored` only if it -is useful as pipeline/tooling information and never as runtime-effective root -metadata. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerRuntimeAssetMaterializer.java` - -### Step 3 - Validate direct palette identity - -**What:** Preserve runtime direct `palette_id` semantics. - -**How:** Ensure packer does not compact or renumber palette indices. If palette -indices are sparse, emitted palette slots up to `palette_count - 1` must keep -their direct identity, with missing slots represented by deterministic default -RGBA8888 palette data only when required to preserve direct ids. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerGlyphBankWalker.java` - -### Step 4 - Update projections that expose metadata - -**What:** Align details/read projections with the effective count. - -**How:** Ensure packer read/details APIs expose `palette_count` consistently -where runtime metadata is projected, and do not present `palette_authored` as -the field that runtime consumes. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerAssetDetailsService.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerReadMessageMapper.java` - -## Test Requirements - -### Unit Tests - -- Parser/metadata tests for `palette_count = 1`, intermediate count, and `64`. -- Rejection tests for zero effective palettes, duplicate indices, negative - indices, and count above `64`. -- Sparse direct identity tests where palette index `3` implies - `palette_count = 4`, without remapping palette `3` to `0`. - -### Integration Tests - -- Workspace read/build test proving asset table metadata reports variable - `palette_count`. - -### Manual Verification - -- Search packer code for `palette_count = 64` and `GLYPH_BANK_PALETTE_COUNT` - assumptions after the change. - -## Acceptance Criteria - -- [x] Packer computes runtime-effective `palette_count` from declared palettes. -- [x] `palette_count` is validated as `1..=64`. -- [x] Sparse palette ids are not remapped. -- [x] `palette_authored` is not treated as runtime-effective metadata. -- [x] Read/details projections do not expose stale fixed-count assumptions. - -## Dependencies - -- Depends on `PLN-0087`. -- Must complete before payload emission changes in `PLN-0089`. - -## Risks - -- Sparse palette handling can accidentally become remapping if implemented by - sorting and compacting declarations. -- Keeping `palette_authored` in tooling may confuse readers unless tests prove - runtime-effective metadata uses `palette_count`. diff --git a/discussion/workflow/plans/PLN-0089-variable-glyph-palette-payload-emission-and-size-accounting.md b/discussion/workflow/plans/PLN-0089-variable-glyph-palette-payload-emission-and-size-accounting.md deleted file mode 100644 index 161cdca0..00000000 --- a/discussion/workflow/plans/PLN-0089-variable-glyph-palette-payload-emission-and-size-accounting.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: PLN-0089 -ticket: variable-tile-bank-palette-serialization -title: Variable Glyph Palette Payload Emission and Size Accounting -status: done -created: 2026-07-14 -completed: 2026-07-14 -ref_decisions: - - DEC-0038 -tags: - - packer - - assets-pa - - glyph-bank - - payload ---- - -## Objective - -Change packer `GLYPH/indexed_v1` payload emission from a fixed 64-palette block -to exactly `palette_count * 16 * 4` RGBA8888 bytes, with matching size and -decoded-size accounting. - -## Background - -`FileSystemPackerWorkspaceService` currently defines fixed palette constants -and emits a fixed `GLYPH_BANK_PALETTE_BYTES` block. `DEC-0038` requires packer -to emit only the runtime-effective palette count and compute asset table sizes -from that count. - -## Scope - -### Included - -- Replace fixed palette byte constants with count-dependent formulas. -- Emit exactly `palette_count` palettes in RGBA byte order. -- Update asset table `size` and `decoded_size`. -- Reject metadata/payload mismatches. - -### Excluded - -- Palette model extraction changes covered by `PLN-0088`. -- Studio UI changes. -- Runtime code changes. - -## Execution Steps - -### Step 1 - Replace fixed palette byte constants - -**What:** Remove normal-path fixed `64 * 16 * 4` size assumptions. - -**How:** Keep maximum constants such as `MAX_PALETTE_COUNT = 64`, but compute -payload palette bytes as `palette_count * 16 * 4` at each glyph-bank packing -boundary. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerAssetWalker.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerRuntimeAssetMaterializer.java` - -### Step 2 - Emit variable palette bytes - -**What:** Write only runtime-effective palettes. - -**How:** Update palette byte generation to allocate -`palette_count * 16 * 4` bytes and fill direct palette ids from `0` through -`palette_count - 1`. Each color remains RGBA8888 in `R`, `G`, `B`, `A` order. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java` - -### Step 3 - Update size and decoded-size formulas - -**What:** Align asset table sizes with runtime `DEC-0041`. - -**How:** Compute: - -```text -size = ceil(width * height / 2) + palette_count * 16 * 4 -decoded_size = width * height + palette_count * 16 * 4 -``` - -Use these formulas for asset table entries, materializer expectations, and -workspace build outputs. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerRuntimeAssetMaterializer.java` - -### Step 4 - Reject metadata/payload mismatches - -**What:** Prevent stale fixed-padding artifacts. - -**How:** Add validation that emitted palette byte length, root metadata -`palette_count`, `size`, and `decoded_size` agree. Do not allow a fixed -64-palette block when `palette_count < 64`. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerRuntimeAssetMaterializer.java` - -## Test Requirements - -### Unit Tests - -- Assert emitted palette bytes for `palette_count = 1`, an intermediate count, - and `64`. -- Assert `size` and `decoded_size` formulas for variable counts. -- Assert RGBA byte order is unchanged. - -### Integration Tests - -- Build a workspace and inspect `assets.pa` asset table and payload length for - variable palette counts. - -### Manual Verification - -- Search for fixed normal-path `4096`, `64 * 16 * 4`, and - `GLYPH_BANK_PALETTE_BYTES` residue. - -## Acceptance Criteria - -- [x] Glyph payloads emit exactly `palette_count * 16 * 4` palette bytes. -- [x] Asset table `size` and `decoded_size` use variable formulas. -- [x] RGBA byte order is unchanged. -- [x] Fixed 64-palette padding is emitted only when `palette_count = 64`. -- [x] Metadata/payload mismatch is rejected or impossible by construction. - -## Dependencies - -- Depends on `PLN-0088`. - -## Risks - -- Updating metadata without payload length will corrupt runtime slicing. -- Updating payload length without decoded-size metadata will fail runtime asset - validation. diff --git a/discussion/workflow/plans/PLN-0090-studio-and-packer-projections-for-variable-glyph-palettes.md b/discussion/workflow/plans/PLN-0090-studio-and-packer-projections-for-variable-glyph-palettes.md deleted file mode 100644 index 502ad7d2..00000000 --- a/discussion/workflow/plans/PLN-0090-studio-and-packer-projections-for-variable-glyph-palettes.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -id: PLN-0090 -ticket: variable-tile-bank-palette-serialization -title: Studio and Packer Projections for Variable Glyph Palettes -status: done -created: 2026-07-14 -completed: 2026-07-14 -ref_decisions: - - DEC-0038 -tags: - - studio - - packer - - api - - projections - - glyph-bank ---- - -## Objective - -Align Studio-facing and packer-facing projections so variable glyph -`palette_count` is visible and not confused with `palette_authored`. - -## Background - -`DEC-0038` says packer metadata projection and Studio-facing read/detail APIs -must expose the runtime-effective `palette_count` correctly. Studio code must -not treat `palette_authored` as the runtime-effective count. - -## Scope - -### Included - -- Update packer read/detail DTO projections where runtime metadata is surfaced. -- Update Studio asset details, palette overhauling, schema, or pack wizard code - if it reads fixed counts or authored counts as runtime-effective. -- Keep `rgba8888` color projection unchanged. - -### Excluded - -- Binary payload emission. -- General palette UI redesign. -- `originalArgb8888` UI fallback cleanup unrelated to variable `palette_count`. - -## Execution Steps - -### Step 1 - Audit projection boundaries - -**What:** Find all Studio/packer paths that expose glyph palette metadata. - -**How:** Search for `palette_count`, `palette_authored`, -`GLYPH_BANK_PALETTE_COUNT`, fixed `64`, and related asset details projections. -Classify each match as runtime-effective metadata, tooling-only metadata, UI -fallback, or unrelated. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerAssetDetailsService.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerReadMessageMapper.java` -- `prometeu-studio/src/main/java/p/studio/workspaces/assets/**` - -### Step 2 - Update packer details/read surfaces - -**What:** Expose runtime-effective `palette_count`. - -**How:** Ensure details/read projections show the `palette_count` that will be -written to the runtime asset table. Preserve `palette_authored` only as -explicitly tooling-only information if it remains useful. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerAssetDetailsService.java` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerReadMessageMapper.java` - -### Step 3 - Update Studio consumers - -**What:** Prevent Studio from using authored count as runtime count. - -**How:** Adjust Studio asset details and pack wizard code so any displayed or -validated runtime count comes from effective `palette_count`. Keep palette -color rendering based on `rgba8888`. - -**File(s):** - -- `prometeu-studio/src/main/java/p/studio/workspaces/assets/details/**` -- `prometeu-studio/src/test/java/p/studio/workspaces/assets/details/**` - -### Step 4 - Preserve scene palette id shape - -**What:** Avoid accidental scene payload changes. - -**How:** Confirm scene projections still carry `palette_id` unchanged and only -runtime/packer validation changes count semantics. - -**File(s):** - -- `prometeu-studio/src/main/java/p/studio/workspaces/assets/**` -- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java` - -## Test Requirements - -### Unit Tests - -- Packer details/read tests for variable `palette_count`. -- Studio asset details tests proving runtime count and authored/tooling count - are not conflated. - -### Integration Tests - -- Workspace read/build flow where a glyph bank with an intermediate - `palette_count` is projected through packer/Studio surfaces. - -### Manual Verification - -- Search Studio and packer projection code for stale assumptions that - `palette_authored` is runtime-effective. - -## Acceptance Criteria - -- [x] Packer read/details projections expose effective `palette_count`. -- [x] Studio consumers do not use `palette_authored` as runtime-effective count. -- [x] `rgba8888` color projection remains unchanged. -- [x] Scene `palette_id` payload shape is unchanged. -- [x] Tests cover variable count projection. - -## Execution Notes - -- Packer runtime output projection is the `assets.pa` asset table generated by - `FileSystemPackerWorkspaceService`; `PLN-0088` and `PLN-0089` now project the - runtime-effective `palette_count` there. -- `PackerAssetDetailsService` and `PackerReadMessageMapper` project palette - color data through `pipelinePalettes` and do not expose - `palette_authored` as runtime-effective metadata. -- Studio asset details mapping forwards packer details without deriving a - runtime count from `palette_authored`. -- No DTO field was added because doing so would create a new Studio/packer API - surface not required by `DEC-0038`. - -## Dependencies - -- Depends on `PLN-0088`. -- Can run in parallel with `PLN-0089` after metadata semantics are stable. - -## Risks - -- UI code may still need ARGB helper fields for presentation. This plan must not - turn that into a runtime metadata decision. -- Overbroad projection edits could accidentally change scene contracts. diff --git a/discussion/workflow/plans/PLN-0091-variable-glyph-palette-tests-fixtures-and-final-validation.md b/discussion/workflow/plans/PLN-0091-variable-glyph-palette-tests-fixtures-and-final-validation.md deleted file mode 100644 index 222c681c..00000000 --- a/discussion/workflow/plans/PLN-0091-variable-glyph-palette-tests-fixtures-and-final-validation.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -id: PLN-0091 -ticket: variable-tile-bank-palette-serialization -title: Variable Glyph Palette Tests, Fixtures, and Final Validation -status: done -created: 2026-07-14 -completed: 2026-07-14 -ref_decisions: - - DEC-0038 -tags: - - tests - - fixtures - - validation - - glyph-bank - - palette-serialization ---- - -## Objective - -Update tests and fixtures to prove Studio/packer emit runtime-conforming -variable glyph palette payloads and contain no stale fixed-padding assumptions. - -## Background - -`DEC-0038` requires downstream fixture coverage for `palette_count = 1`, an -intermediate count, and `palette_count = 64`, plus producer validation for -metadata/payload mismatch. Earlier tests still assert `palette_count = 64`, -4096-byte palette blocks, and fixed glyph payload sizes. - -## Scope - -### Included - -- Update packer unit tests and integration-style workspace tests. -- Update packer fixture `asset.json` files and expected runtime payload checks. -- Update Studio tests only where Studio projections or UI logic expose - effective palette count. -- Run focused and broad validation. - -### Excluded - -- Runtime repository tests. -- New feature design. -- Palette remapping behavior. - -## Execution Steps - -### Step 1 - Update packer parser and metadata tests - -**What:** Prove effective `palette_count` validation. - -**How:** Add tests for `palette_count = 1`, intermediate counts, `64`, -duplicate/sparse direct identity behavior, and rejection above `64`. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDeclarationParserTest.java` -- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/PackerGlyphBankWalkerTest.java` - -### Step 2 - Update payload and asset table tests - -**What:** Prove variable payload lengths and size formulas. - -**How:** Replace fixed 4096-byte expectations with -`palette_count * 16 * 4`. Assert `size`, `decoded_size`, payload offsets, and -RGBA bytes for several counts. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/FileSystemPackerWorkspaceServiceTest.java` -- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/PackerRuntimeAssetMaterializerTest.java` -- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerRuntimePatchServiceTest.java` -- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerRuntimeRegistryTest.java` - -### Step 3 - Update fixtures - -**What:** Replace stale fixed-padding fixtures. - -**How:** Regenerate or edit packer test fixtures so at least one glyph bank uses -`palette_count = 1`, one uses an intermediate count, and one uses `64`. -Fixtures with fixed 64 padding are valid only when metadata says -`palette_count = 64`. - -**File(s):** - -- `prometeu-packer/prometeu-packer-v1/src/test/resources/fixtures/**/asset.json` -- Related binary or generated expected payload fixtures under packer test - resources. - -### Step 4 - Update Studio tests - -**What:** Cover Studio-facing projection changes. - -**How:** Adjust tests only where Studio surfaces effective palette counts or -metadata. Keep color rendering assertions focused on `rgba8888`. - -**File(s):** - -- `prometeu-studio/src/test/java/p/studio/workspaces/assets/details/**` - -### Step 5 - Run validation and residue scans - -**What:** Prove no normal-path fixed-padding residue remains. - -**How:** Run relevant Gradle tests and search normal specs/code/tests/fixtures -for stale `palette_count = 64`, `4096`, fixed `64 * 16 * 4`, `GLYPH/indexed_v2`, -and sparse remapping language. Classify any remaining match as historical, -max-bound, or a bug. - -**File(s):** - -- `docs/specs/packer/**` -- `docs/specs/studio/**` -- `prometeu-packer/**` -- `prometeu-studio/**` - -## Test Requirements - -### Unit Tests - -- Packer parser, walker, materializer, details/read, and workspace service tests - pass. -- Studio asset details tests pass where touched. - -### Integration Tests - -- Packer workspace build/materialization tests pass. -- Repository build or narrow Studio/packer build validation passes. - -### Manual Verification - -- Residue scan finds no normal-path fixed-padding contract text or code. -- `discussion validate` passes. - -## Acceptance Criteria - -- [x] Tests cover `palette_count = 1`, an intermediate count, and `64`. -- [x] Tests cover variable `size` and `decoded_size`. -- [x] Tests cover emitted palette byte length and RGBA order. -- [x] Tests cover metadata/payload mismatch rejection or producer validation. -- [x] Fixtures no longer rely on fixed 64-palette padding unless count is `64`. -- [x] Validation commands pass. -- [x] Residue scan results are clean or explicitly classified. - -## Execution Notes - -- Added packer workspace coverage for `palette_count = 1` and intermediate - `palette_count = 7`. -- Existing fixture and build paths continue to cover `palette_count = 64` where - a max-count payload is intended. -- Added parser coverage rejecting palette declaration index `64`, preserving - the v1 maximum effective count of `64` through direct ids `0..63`. -- `:prometeu-packer:prometeu-packer-v1:test` passed. -- `./gradlew build` passed. -- Residue scan found only intentional normative statements rejecting - `convertedRgb565`, `GLYPH/indexed_v2`, fixed-padding compatibility, and - sparse-to-dense remapping. - -## Dependencies - -- Depends on `PLN-0087`, `PLN-0088`, `PLN-0089`, and `PLN-0090`. - -## Risks - -- Generated project fixtures may require regeneration rather than manual edits. -- Broad residue scans may include historical discussions; scope final checks to - active specs, code, tests, and fixtures.