prometeu-studio/discussion/workflow/decisions/DEC-0004-pbs-low-level-asset-manager-surface.md

6.6 KiB

id ticket title status created accepted agenda plans tags
DEC-0004 pbs-low-level-asset-manager-surface PBS Low-Level Asset Manager Surface for Runtime AssetManager accepted 2026-03-27 2026-03-27 AGD-0008
PLN-0004
compiler
pbs
runtime
asset-manager
host-abi
stdlib
asset

Decision

PBS SHALL expose the runtime asset low-level surface through a reserved host-backed owner named LowAssets.

The canonical v1 PBS declaration owner SHALL be:

declare host LowAssets { ... }

This owner name is editorial PBS surface only. It MUST NOT change the canonical runtime identities published by ../runtime.

The low-level PBS asset surface SHALL bind to the current runtime syscall identities:

  • ("asset", "load", 1)
  • ("asset", "status", 1)
  • ("asset", "commit", 1)
  • ("asset", "cancel", 1)

The capability spelling for this surface SHALL be asset, in the singular:

[Capability(name = "asset")]

PBS SHALL NOT publish assets as the capability string for this low-level surface.

For v1, the low-level PBS surface SHALL use raw int for:

  • asset_id
  • slot
  • handle
  • operation and lifecycle status values

The canonical illustrative shape is:

declare host LowAssets {
  [Host(module = "asset", name = "load", version = 1)]
  [Capability(name = "asset")]
  fn load(asset_id: int, slot: int) -> (status: int, loading_handle: int);

  [Host(module = "asset", name = "status", version = 1)]
  [Capability(name = "asset")]
  fn status(loading_handle: int) -> int;

  [Host(module = "asset", name = "commit", version = 1)]
  [Capability(name = "asset")]
  fn commit(loading_handle: int) -> int;

  [Host(module = "asset", name = "cancel", version = 1)]
  [Capability(name = "asset")]
  fn cancel(loading_handle: int) -> int;
}

Rationale

This decision locks the low-level PBS surface to the runtime contract that actually exists in the workspace on 2026-03-27.

The runtime side has already converged on:

  • asset.load(asset_id, slot) -> (status, handle)
  • asset.status(handle) -> status
  • asset.commit(handle) -> status
  • asset.cancel(handle) -> status

The earlier name-based low-level load path is no longer the active runtime contract. PBS SHOULD therefore stop treating that retired shape as a first-class candidate.

LowAssets was chosen instead of LowAsset or LowAssetManager because:

  • it reads naturally beside higher-level surfaces such as a future Assets facade;
  • it matches the user-facing plurality of the domain without changing runtime ABI identities;
  • it keeps the source declaration owner concise.

Raw int was chosen for v1 because:

  • the runtime ABI is slot-based and already integer-shaped;
  • the immediate need is to publish a stable low-level bridge, not a richer type taxonomy;
  • delaying the SDK interface until nominal wrappers are designed would block spec and implementation progress without changing executable semantics.

Capability spelling remains singular asset because capability names are operational registry identities, not editorial surface names. They MUST stay aligned with the runtime capability map.

Technical Specification

1. Ownership And Binding

  • PBS low-level asset access MUST be declared through declare host LowAssets.
  • Each member MUST carry a canonical [Host(module = "asset", name = "...", version = 1)] attribute.
  • Each member MUST carry [Capability(name = "asset")].
  • PBS compilers and loaders MUST treat module, name, version, argument slots, return slots, and capability spelling as runtime-facing operational identity.

2. ABI Shape

The required v1 members are:

  1. load(asset_id: int, slot: int) -> (status: int, loading_handle: int)
  2. status(loading_handle: int) -> int
  3. commit(loading_handle: int) -> int
  4. cancel(loading_handle: int) -> int

Normative ABI correspondence:

  • load MUST lower to runtime syscall identity ("asset", "load", 1) with arg_slots = 2 and ret_slots = 2.
  • status MUST lower to ("asset", "status", 1) with arg_slots = 1 and ret_slots = 1.
  • commit MUST lower to ("asset", "commit", 1) with arg_slots = 1 and ret_slots = 1.
  • cancel MUST lower to ("asset", "cancel", 1) with arg_slots = 1 and ret_slots = 1.

3. Value Semantics

  • asset_id SHALL represent the runtime asset identity carried by asset_table.
  • slot SHALL represent the target runtime slot index.
  • handle SHALL represent the runtime load-operation handle returned by load when status is OK.
  • PBS source signatures SHOULD use a non-keyword parameter label such as loading_handle for this value.
  • status values SHALL remain raw integer domain values in the low-level surface for v1.

PBS low-level callers MUST NOT pass:

  • asset_name
  • bank_type
  • any alternate symbolic asset reference directly to LowAssets.load

The runtime resolves bank kind from asset_table using asset_id. PBS low-level surface MUST preserve that rule.

4. Relationship To Higher-Level Surfaces

  • This decision defines only the low-level host-backed asset surface.
  • It does NOT define the final author-facing asset API.
  • Any future symbolic PBS asset surface, including Addressable or assets.foo.bar style references, MUST lower to asset_id before the final LowAssets.load(...) host call.
  • A future declare service Assets MAY wrap LowAssets, but such facade MUST NOT alter the canonical host identities defined here.

5. Scope Boundary

This decision covers:

  • the low-level owner name;
  • capability spelling;
  • canonical host bindings;
  • raw value shape for v1.

This decision does NOT yet cover:

  • nominal wrapper types for AssetId, Handle, or SlotIndex;
  • enum surfaces for asset status values;
  • bank.info / bank.slot_info integration;
  • the author-facing symbolic assets surface from AGD-0006.

Constraints

  • PBS MUST stay aligned with the runtime capability registry and syscall registry as implemented in ../runtime.
  • PBS MUST NOT publish a plural capability string assets for this surface.
  • PBS MUST NOT reintroduce a name-based low-level load contract into the canonical v1 PBS host surface.
  • Any future editorial refinement to stronger low-level types MUST preserve the same runtime syscall identities unless a new decision explicitly revises this one.
  • Plans and implementation derived from this decision MUST propagate updates to PBS specs and stdlib resources before introducing user-facing wrappers.

Revision Log

  • 2026-03-27: Initial accepted decision from AGD-0008.
  • 2026-03-27: Linked execution plan PLN-0004.
  • 2026-03-27: Refined illustrative PBS signatures to use named tuple returns and non-keyword handle labels without changing the locked runtime contract.