6.4 KiB
Asset Workspace, Registry, and Stable Identity Decision
Status
Accepted
Date
2026-03-11
Context
This decision closes the architectural questions raised in 01.1. Asset Workspace, Registry, and Stable Identity Agenda.
The packer needs a stable model for:
- what counts as a managed asset;
- how local asset declaration relates to workspace registry state;
- how asset identity survives rename and relocation;
- how adoption and diagnostics distinguish registered from unregistered asset roots.
If this model remains ambiguous, later specs for asset.json, virtual assets, diagnostics, build outputs, and Studio services will inherit unstable semantics.
Decision
The packer adopts a registry-authoritative, anchor-declared, identity-stable, path-mutable model.
1. Managed asset unit
A managed asset is one asset root directory.
Rules:
- one managed asset maps to one dedicated asset root directory;
- one asset root contains exactly one anchor
asset.json; - files and subdirectories under that root are inputs or support files of that managed asset unless explicitly modeled otherwise in future specs;
- individual source files are not separate managed assets by default.
This allows grouped assets such as atlases, image banks, or palette-driven bundles to be modeled as one managed asset with many inputs.
2. Registry authority
assets/.prometeu/index.json is the authoritative workspace registry for managed assets.
It defines:
- which assets are officially managed by the packer;
- their stable project-local identities;
- their current registered root locations;
- allocator state and registry-owned metadata.
If an asset root is not present in index.json, it is not part of the managed build set.
3. Asset-local declaration
asset.json is the asset-local declaration anchored at the asset root.
It defines the local declaration of the asset, including the asset contract that later specs will refine.
asset.json does not, by itself, make an asset managed.
Registration and build inclusion remain registry-owned concerns.
4. Identity model
Each managed asset has:
asset_id: stable project-local identity;asset_uuid: stable long-lived identity for tooling and migration scenarios.
The following are not primary identity:
- display name;
- filesystem path;
- internal input filenames.
Name and path are mutable presentation or location fields.
However, asset_name may still participate in authoring and runtime-facing APIs as a logical reference label.
That does not make it the stable identity of the asset.
Practical consequence:
- changing
asset_namedoes not create a new asset identity; - but changing
asset_namemay still require source-level or tooling-level reference updates where game/runtime APIs refer to assets by name.
5. Relocation and rename
Moving or renaming an asset root does not create a new asset.
Rules:
asset_idmust remain unchanged;asset_uuidmust remain unchanged;- registry location is updated to the new asset root;
- this is treated as relocation, not recreation.
6. Orphan anchor behavior
An asset.json without a corresponding registry entry is an orphan asset declaration.
Rules:
- it does not enter the build automatically;
- it must be surfaced by workspace diagnostics such as
doctor --workspace; - it may be incorporated only through explicit adoption flow.
7. asset_id allocation
asset_id allocation is registry-owned and strictly monotonic within the project.
Rules:
- allocation happens once at registration time;
- previously issued IDs must not be silently recycled;
- allocator state is persisted in
index.json; - allocator rollback is not allowed as normal behavior.
If audit metadata is useful, it should be recorded separately, for example as creation metadata. Time should not be encoded into the runtime-facing identity model without a concrete future need.
8. Manual copy and identity collision
Manual copy of an asset root that duplicates identity-bearing content must not be reconciled implicitly.
Rules:
- packer must surface identity collision or duplicate-anchor diagnostics explicitly;
- packer must not silently guess whether the copy is a rename, clone, or replacement;
- resolution must happen through explicit user action or future dedicated workflows.
Invariants and Constraints
The following invariants now apply:
- One managed asset equals one asset root.
- One managed asset root contains exactly one anchor
asset.json. index.jsonis the authoritative managed registry.asset.jsonis the authoritative asset-local declaration.asset_idis stable, monotonic, and non-recycled.asset_uuidis stable across relocation.- Path and display name are mutable and not primary identity.
- Orphan
asset.jsondeclarations are diagnosable but not build-active. - Copy-induced identity collisions are explicit errors, not heuristic reconciliation cases.
Explicit Non-Decisions
This decision does not yet define:
- the detailed schema of
asset.json; - the field-level boundary between common asset declaration and format-specific declaration;
- CLI or Studio service APIs;
- detailed adoption UX;
- detailed garbage collection and quarantine behavior;
- runtime artifact formats such as
assets.pa.
Those belong to later decisions and specs.
Propagation Targets
This decision must propagate to:
- packer workspace and control files specs;
- packer managed asset and identity specs;
- packer registry consistency and diagnostics specs;
- future Studio service contracts for adoption, registration, move, rename, and inspection;
- future implementation of registry persistence and identity allocation.
Validation Notes
Example: grouped atlas asset
assets/
ui_atlas/
asset.json
sprites/
confirm.png
cancel.png
palettes/
ui_main.pal
This is one managed asset, not many.
The internal files are inputs of the asset root declared by asset.json.
Example: relocation
assets/ui_atlas/moves toassets/ui/common_atlas/asset_idremains the sameasset_uuidremains the same- only the registered root path changes
Example: orphan anchor
assets/wip/new_bank/asset.jsonexists- no corresponding registry entry exists in
index.json - the asset is diagnosable and adoptable, but not part of the managed build set