diff --git a/docs/packer/specs/4. Build Artifacts and Deterministic Packing Specification.md b/docs/packer/specs/4. Build Artifacts and Deterministic Packing Specification.md index 95149e6c..c509b85b 100644 --- a/docs/packer/specs/4. Build Artifacts and Deterministic Packing Specification.md +++ b/docs/packer/specs/4. Build Artifacts and Deterministic Packing Specification.md @@ -90,6 +90,13 @@ Rules: - metadata key collisions across independent sources must fail build unless the family/format spec declares an explicit merge rule; - normalization behavior must be testable and covered by conformance-oriented tests. +Baseline normalized metadata segmentation: + +- `output.metadata` materializes at the metadata root; +- `output.codec_configuration` materializes under `metadata.codec`; +- `output.pipeline` materializes under `metadata.pipeline`; +- format-specific runtime-required fields may remain directly readable at the metadata root when the runtime consumer requires them there. + ### Preload Preload is emitted deterministically from per-asset declaration. @@ -131,6 +138,73 @@ Offset ambiguity guardrail: - internal pipeline indexing data (for example per-sample ranges for audio banks) must live under `asset_table[].metadata`; - internal indexing fields must not be interpreted as payload slicing fields. +## Format-Specific Baseline: `TILES/indexed_v1` + +The first-wave producer contract for `TILES/indexed_v1` is fixed and runtime-aligned. + +### Tile Selection and Identity + +Rules: + +- only selected artifacts participate in the emitted tile bank; +- `1 artifact = 1 tile` in v1; +- artifacts are normalized by ascending `artifacts[*].index`; +- emitted `tile_id` equals the normalized artifact index; +- duplicate or gapped artifact indices are build-blocking structural failures. + +### Emitted Sheet Shape + +Rules: + +- the emitted tile-bank sheet is always `256 x 256` in v1; +- tile placement within that emitted sheet is row-major; +- runtime `width` and `height` for the bank entry therefore refer to the full emitted sheet, not one individual artifact; +- resulting per-bank capacities are: + - `tile_size = 8` -> `1024` tiles + - `tile_size = 16` -> `256` tiles + - `tile_size = 32` -> `64` tiles +- capacity overflow is a build-blocking structural failure. + +### Payload Layout + +Rules: + +- the serialized payload for `TILES/indexed_v1` is: + 1. one packed `u4` pixel plane for the full emitted sheet; + 2. one palette block of `64 * 16 * 2 = 2048` bytes; +- packed pixel bytes must be emitted by the packer, not inferred later by the runtime; +- the palette block is serialized as `RGB565` `u16` values; +- palette bytes must be emitted in little-endian order; +- payload interpretation must not depend on incidental per-artifact boundaries. + +### Runtime Entry Derivation + +Rules: + +- emitted tile-bank entries use: + - `bank_type = TILES` + - `codec = NONE` +- tile-bank v1 metadata must expose at least: + - `tile_size` + - `width` + - `height` + - `palette_count` +- tile-bank v1 requires `palette_count = 64`; +- tile-bank v1 size formulas are: + - `size = ceil(width * height / 2) + 2048` + - `decoded_size = (width * height) + 2048` + +### Palette Contract + +Rules: + +- bank palettes are declared under `output.pipeline.palettes`; +- each palette declaration uses the shape `{ "index": , "palette": { ... } }`; +- palette ordering is ascending numeric `index`, never raw array position; +- palette ids in the emitted tile bank are the normalized declared palette indices; +- any tile in the bank may be rendered with any palette in the bank at runtime; +- palette selection is a runtime draw concern, not a tile-payload embedding concern. + ## Determinism Equivalent build inputs must produce equivalent outputs.