# Metadata Convergence to AssetEntry.metadata Decision Status: Accepted Date: 2026-03-17 Domain Owner: `docs/packer` Cross-Domain Impact: `docs/vm-arch`, runtime asset consumers ## Context The packer asset contract currently has multiple metadata-producing sources with different responsibilities: - asset-level runtime contract metadata (authoring declaration); - codec-related metadata (codec configuration/effective codec parameters); - pipeline-derived metadata generated during build materialization (for example, indexed ranges for packed samples). At runtime, consumers read one metadata sink from the asset table: `AssetEntry.metadata`. Without an explicit decision, the system risks inconsistent behavior and documentation drift: - metadata spread across sources without deterministic merge semantics; - ambiguity between storage-layout fields (`AssetEntry.offset`/`AssetEntry.size`) and pipeline-internal indexing data (`offset`/`length` per sample); - Studio, packer, and runtime docs diverging on where runtime consumers should read final values. ## Decision The following direction is adopted: 1. All runtime-consumable metadata must converge to a single sink: `AssetEntry.metadata`. 2. Source segmentation in `asset.json` is allowed for authoring clarity, but build materialization must normalize these sources into that single sink. 3. Metadata normalization must be deterministic and testable. 4. `AssetEntry.offset` and `AssetEntry.size` remain payload slicing fields and are not reinterpreted as pipeline-internal indexing metadata. 5. Pipeline indexing metadata (for example, audio per-`sample_id` ranges) must live inside `AssetEntry.metadata` under explicit keys. ## Adopted Constraints ### 1. Source Segmentation vs Runtime Sink - authoring sources may remain segmented (asset metadata, codec metadata, pipeline metadata); - runtime consumers must read effective values from `AssetEntry.metadata`; - packer build output is responsible for normalization. ### 2. Deterministic Convergence - normalization must produce the same `AssetEntry.metadata` for the same effective declaration and build inputs; - metadata key collisions between independent sources must be rejected with a build-time error unless explicitly specified by family/format contract; - normalization order and collision policy must be documented by packer specs. ### 3. Audio Indexing Semantics For multi-sample audio banks, sample indexing metadata belongs to `AssetEntry.metadata`, keyed by `sample_id`. Illustrative shape: ```json { "metadata": { "sample_rate": 22050, "channels": 1, "samples": { "1": { "offset": 0, "length": 100 } }, "codec": { "parity": 10 } } } ``` This decision accepts either nested codec metadata (for example `metadata.codec.*`) or a flat equivalent only when the family/format spec declares that shape explicitly. ### 4. Offset Ambiguity Guardrail - `AssetEntry.offset`/`AssetEntry.size` describe where one packed asset payload is stored in `assets.pa`; - `metadata.samples[*].offset`/`metadata.samples[*].length` describe internal layout/indexing inside that asset's runtime payload contract; - documentation and tests must keep these meanings separate. ## Why This Direction Was Chosen - It keeps runtime consumption simple: one metadata sink. - It preserves authoring ergonomics: source metadata can stay segmented by concern. - It avoids semantic duplication between packer and runtime consumers. - It creates a clear path for bank-like assets (tiles/audio) that require indexed internal metadata. ## Explicit Non-Decisions This decision does not define: - the final complete metadata schema for every asset family; - the final canonical codec metadata shape (`nested` vs `flat`) for all formats; - multi-sample audio runtime loading implementation details; - exact binary container/header layout for audio banks. ## Implications - packer specs must define normalization semantics and collision policy; - packer build/materialization must emit normalized metadata into `AssetEntry.metadata`; - runtime-facing docs must state that effective metadata is read from `AssetEntry.metadata`; - tests must cover convergence correctness and ambiguity boundaries for offset semantics. ## Propagation Targets Specs: - [`../specs/3. Asset Declaration and Virtual Asset Contract Specification.md`](../specs/3.%20Asset%20Declaration%20and%20Virtual%20Asset%20Contract%20Specification.md) - [`../specs/4. Build Artifacts and Deterministic Packing Specification.md`](../specs/4.%20Build%20Artifacts%20and%20Deterministic%20Packing%20Specification.md) - [`../../vm-arch/ARCHITECTURE.md`](../../vm-arch/ARCHITECTURE.md) Plans: - next packer PR/plan that introduces metadata normalization and multi-source merge validation Code: - packer asset declaration/materialization pipeline - asset table emission path (`AssetEntry.metadata` payload) Tests: - normalization unit tests (source merge determinism) - collision/ambiguity tests for offset semantics - regression tests for runtime-readable metadata shape Docs: - packer specs and learn artifacts covering metadata source-to-sink flow - runtime asset-management documentation referencing `AssetEntry.metadata` as sink ## References Related specs: - [`../specs/3. Asset Declaration and Virtual Asset Contract Specification.md`](../specs/3.%20Asset%20Declaration%20and%20Virtual%20Asset%20Contract%20Specification.md) - [`../specs/4. Build Artifacts and Deterministic Packing Specification.md`](../specs/4.%20Build%20Artifacts%20and%20Deterministic%20Packing%20Specification.md) Related agendas: - no formal agenda artifact yet for this specific topic; this decision consolidates current packer/runtime alignment discussion. ## Validation Notes This decision is correctly implemented only when all of the following are true: - runtime consumers can read final effective metadata exclusively from `AssetEntry.metadata`; - segmented metadata sources in authoring inputs converge deterministically during packing; - offset semantics remain unambiguous between asset-table payload slicing and pipeline-internal indexing; - documentation across packer and runtime-facing domains is consistent about this source-to-sink contract.