# PR-32 Palette Declarations with Explicit Index Contract Domain Owner: `docs/packer` Cross-Domain Impact: `docs/studio`, `../runtime` ## Briefing The current authoring shape for `asset.json.output.pipeline.palettes` is still too dependent on list order as semantic identity. That is fragile: - editorial reordering can silently change meaning; - merges become harder to review safely; - the packer has to infer identity from position instead of reading it explicitly. The repository already depends on stable palette ordering for `tile bank` packing. That ordering should therefore be explicit in the authoring contract. ## Decisions de Origem - [`../decisions/Pack Wizard Pack Execution Semantics Decision.md`](../decisions/Pack%20Wizard%20Pack%20Execution%20Semantics%20Decision.md) - ongoing agenda: [`../agendas/Tile Bank Packing Materialization Agenda.md`](../agendas/Tile%20Bank%20Packing%20Materialization%20Agenda.md) ## Objective Replace list-position-defined palette identity with an explicit index-bearing declaration contract for `asset.json.output.pipeline.palettes`. Recommended shape: ```json "palettes": [ { "index": 0, "palette": { ... } }, { "index": 1, "palette": { ... } } ] ``` ## Dependencies - tile-bank materialization agenda in `docs/packer/agendas` - runtime-side tile-bank consumer contract already aligned around stable palette ids ## Scope - define the normative authoring shape for `output.pipeline.palettes` - make `index` the semantic identity of each declared palette - require packer normalization to sort by `index`, not by list position - define diagnostics for duplicate, missing, invalid, or malformed palette entries - prepare propagation into: - packer specs - parser/runtime-facing normalization code - Studio editing surfaces if they expose palette management ## Non-Goals - no immediate migration of `artifacts` in this PR - no tile-bank payload implementation in this PR - no runtime code changes in this PR - no speculative keyed-object JSON contract for palettes in this wave ## Execution Method 1. Update the packer-side documentation/decision chain to make palette identity explicit. 2. Define `output.pipeline.palettes` as a list of records with: - `index` - `palette` 3. State that semantic ordering is ascending numeric `index`, never raw list position. 4. Define structural diagnostics: - duplicate `index` => blocking - negative or malformed `index` => blocking - missing `palette` payload => blocking - palette count above the runtime-facing v1 limit => blocking 5. Define whether index gaps are: - blocking - or warning/advisory 6. Prepare follow-up implementation PRs for parser, validation, and Studio surfaces. ## Contract Direction First-wave packer contract direction: 1. `output.pipeline.palettes` remains a JSON array for authoring ergonomics; 2. each entry must declare an explicit `index`; 3. each entry must declare a `palette` object payload; 4. packer meaning comes from numeric `index`, not from the physical array position; 5. the runtime-facing `palette_id` consumed later by tile/sprite draw paths is the normalized numeric palette `index`. ## Acceptance Criteria - the packer docs/spec path no longer relies on raw list order as palette identity - the explicit-index palette shape is documented clearly enough for parser and Studio implementation - duplicate or malformed palette indices are identified as structural diagnostics - the contract leaves no ambiguity about whether sorting happens by array order or by `index` ## Validation - editorial validation across packer agenda/decision/spec material - parser-oriented review proving the contract is implementable without hidden heuristics - Studio-facing review confirming the editing UX can preserve stable palette identity ## Affected Artifacts - `docs/packer/agendas/**` - `docs/packer/decisions/**` - `docs/packer/specs/3. Asset Declaration and Virtual Asset Contract Specification.md` - `docs/packer/specs/4. Build Artifacts and Deterministic Packing Specification.md` - future parser/runtime materialization code under `prometeu-packer-v1`