3.6 KiB
Asset Management Mental Model
Status: pedagogical Companion specs:
Origin decision: ../decisions/011-assets-pa-autocontained-runtime-contract.md
PROMETEU treats assets as a self-contained cart artifact, not as metadata scattered across manifest.json, the loader, and the runtime.
One Runtime Artifact
The right mental model is:
manifest.jsonidentifies the cart and its capabilities;assets.pacarries the runtime-facing asset contract;- the runtime consumes that contract without depending on auxiliary tooling artifacts.
That avoids mixing:
- cart editorial metadata;
- internal packer details;
- runtime loading policy.
Why assets.pa Owns The Asset Contract
assets.pa puts into the same binary:
- a fixed prelude to locate the header;
- a JSON header that is easy to inspect;
- the cold binary payload of the assets.
That split exists to preserve two properties at the same time:
- fixed cost to open and validate the artifact;
- a readable header that is simple to debug.
The important point is not the format by itself. The important point is that the runtime finds everything it needs for assets behind one stable boundary.
preload Is Not asset_table
Both live in the header, but they serve different roles:
asset_tableis the live asset-resolution index for the entire execution;preloadis only a boot-time instruction for initial residency.
A short way to think about it:
asset_tablestays;preloadpasses.
That prevents the runtime from treating preload as permanent metadata when, in practice, it is only an initial loading impulse.
Payload-Relative Thinking
AssetEntry offsets are relative to the start of the payload, not to the start of the whole file.
That choice preserves the semantics of the asset domain:
AssetEntrydescribes where content sits inside the cold-byte region;- the outer envelope can evolve without contaminating each entry with container details.
The runtime only needs to resolve:
payload_base + entry.offset
Slice-First Loading
The correct loading mental model is not:
ROM -> load the whole assets.pa into RAM -> look up asset
The correct flow is:
ROM -> open_slice -> CODEX/decode -> Bank
or, when the codec requires it:
ROM -> open_slice -> temporary blob -> CODEX/decode -> Bank
That matters because PROMETEU was designed for low-cost hardware. Keeping the whole payload resident as a baseline wastes memory, couples IO to a monolithic blob, and weakens the runtime's real boundary.
OP_MODE Belongs To The Runtime
The cart describes the asset. The runtime decides how to consume the slice.
In v1, that decision comes from the codec/CODEX:
- some assets can be read directly from the limited view;
- others require temporary materialization before decode.
The key point is to separate:
- the asset storage contract;
- the operational strategy for reading and decode.
Why This Fits PROMETEU
This model fits the project well because:
- it reduces dependence on metadata scattered through
manifest.json; - it separates
packer,shipper, and runtime more cleanly; - it allows early failure when
Capability::Assetrequiresassets.pa; - it preserves a runtime that can run on desktop and on low-cost dedicated hardware.
When thinking about assets in PROMETEU, think less in terms of "a manifest with attachments" and more in terms of "a cart with an asset artifact that explains itself".