prometeu-studio/docs/specs/packer/3. Asset Declaration and Virtual Asset Contract Specification.md
bQUARKz dd6c9dd718
All checks were successful
JaCoCo Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 60.67% (15274/25176) * Branch Coverage: 53.64% (5782/10779) * Lines of Code: 25176 * Cyclomatic Complexity: 9960 #### Quality Gates Summary Output truncated.
Test / Build skipped: 11, passed: 545
Intrepid/Prometeu/Studio/pipeline/head This commit looks good
dev/glyph-bank-alignment (#3)
Reviewed-on: #3
Co-authored-by: bQUARKz <bquarkz@gmail.com>
Co-committed-by: bQUARKz <bquarkz@gmail.com>
2026-04-10 06:14:07 +00:00

6.2 KiB

Asset Declaration and Virtual Asset Contract Specification

Status: Draft Scope: Common asset.json contract Purpose: Define the shared declaration model for raw and virtual assets.

Authority and Precedence

This specification consolidates the initial packer agenda and decision wave into normative form.

Core Rules

The common asset.json contract requires these top-level fields:

  • schema_version
  • asset_uuid
  • name
  • type
  • inputs
  • output
  • preload

The common contract may also include:

  • build

Meaning of asset_uuid

asset_uuid is the stable asset-local identity anchor.

Rules:

  • it is required;
  • it must be stable across relocate and rename flows;
  • it is not the project-local runtime artifact identity;
  • it is not a substitute for registry-owned asset_id;
  • it exists so the asset root can preserve identity even when path-based assumptions drift;
  • it must remain compatible with packer reconcile behavior and migration flows.

Meaning of name

name is the logical asset reference label.

Rules:

  • it is required;
  • it is not the stable artifact identity;
  • it may still be used by runtime-facing APIs and source-level workflows.

Meaning of type

type identifies the authoring-side asset family.

Rules:

  • it is not the runtime bank identity;
  • the runtime-facing technical target belongs in output.format.

Examples:

  • glyph_bank
  • sound_bank

Inputs

inputs is a structured object keyed by semantic role.

Rules:

  • each key names an input role such as sprites, palettes, or sources;
  • each value is a list of paths;
  • paths are relative to the asset root;
  • even a single input is represented as a list.

This model supports grouped virtual assets such as atlases and bank-style assets.

Output

output is the runtime-relevant output declaration.

Required baseline fields:

  • output.format
  • output.codec

Optional baseline field:

  • output.metadata
  • output.pipeline

Rules:

  • output.format defines the semantic/runtime format contract;
  • output.codec defines storage/extraction behavior;
  • output.codec serialized values must use SCREAMING_SNAKE_CASE;
  • output.metadata carries runtime-relevant format-specific detail;
  • output.pipeline carries tooling/build metadata kept separate at authoring time;
  • codec must remain explicit and must not be hidden inside format naming.

Explicit Index Collections

When output.pipeline carries ordered collections whose members need stable semantic identity, that identity must not depend on raw list position alone.

Rules:

  • collections such as output.pipeline.palettes may remain JSON arrays for authoring ergonomics;
  • when a collection member has runtime- or packing-relevant identity, each entry must carry an explicit index;
  • output.pipeline.palettes entries must use the shape { "index": <int>, "palette": { ... } };
  • the packer must sort such entries by numeric index, not by physical array position;
  • duplicate or malformed indices are structural errors;
  • missing or malformed palette payloads are structural errors;
  • editorial reordering of the JSON array alone must not change semantic meaning.

Example:

{
  "output": {
    "pipeline": {
      "palettes": [
        {
          "index": 0,
          "palette": {
            "originalArgb8888": [4294901760, 4278255360],
            "convertedRgb565": [63488, 2016]
          }
        }
      ]
    }
  }
}

Metadata Source Segmentation and Runtime Sink

asset.json may keep metadata segmented by concern during authoring.

Rules:

  • declaration-time metadata may come from multiple sources under the asset contract (for example, format metadata, codec-related metadata, and build/pipeline-derived declarations);
  • output.pipeline may carry nested pipeline-derived metadata objects;
  • this segmentation exists for authoring clarity and does not define multiple runtime sinks;
  • output.pipeline is tooling-only and must not become part of the runtime-facing asset header by default;
  • pipeline-derived values required at runtime must be promoted explicitly into normative runtime-owned metadata fields;
  • runtime consumers must read effective metadata from the runtime asset entry metadata sink (AssetEntry.metadata);
  • convergence/normalization behavior is normative in the build artifact specification.

Build

build is optional and process-oriented.

Rules:

  • it may describe how authoring inputs are transformed or organized;
  • if a parameter affects the runtime-facing output contract, it belongs in output.metadata;
  • build must not hide runtime-relevant semantics.

Operational State Exclusion

asset.json is a declaration artifact, not a catalog cache.

Rules:

  • transient UI state must not be stored in asset.json;
  • registry-managed fields such as asset_id and included_in_build must not be duplicated into asset.json;
  • packer cache or snapshot bookkeeping must not be materialized into asset.json as normal operational state;
  • asset.json should remain focused on identity anchoring plus declared authoring/packing behavior.

Preload

Each registered asset must declare preload intent explicitly.

Baseline shape:

{
  "preload": {
    "enabled": true
  }
}

Rules:

  • preload.enabled is required and boolean;
  • preload participation is declared, not inferred;
  • richer preload policy fields are deferred.

Defaults and Materialization

Defaults that affect runtime-visible behavior must not remain hidden.

Rules:

  • runtime-relevant defaults should be materialized in asset.json whenever practical;
  • if materialized later, the resulting artifact must expose effective values explicitly.

Versioning

The asset.json schema is versioned independently from:

  • registry schema
  • runtime-facing artifact schema
  • format contract versions

Format-specific contracts evolve through values such as GLYPH/indexed_v1.

Non-Goals

  • field-level format schemas for every output family
  • rich preload policies
  • source-language lowering behavior for asset references

Exit Criteria

This specification is complete enough when:

  • the common asset.json shape is stable;
  • raw and virtual assets share a coherent baseline contract;
  • format-specific specs can build on it cleanly.