197 lines
12 KiB
Markdown
197 lines
12 KiB
Markdown
---
|
|
id: AGD-0008
|
|
ticket: pbs-low-level-asset-manager-surface
|
|
title: PBS Low-Level Asset Manager Surface for Runtime AssetManager
|
|
status: accepted
|
|
created: 2026-03-27
|
|
resolved: 2026-03-27
|
|
decision: DEC-0004
|
|
tags: [compiler, pbs, runtime, asset-manager, host-abi, stdlib, asset]
|
|
---
|
|
|
|
## 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:
|
|
|
|
1. o runtime ja publica a familia de syscalls `asset.load`, `asset.status`, `asset.commit` e `asset.cancel`;
|
|
2. o `AssetBridge`/`AssetManager` ja carregam semantica real de slots, handles, lifecycle e status-first;
|
|
3. o SDK PBS ainda nao declara o owner low-level equivalente;
|
|
4. a agenda `AGD-0006` discute a superficie simbolica author-facing e o lowering de `Addressable` para 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 Assets` ergonomico;
|
|
- 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-arch` se 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.rs` publica `module = "asset"` com `load`, `status`, `commit` e `cancel`;
|
|
- `../runtime/docs/specs/runtime/15-asset-management.md` fixa o MVP syscall shape como:
|
|
- `asset.load(asset_id, slot) -> (status:int, handle:int)`
|
|
- `asset.status(handle) -> status:int`
|
|
- `asset.commit(handle) -> status:int`
|
|
- `asset.cancel(handle) -> status:int`
|
|
- `../runtime/crates/console/prometeu-hal/src/asset_bridge.rs` agora expõe `load(&self, asset_id: AssetId, slot_index: usize) -> Result<HandleId, AssetLoadError>`;
|
|
- `../runtime/docs/specs/runtime/16-host-abi-and-syscalls.md` reforca que o caller nao fornece `asset_name` nem `bank_type`;
|
|
- `../runtime/docs/vm-arch/ISA_CORE.md` e `../runtime/docs/vm-arch/ARCHITECTURE.md` ja tratam o stack contract canonico como `asset_id, slot -> status, handle`;
|
|
- o mesmo runtime spec usa `asset_id` como chave normativa para preload.
|
|
|
|
No workspace atual, isso elimina a ambiguidade antiga do lado runtime:
|
|
|
|
1. o runtime low-level ja convergiu para `asset_id + slot`;
|
|
2. preload/bootstrap e `asset_table` usam a mesma identidade;
|
|
3. 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:
|
|
|
|
- `log` usa `declare host LowLog` como owner bruto e `declare service Log` como fachada ergonomica;
|
|
- `gfx` usa `declare host LowGfx` e `declare service Gfx` no mesmo padrao;
|
|
- `input` nao 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 `asset` que 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 `../runtime` is still `module = "asset"` and `name = "load"`;
|
|
- the substantive update is the argument contract, now `asset_id, slot`, not `asset_name, kind, slot`.
|
|
- the canonical capability name checked on 2026-03-27 is also `asset` in 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.
|
|
|
|
## 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 `load` em PBS low-level como `int asset_id` cru, 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 `Addressable` para uma camada superior, ou deve nascer ja preparado para metadata reservada de asset lowering?
|
|
- [ ] Como representar `slot` na interface PBS: `int` cru, nominal `SlotIndex`, ou algum wrapper pequeno que continue baixando para o mesmo slot integer da ABI?
|
|
- [ ] Devemos refletir normativamente que `bank kind` nao e mais argumento publico de `asset.load`, porque o runtime o deriva de `asset_table`?
|
|
- [ ] `handle` deve ser um `int` cru no MVP, ou um builtin/nominal type dedicado para evitar mistura acidental com outros ids?
|
|
- [ ] Os status de `load`, `status`, `commit` e `cancel` devem ficar como `int` cru no low-level, ou o SDK PBS deve declarar enums dedicados desde o inicio?
|
|
- [ ] `bank_info` e `slot_info`, que existem no runtime como modulo `bank`, 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 um `declare service Assets` opcional depois, seguindo `log/gfx`?
|
|
- [ ] A agenda deve assumir como principio que PBS nunca fala diretamente com `AssetManager`, e sim apenas com a ABI `module/name/version` publicada 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 host` que reflita exatamente `asset.load(asset_id, slot)`, `asset.status(handle)`, `asset.commit(handle)` e `asset.cancel(handle)`, usando `int` cru 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`, `slot` e `handle`.
|
|
- **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 para `asset_id`, `handle`, `slot` e 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 `int` solto 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 `Assets` baseada em `Addressable`/`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/gfx` evitaram 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:
|
|
|
|
1. `log` e `gfx` ja mostraram um padrao util: owner low-level explicito via `declare host`, opcionalmente embrulhado por `declare service`;
|
|
2. `input` reforca 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";
|
|
3. a agenda `AGD-0006` precisa de uma base concreta onde o lowering author-facing possa cair;
|
|
4. o runtime ja tem ABI publicada para `asset`, entao PBS nao deve inventar uma forma paralela nem falar com `AssetManager` de forma privilegiada;
|
|
5. 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;
|
|
6. ainda assim, espelhar apenas `int/int/int` sem 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 `Addressable` or symbolic authoring, that should lower into `asset_id` before the final host call;
|
|
- the low-level owner should be designed around the runtime contract that actually exists now, not around the retired `asset_name` surface.
|
|
|
|
Current convergence already accepted in discussion:
|
|
|
|
1. the low-level PBS owner name should be `LowAssets`;
|
|
2. the first PBS low-level surface should keep `int` raw for `asset_id` and `slot`;
|
|
3. the declaration shape should be `declare host LowAssets { ... }`;
|
|
4. capability spelling should remain `asset`, not `assets`, to preserve alignment with the runtime capability and syscall registries even if the PBS owner type is pluralized.
|
|
|
|
Illustrative direction:
|
|
|
|
```pbs
|
|
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 em `asset_id`.
|
|
|
|
## Resolution
|
|
|
|
Accepted on 2026-03-27.
|
|
|
|
Locked points:
|
|
|
|
1. the low-level PBS owner is `LowAssets`;
|
|
2. the low-level declaration shape is `declare host LowAssets { ... }`;
|
|
3. the runtime binding stays on `module = "asset"` with capability `asset` in the singular;
|
|
4. v1 keeps raw `int` for `asset_id`, `slot`, `handle`, and status values;
|
|
5. any future symbolic author-facing asset surface must lower into this runtime-aligned low-level contract.
|