11 KiB
Asset Management
Domain: asset runtime surface Function: normative
This chapter defines the runtime-facing asset model of PROMETEU.
1 Scope
PROMETEU asset management is bank-centric.
Assets are:
- cold bytes stored in the cartridge;
- described by cartridge metadata;
- materialized into host-managed banks;
- separate from VM heap ownership.
This chapter describes the runtime contract currently visible in the codebase. It is not a full tooling pipeline specification.
2 Core Principles
- asset residency is explicit;
- asset memory belongs to the machine, not to the VM heap;
- banks and slots are hardware/runtime concepts;
- loading and activation are explicit operations;
- asset memory does not participate in GC.
3 Cartridge Asset Artifact
The runtime currently consumes one primary cartridge asset artifact:
assets.pa: autocontained asset artifact.
assets.pa carries, inside the same binary:
- fixed binary prelude;
- JSON header;
- payload bytes.
The JSON header carries:
asset_table: metadata entries describing asset content;preload: optional initial residency requests consumed during cartridge initialization.
This chapter describes the runtime-facing asset contract. It does not define the Studio packer workflow or the shipper pipeline that publishes the cartridge.
3.1 assets.pa v1 envelope
assets.pa v1 is structured as:
[fixed binary prelude]
[json header]
[binary payload region]
The fixed binary prelude contains, at minimum:
magicschema_versionheader_lenpayload_offset
It may additionally include:
flagsreservedheader_checksum
3.2 Header and payload contract
The runtime loads:
asset_tablefrom the JSON header and keeps it live during cartridge execution;preloadfrom the JSON header and consumes it only during boot.
Payload bytes are addressed from the payload region using offsets relative to payload_offset, not relative to the start of the whole file.
4 Asset Table
Current runtime-facing asset metadata includes:
AssetEntry {
asset_id
asset_name
bank_type
offset
size
decoded_size
codec
metadata
}
This table describes content identity and storage layout, not live residency.
asset_id is the stable runtime-facing asset identity and uses 32-bit signed integer semantics compatible with Java int.
offset is relative to the start of the payload region inside assets.pa.
size is the serialized byte count stored in the payload region.
decoded_size is the byte count of the materialized runtime bank after decode, not necessarily the same as the serialized payload size.
codec identifies the generic transformation pipeline applied to the serialized payload slice before the asset becomes a resident bank.
codec does not define the bank-specific serialized layout itself. Specialized banks may still have normative decode rules even when codec = NONE.
4.1 TILES asset contract in v1
Para BankType::TILES, o contrato v1 voltado para o runtime é:
codec = NONE- pixels serializados usam índices de paleta
u4empacotados - paletas serializadas usam
RGB565(u16, little-endian) palette_count = 64- a materialização em runtime pode expandir índices de pixel para um
u8por pixel
NONE para TILES significa que não há camada de codec genérica adicional além do próprio contrato do banco.
Para a janela de transição atual:
RAWé um alias legado e depreciado deNONE- novos materiais publicados devem usar
NONEcomo valor canônico
Mesmo com codec = NONE, TILES ainda requer decode específico de banco a partir de seu payload serializado. O layout de bytes serializados não precisa, portanto, ser idêntico ao layout em memória.
4.1.1 Metadata Normalization
Seguindo a DEC-0004, o campo AssetEntry.metadata deve ser estruturado de forma segmentada para evitar ambiguidades.
Campos de metadados obrigatórios (efetivos) para TILES no nível raiz:
tile_size: aresta do tile em pixels; valores válidos são8,16, ou32width: largura total da folha do banco em pixelsheight: altura total da folha do banco em pixelspalette_count: número de paletas serializadas para o banco
Subárvores opcionais e informativas:
metadata.codec: Configuração específica do codec/compressor (ex: dicionários, flags de compressão).metadata.pipeline: Metadados informativos do processo de build do Studio (ex: source hashes, timestamps, tool versions).
Regras de validação para TILES v1:
palette_countdeve ser64width * heightdefine o número de pixels indexados lógicos na folha decodificada- metadados adicionais podem existir, mas o contrato do runtime não deve depender deles para reconstruir o banco em memória (exceto se definidos na raiz como campos efetivos).
4.1.2 Payload Layout
- packed indexed pixels for the full sheet, using
ceil(width * height / 2)bytes; - palette table, using
palette_count * 16 * 2bytes.
The tile-bank payload therefore separates serialized storage form from runtime memory form:
- serialized pixel plane: packed
4bpp - decoded pixel plane: expanded
u8indices, one entry per pixel - palette table:
64 * 16colors inRGB565
For TILES v1:
sizemust matchceil(width * height / 2) + (palette_count * 16 * 2)decoded_sizemust match(width * height) + (palette_count * 16 * 2)
5 Banks and Slots
The current runtime exposes bank types:
GLYPHSOUNDS
Assets are loaded into explicit slots identified by slot index at the public ABI boundary.
The runtime resolves bank context from asset_table using asset_id.
Internally, the runtime may still use a bank-qualified slot reference such as:
SlotRef { bank_type, index }
That internal representation is derived from the resolved AssetEntry, not supplied by the caller.
5.1 Canonical Bank Telemetry
The canonical visible bank telemetry contract is exposed by AssetManager.
The per-bank summary is slot-first and uses this shape:
BankTelemetry {
bank_type
used_slots
total_slots
}
Rules:
- the visible contract MUST NOT expose byte-oriented bank occupancy as the canonical summary;
- canonical bank names are
GLYPHandSOUNDS; - detailed occupancy inspection remains slot-based through slot references, not bank byte totals;
- any residual byte accounting MAY exist internally, but it is not part of the visible bank telemetry contract.
6 Load Lifecycle
The runtime asset manager exposes a staged lifecycle:
PENDINGLOADINGREADYCOMMITTEDCANCELEDERROR
High-level flow:
- request load of an asset into a slot;
- resolve the asset entry from live
asset_table; - open the payload slice in
assets.pa; - perform read/decode/materialization work;
- mark the load
READY; - explicitly
commit; - activate the resident asset in the slot.
The canonical payload paths are:
ROM -> open_slice -> CODEX/decode -> BankROM -> open_slice -> temporary in-memory blob -> CODEX/decode -> Bank
open_slice is the runtime-facing concept for opening a limited view over a payload slice. The runtime must not require the whole assets.pa payload to remain resident in RAM as its baseline operating mode.
OP_MODE selects between direct slice consumption and temporary materialization in memory.
For v1:
OP_MODEis derived fromcodec/CODEX;- explicit per-asset hinting is not part of the baseline contract.
TILESwithcodec = NONEmay still stage in memory before bank installation because bank-specific decode expands packed pixel indices into the resident representation.- during the migration window, runtime may accept legacy
RAWas an alias ofNONE.
The runtime does not treat asset installation as implicit side effect.
7 Residency and Ownership
Asset banks are host/runtime-owned memory.
Therefore:
- VM heap does not own asset residency;
- GC does not scan asset bank memory;
- shutting down a cartridge can release bank residency independently of VM heap behavior.
- the runtime must not keep the full
assets.papayload resident in RAM as a baseline requirement.
8 Bank Telemetry
The runtime surfaces bank and slot statistics such as:
- total bytes;
- used bytes;
- free bytes;
- inflight bytes;
- slot occupancy;
- resident asset identity per slot.
These metrics support debugging, telemetry, and certification-oriented inspection.
9 Preload
preload is stored in the JSON header of assets.pa.
The normative preload shape is:
PreloadEntry {
asset_id
slot
}
These preload entries are consumed during cartridge initialization so the asset manager can establish initial residency before normal execution flow.
Validation rules:
preloadis resolved byasset_id, not byasset_name;- every
preload.asset_idmust exist in the sameasset_table; - no two preload entries may resolve to the same
(bank_type, slot)pair; - legacy preload keyed by
asset_nameis invalid for the current contract.
Lifecycle rule:
preloadis boot-time input only;- it does not need to remain live after initialization completes.
Bootstrap rule:
- invalid preload is a structural cartridge error and must fail cartridge bootstrap before normal execution begins.
10 Relationship to Other Specs
13-cartridge.mddefines the cartridge package and the requirement thatassets.pacarries its own asset header.16-host-abi-and-syscalls.mddefines the syscall boundary used to manipulate assets.03-memory-stack-heap-and-allocation.mddefines the distinction between VM heap memory and host-owned memory.
11 Syscall Surface and Status Policy
asset follows status-first policy.
Fault boundary:
Trap: structural ABI misuse (type/arity/capability/shape mismatch);status: operational failure;Panic: internal invariant break only.
11.1 MVP syscall shape
asset.load(asset_id, slot) -> (status:int, handle:int)asset.status(handle) -> status:intasset.commit(handle) -> status:intasset.cancel(handle) -> status:int
Rules:
handleis valid only whenloadstatus isOK;- failed
loadreturnshandle = 0; commitandcancelmust not be silent no-op for unknown/invalid handle state.asset.loadresolves the target bank type fromasset_tableusingasset_id;- public callers must not supply
asset_nameorbank_typetoasset.load; - slot validation and residency/lifecycle rejection remain in
assetstatus space and are not delegated tobank.
11.2 Minimum status tables
asset.load request statuses:
0=OK3=ASSET_NOT_FOUND5=SLOT_INDEX_INVALID6=BACKEND_ERROR
asset.status lifecycle statuses:
0=PENDING1=LOADING2=READY3=COMMITTED4=CANCELED5=ERROR6=UNKNOWN_HANDLE
asset.commit and asset.cancel operation statuses:
0=OK1=UNKNOWN_HANDLE2=INVALID_STATE