prometeu-studio/docs/specs/packer/3. Asset Declaration and Virtual Asset Contract Specification.md

221 lines
6.2 KiB
Markdown

# 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:
```json
{
"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:
```json
{
"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.