12 KiB
| id | ticket | title | status | created | resolved | decision | tags | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| AGD-0008 | pbs-low-level-asset-manager-surface | PBS Low-Level Asset Manager Surface for Runtime AssetManager | accepted | 2026-03-27 | 2026-03-27 | DEC-0004 |
|
Pain
PBS ainda nao tem uma superficie low-level explicita para operar o AssetManager do ../runtime, apesar de ja existir um contrato host-backed claro para outras areas como log e gfx, e uma superficie VM-owned consolidada para input.
Hoje isso deixa uma lacuna pratica:
- o runtime ja publica a familia de syscalls
asset.load,asset.status,asset.commiteasset.cancel; - o
AssetBridge/AssetManagerja carregam semantica real de slots, handles, lifecycle e status-first; - o SDK PBS ainda nao declara o owner low-level equivalente;
- a agenda
AGD-0006discute a superficie simbolica author-facing e o lowering deAddressablepara identidade estavel, mas nao fecha o shape minimo do contrato host-backed bruto que deve existir por baixo.
Sem essa camada low-level bem definida, o proximo passo fica mais dificil:
- nao existe base clara para um futuro
declare service Assetsergonomico; - nao existe alvo normativo preciso para o frontend PBS validar e lowerar;
- mesmo com o runtime agora convergido para
asset_id, PBS ainda precisa decidir qual shape low-level publicar no SDK e como nomear/encapsular esse contrato.
Context
Domain owner:
compiler/pbs
Referenced domains:
runtime- possivelmente
vm-archse a discussao tocar contrato transversal de handles/status layout
O runtime ja fornece evidencia concreta para esta discussao:
../runtime/crates/console/prometeu-hal/src/syscalls/domains/asset.rspublicamodule = "asset"comload,status,commitecancel;../runtime/docs/specs/runtime/15-asset-management.mdfixa o MVP syscall shape como:asset.load(asset_id, slot) -> (status:int, handle:int)asset.status(handle) -> status:intasset.commit(handle) -> status:intasset.cancel(handle) -> status:int
../runtime/crates/console/prometeu-hal/src/asset_bridge.rsagora expõeload(&self, asset_id: AssetId, slot_index: usize) -> Result<HandleId, AssetLoadError>;../runtime/docs/specs/runtime/16-host-abi-and-syscalls.mdreforca que o caller nao forneceasset_namenembank_type;../runtime/docs/vm-arch/ISA_CORE.mde../runtime/docs/vm-arch/ARCHITECTURE.mdja tratam o stack contract canonico comoasset_id, slot -> status, handle;- o mesmo runtime spec usa
asset_idcomo chave normativa para preload.
No workspace atual, isso elimina a ambiguidade antiga do lado runtime:
- o runtime low-level ja convergiu para
asset_id + slot; - preload/bootstrap e
asset_tableusam a mesma identidade; - a tensao restante agora esta quase toda do lado PBS, que ainda precisa conectar essa ABI crua com a futura superficie simbolica discutida em
AGD-0006.
Os exemplos existentes no SDK PBS ajudam a enquadrar a forma esperada:
logusadeclare host LowLogcomo owner bruto edeclare service Logcomo fachada ergonomica;gfxusadeclare host LowGfxedeclare service Gfxno mesmo padrao;inputnao usa host ABI, porque ja foi modelado como builtin VM-owned, entao ele serve mais como contraexemplo util do que como template direto.
O que esta discussion precisa responder nao e "como o jogo vai referenciar assets de forma simpatica". Essa parte ja esta sendo discutida em outra agenda.
O foco aqui e mais baixo nivel:
- qual contrato PBS deve declarar para falar com a superficie
assetque o runtime ja resolve por host ABI; - quais tipos/status/handles/slots precisam existir no SDK/interface module;
- onde a fronteira entre espelho fiel do runtime atual e normalizacao futura deve ser colocada.
Clarification:
- despite the user shorthand "assets.load", the concrete runtime surface checked on 2026-03-27 in
../runtimeis stillmodule = "asset"andname = "load"; - the substantive update is the argument contract, now
asset_id, slot, notasset_name, kind, slot. - the canonical capability name checked on 2026-03-27 is also
assetin the singular:- runtime caps publish
ASSET; - runtime cartridge capability mapping uses
"asset" -> ASSET; - PBS capability spelling examples follow singular names such as
"gfx"and should stay aligned with the runtime capability registry.
- runtime caps publish
Open Questions
- Qual deve ser o owner low-level em PBS:
LowAsset,LowAssets,LowAssetManager, ou outro naming alinhado ao padrao existente? - A primeira versao do contrato PBS deve espelhar exatamente o runtime atual (
asset.load(asset_id, slot)), ou ainda vale esconder parte disso atras de wrappers nominais mais fortes? - Devemos modelar a entrada de
loadem PBS low-level comoint asset_idcru, como um nominal type dedicado (AssetId), ou como um builtin reservado com semantica de runtime id? - O baixo nivel deve assumir apenas o ABI do runtime publicado hoje, deixando qualquer lowering de
Addressablepara uma camada superior, ou deve nascer ja preparado para metadata reservada de asset lowering? - Como representar
slotna interface PBS:intcru, nominalSlotIndex, ou algum wrapper pequeno que continue baixando para o mesmo slot integer da ABI? - Devemos refletir normativamente que
bank kindnao e mais argumento publico deasset.load, porque o runtime o deriva deasset_table? handledeve ser umintcru no MVP, ou um builtin/nominal type dedicado para evitar mistura acidental com outros ids?- Os status de
load,status,commitecanceldevem ficar comointcru no low-level, ou o SDK PBS deve declarar enums dedicados desde o inicio? bank_infoeslot_info, que existem no runtime como modulobank, fazem parte da mesma discussion ou devem ficar fora do primeiro recorte do asset low-level?- O contrato PBS low-level deve cobrir somente
load/status/commit/cancel, ou tambem preparar desde ja preload/bootstrap observability e telemetry adjacentes? - A surface low-level deve ser totalmente host-backed via
declare host, com umdeclare service Assetsopcional depois, seguindolog/gfx? - A agenda deve assumir como principio que PBS nunca fala diretamente com
AssetManager, e sim apenas com a ABImodule/name/versionpublicada pelo runtime? - Qual parte desta decisao precisa propagar para specs PBS (
6.2, stdlib surface, talvez runtime capabilities) e qual parte fica apenas como implementacao de SDK/resources?
Options
Option A - Mirror The Current Runtime ABI Exactly
- Approach: declarar em PBS um
declare hostque reflita exatamenteasset.load(asset_id, slot),asset.status(handle),asset.commit(handle)easset.cancel(handle), usandointcru em todos os pontos onde a ABI hoje e inteira. - Pro: reduz risco de desalinhamento com o runtime atual e facilita implementacao incremental rapida.
- Con: empurra pouca semantica para o SDK e deixa PBS exposto a mistura acidental entre
asset_id,slotehandle. - Maintainability: media. O alinhamento ABI e forte, mas a superficie editorial continua pobre.
Option B - Publish A Low-Level PBS Surface That Is ABI-Faithful But Type-Normalized
- Approach: manter alinhamento estrito com
module = "asset"e com os nomes/version atuais, mas permitir que PBS exponha wrappers nominais/enums/structs paraasset_id,handle,slote status, desde que o lowering final preserve o ABI publicado. - Pro: segue o padrao de
log/gfx, melhora legibilidade do SDK e deixa o compiler com um alvo mais seguro sem esconder que a ownership continua no runtime ABI. - Con: exige decidir cedo quais normalizacoes de tipo sao so editoriais e quais ja implicam semantica nova.
- Maintainability: alta. A ABI continua estavel, mas a superficie PBS nao precisa ficar presa a
intsolto para sempre.
Option C - Skip The Raw Surface And Design Only The Author-Facing Assets API
- Approach: postergar a definicao low-level e discutir apenas a futura fachada
Assetsbaseada emAddressable/asset_id, deixando o contrato host-backed implicito por enquanto. - Pro: conversa mais proxima da experiencia do autor de jogo.
- Con: deixa o pipeline sem camada de base; mistura decisao ergonomica com decisao de ABI; repete exatamente o tipo de ambiguidade que
log/gfxevitaram ao separar owner bruto de fachada. - Maintainability: baixa. A implementacao tendera a inventar detalhes sem uma superficie canonica intermediaria.
Discussion
No estado atual, a direcao mais coerente parece ser a Option B.
Motivos:
logegfxja mostraram um padrao util: owner low-level explicito viadeclare host, opcionalmente embrulhado pordeclare service;inputreforca que nem toda superficie do SDK precisa ser host-backed, entao esta agenda deve ser cuidadosa para nao confundir "API de jogo" com "contrato ABI";- a agenda
AGD-0006precisa de uma base concreta onde o lowering author-facing possa cair; - o runtime ja tem ABI publicada para
asset, entao PBS nao deve inventar uma forma paralela nem falar comAssetManagerde forma privilegiada; - o runtime recente removeu a maior parte da ambiguidade de carga ao convergir para
asset_id + slot, entao a agenda PBS pode ficar mais assertiva e menos especulativa; - ainda assim, espelhar apenas
int/int/intsem nenhuma disciplina editorial empurra custo cognitivo desnecessario para o SDK e para os testes do compiler.
O principal cuidado e separar dois eixos:
- fidelidade ABI:
module,name,version, aridade e retorno precisam permanecer alinhados ao runtime;
- editorial/type shape em PBS:
- wrappers nominais, enums ou pequenos value types podem ser aceitaveis se o lowering terminar no mesmo contrato host-backed.
The recent runtime change also sharpens the recommendation:
- this agenda no longer needs to entertain a name-based low-level path as a first-class candidate;
- if PBS wants
Addressableor symbolic authoring, that should lower intoasset_idbefore the final host call; - the low-level owner should be designed around the runtime contract that actually exists now, not around the retired
asset_namesurface.
Current convergence already accepted in discussion:
- the low-level PBS owner name should be
LowAssets; - the first PBS low-level surface should keep
intraw forasset_idandslot; - the declaration shape should be
declare host LowAssets { ... }; - capability spelling should remain
asset, notassets, to preserve alignment with the runtime capability and syscall registries even if the PBS owner type is pluralized.
Illustrative direction:
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;
}
This keeps one deliberate naming asymmetry:
- source owner:
LowAssets - runtime module/capability:
asset
That asymmetry looks acceptable because source declaration ownership is editorial, while module/name/version and capability strings are operational identities that must stay runtime-aligned.
Tambem parece importante explicitar o limite desta agenda:
- ela nao deve fechar a politica author-facing completa de asset references;
- ela deve produzir um alvo low-level suficiente para que a proxima decision possa dizer como
Assets.load(assets.foo.bar, slot)baixa para a chamada host-backed final baseada emasset_id.
Resolution
Accepted on 2026-03-27.
Locked points:
- the low-level PBS owner is
LowAssets; - the low-level declaration shape is
declare host LowAssets { ... }; - the runtime binding stays on
module = "asset"with capabilityassetin the singular; - v1 keeps raw
intforasset_id,slot,handle, and status values; - any future symbolic author-facing asset surface must lower into this runtime-aligned low-level contract.