clean up and update docs (agenda, decisions, PRs, learn and specs)

This commit is contained in:
bQUARKz 2026-03-16 18:17:45 +00:00
parent d5eb5cf033
commit 03494c8cd7
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
11 changed files with 62 additions and 964 deletions

View File

@ -1,26 +0,0 @@
# Agenda 011 - VM-Owned Stateful Core (Fechada)
## Status
Fechada pela decisao:
- `../decisions/006-vm-owned-stateful-core-contract.md`
## O Que Foi Fechado
1. Modelo canonico com `HeapRef<TBuiltinState>` e regra anti-stale por generation.
2. Lifecycle minimo (`create/read-update/destroy`) para servicos stateful.
3. Manutencao do caminho `INTRINSIC <id_final>` sem tabela adicional.
4. Metadata obrigatoria por operacao (`arg_slots`, `ret_slots`, efeito, determinismo, custo).
5. Fronteira de fault (`status` operacional, `Trap` estrutural, `Panic` interno).
6. Direcao de verifier/disasm/compatibilidade binaria para intrinsic stateful.
## Efeito Pratico
- Agenda `012` passa a consumir essa base para fechar random.
- Implementacoes VM-owned stateful devem seguir a decisao `006` como contrato.
## Follow-up
- consolidar implementacao de identity/registry de intrinsic no frontend/backend/runtime;
- fechar random em `012-vm-owned-random-service.md`.

View File

@ -1,29 +0,0 @@
# Agenda 024 - `assets.pa` Preload and Asset Table ID-based Contract (Fechada)
## Status
Fechada pela decisao:
- `../decisions/012-assets-preload-asset-id-contract.md`
## O Que Foi Fechado
1. `PreloadEntry` deixa de usar `asset_name` e passa a ser normativamente `{ asset_id, slot }`.
2. `asset_id` passa a ser o identificador operacional de preload com semantica de `java int`.
3. `asset_name` permanece apenas como metadata descritiva/debug e nao participa do preload.
4. `preload` deve ser validado contra a `asset_table` do proprio `assets.pa` durante o bootstrap.
5. `asset_id` ausente da `asset_table` e clash de slot por tipo caracterizam erro estrutural de formacao do cart.
6. Nao existe compatibilidade normativa para preload legado por `asset_name`.
## Efeito Pratico
- `spec 15` passa a precisar explicitar o shape normativo de `PreloadEntry` e a validacao estrutural de preload.
- loader, parser de `assets.pa` e `AssetManager` passam a consumir preload por `asset_id`.
- a modelagem atual em codigo baseada em `u32` para `asset_id` precisa ser revisitada onde o contrato exposto ainda assume unsigned.
## Follow-up
- propagar a decisao em `specs 13/15`;
- criar suporte de parse/validacao estrutural para preload por `asset_id`;
- remover o preload por `asset_name` do runtime e dos testes;
- manter `asset.load(name, kind, slot)` inalterado ate decisao futura sobre a superficie VM-facing.

View File

@ -1,153 +0,0 @@
# Decision Record - VM-Owned Byte Transfer Protocol
## Status
Accepted
## Contexto
O runtime precisa de um protocolo canonico para trafegar bytes entre host e userland sem:
- converter payload binario em `String`;
- devolver handles host-owned;
- inventar formatos ad hoc por dominio.
O estado atual relevante e:
- a heap ja possui `ObjectKind::Bytes`;
- o runtime ja consegue armazenar payload binario bruto na heap;
- `Value` ainda nao possui `Byte`;
- a spec de valores ainda nao reconhece `byte` como valor primitivo;
- `HostReturn` ainda modela apenas empilhar valores na stack;
- `fs` e o futuro data bank precisarao trafegar bytes pela borda host <-> guest.
O projeto tambem ja fixou que:
- syscalls usam stack;
- o host nao devolve handles opacos;
- o host nao devolve memoria host-owned;
- banks de hardware trafegam IDs, nao bytes;
- nao ha backward compatibility.
## Decisao
### 1. Tipo base
- O runtime passa a exigir `Value::Byte` como valor primitivo real.
- A spec de valores deve ser atualizada para incluir `byte`.
### 2. Buffer canonico
- O buffer canonico de bytes da VM e `HeapRef(Byte)`.
- `HeapRef(Byte)` significa um `HeapRef` cujo objeto alvo e `ObjectKind::Bytes`.
- Nao sera introduzido mecanismo paralelo para buffer binario.
### 3. Nomes canonicos
- `src` = origem dos bytes.
- `dst` = destino dos bytes.
- `src_ref`/`dst_ref` = handle VM-owned para buffer de bytes.
- `src_offset`/`dst_offset` = offset no buffer da VM.
- `host_handle` = identificador opaco do lado host.
- `host_offset` = offset do lado host.
- `max_bytes` = quantidade maxima pedida para a operacao.
- `bytes_transferred` = quantidade efetivamente transferida.
### 4. Domain ops iniciais
Os dois domain ops iniciais deste protocolo sao:
- `read`: host -> VM
- `write`: VM -> host
### 5. Assinatura canonica de `read`
`read` deve seguir este formato:
```text
read(host_handle, host_offset, dst_ref, dst_offset, max_bytes) -> (status, bytes_transferred, eof)
```
Regras:
- `status` e `bytes_transferred` sao inteiros;
- `eof` e booleano;
- `dst_ref` deve apontar para `HeapRef(Byte)`;
- `read` parcial pode ser sucesso;
- `eof` representa fim/exaustao observada no lado host.
### 6. Assinatura canonica de `write`
`write` deve seguir este formato:
```text
write(host_handle, host_offset, src_ref, src_offset, max_bytes) -> (status, bytes_transferred)
```
Regras:
- `status` e `bytes_transferred` sao inteiros;
- `src_ref` deve apontar para `HeapRef(Byte)`;
- `write` parcial e falha.
### 7. Janela explicita de transferencia
Toda operacao atua sobre uma janela explicita da heap da VM:
- `read` escreve em `dst_ref[dst_offset .. dst_offset + max_bytes)`;
- `write` le de `src_ref[src_offset .. src_offset + max_bytes)`.
### 8. Politica de falha
- Esta decisao define o data plane de bytes, nao a taxonomia final de faults por dominio.
- Condicoes operacionais devem retornar `status`.
- Violacoes estruturais de chamada/ABI seguem `16a` e a decisao de fault policy do dominio.
- Para `fs`, a classificacao normativa esta na decisao `007-filesystem-fault-core-policy.md`.
### 9. API minima necessaria na VM
Para suportar este protocolo, a VM precisa expor API canonica para:
- alocar buffer de bytes VM-owned;
- validar se um `HeapRef` aponta para `ObjectKind::Bytes`;
- expor comprimento/capacidade relevantes;
- escrever bytes em faixa valida;
- ler bytes em faixa valida.
## Consequencias
### Positivas
- `fs` e data bank passam a compartilhar o mesmo protocolo estrutural.
- A borda host <-> guest deixa de depender de texto para payload binario.
- O host nao precisa alocar memoria propria para devolver bytes.
- O guest passa a controlar explicitamente buffer, janela e interpretacao do payload.
### Custos
- `Value` e a spec de valores precisam mudar.
- A heap precisa de API publica mais util para `Bytes`.
- `HostReturn` e a camada host-backed precisam acomodar o protocolo sem atalhos.
- Dominios como `fs` ainda precisam decidir suas semanticas funcionais sobre este protocolo.
## Fora de Escopo
- API funcional completa de `fs`;
- API funcional do data bank;
- listas e structs retornadas pelo host;
- transporte de banks graficos/sonoros para a VM;
- input/intrinsics.
## Follow-up Obrigatorio
As seguintes agendas devem consumir esta decisao:
- `spec 08-save-memory-and-memcard.md` (historico arquitetural em `learn/historical-game-memcard-slots-surface-and-semantics.md`)
- `014-app-home-filesystem-surface-and-semantics.md`
- discussoes futuras de data bank
As seguintes specs precisarao ser atualizadas:
- `02a-vm-values-and-calling-convention.md`
- `03-memory-stack-heap-and-allocation.md`
- `16-host-abi-and-syscalls.md`

View File

@ -1,171 +0,0 @@
# Decision Record - VM-Owned Stateful Core Contract
## Status
Accepted
## Contexto
O runtime ja possui intrinsics VM-owned read-only (input), mas faltava um contrato canonico para recursos VM-owned stateful.
Sem esse contrato, cada dominio novo tende a divergir em:
- referencia/handle;
- lifecycle;
- shape de ABI por operacao;
- politica de fault/status;
- validacao de verifier/disasm.
## Decisao
### 1. Fronteira host-backed permanece inalterada
- `HOSTCALL`/`SYSCALL` continuam sendo o caminho host-backed.
- Esta decisao nao introduz redesign de host boundary.
### 2. Modelo canonico de recurso stateful
- Recurso stateful VM-owned e representado por `HeapRef<TBuiltinState>`.
- Validade da referencia segue `index + generation` (anti-stale).
- Nao sera introduzido, nesta etapa, um modelo paralelo de handle numerico tipado.
### 3. Lifecycle minimo obrigatorio
Todo dominio stateful deve explicitar:
- `create`;
- `read/query`;
- `update`;
- `destroy`.
### 4. Forma de invocacao
- O caminho de execucao permanece `INTRINSIC <id_final>`.
- Nao ha tabela adicional de pre-load para VM-owned stateful.
- IDs finais continuam versionados por operacao.
### 5. Metadata canonica por operacao intrinsic stateful
Cada operacao deve declarar, no minimo:
- `arg_slots`;
- `ret_slots`;
- `effect` (read/create/update/destroy);
- `determinism`;
- `may_allocate`;
- `cost_hint`.
### 6. Fault model para VM-owned stateful
- `Trap` para erro estrutural (shape de chamada invalido, stale handle, kind invalido).
- `status` para falha operacional de dominio.
- `Panic` apenas para inconsistencia interna do runtime.
### 7. GC/lifetime e aliasing
- Recursos stateful vivem na heap VM e seguem roots normais de GC.
- `destroy` existe para encerramento explicito quando o dominio exigir.
- Multipla referencia para o mesmo recurso nao muda semantica de ownership; validade segue regras de `HeapRef`.
### 8. Verifier/toolchain/disasm
- Verifier deve validar assinatura (`arg_slots`/`ret_slots`) e identidade da operacao.
- Disasm deve expor identidade canonica (nome + versao), nao apenas id numerico.
- Mudanca breaking exige nova versao da operacao.
### 9. Compatibilidade binaria
- Mesma versao de operacao nao muda contrato de slots nem efeito.
- Operacao inexistente/incompativel deve falhar em carga/verificacao.
## Estado Atual do Frontend PBS (Studio)
Estado observado:
- SDK interface ja modela VM-owned builtin surfaces com `declare builtin type` + `IntrinsicCall`.
- Lowering ja emite `CALL_INTRINSIC` e pipeline ja converte para opcode `INTRINSIC`.
Lacunas relevantes para stateful:
- resolucao de intrinsic no frontend ainda e indexada por `sourceMethodName` simples;
- ids de intrinsic no frontend ainda usam `hash(canonicalName#version)` como placeholder.
Direcao exigida por esta decisao:
- resolucao de intrinsic deve considerar identidade canonica sem ambiguidade de receiver;
- ids finais de intrinsic devem vir de registry canonico FE/backend/runtime, nao de hash provisoria.
## Exemplos (Ilustrativos, nao normativos)
### Exemplo A - Surface de SDK para random stateful na PBS
```text
[BuiltinType(name = "random", version = 1)]
declare builtin type Random() {
[IntrinsicCall(name = "new", version = 1)]
fn new(seed: int) -> RandomRng;
}
[BuiltinType(name = "random.rng", version = 1)]
declare builtin type RandomRng() {
[IntrinsicCall(name = "next", version = 1)]
fn next() -> int;
[IntrinsicCall(name = "destroy", version = 1)]
fn destroy() -> int; // status
}
[BuiltinConst(target = "random", name = "global", version = 1)]
declare const Random: Random;
```
### Exemplo B - Uso em userland PBS
```text
import { Random } from @sdk:random;
fn tick() -> void {
let rng = Random.new(12345);
let a = rng.next();
let b = rng.next();
let _s = rng.destroy();
}
```
### Exemplo C - Contraste de lowering
```text
CALL_INTRINSIC random.new@1
CALL_INTRINSIC random.rng.next@1
CALL_INTRINSIC random.rng.destroy@1
```
No bytecode final:
```text
INTRINSIC <id_random_new_v1>
INTRINSIC <id_random_rng_next_v1>
INTRINSIC <id_random_rng_destroy_v1>
```
## Consequencias
### Positivas
- cria base unica para dominios stateful VM-owned;
- evita proliferacao de protocolos ad hoc por servico;
- preserva fronteira host-backed atual;
- prepara random como primeiro consumidor sem redesenho posterior.
### Custos
- exige evolucao de registry/identity de intrinsic no frontend/backend;
- exige endurecimento de verifier/disasm para contrato stateful;
- exige disciplina de versionamento por operacao.
## Follow-up Obrigatorio
- agenda `011-vm-owned-stateful-core.md` deve ser considerada fechada por esta decisao;
- agenda `012-vm-owned-random-service.md` passa a ser o primeiro consumidor desta base;
- specs `16`/`16a` devem absorver o contrato stateful quando a implementacao ficar estavel.

View File

@ -1,98 +0,0 @@
# Decision Record - Filesystem Fault Core Policy
## Status
Accepted
## Contexto
A agenda `003-filesystem-fault-semantics.md` existia para fechar fault semantics de `fs` depois das discussoes de superficie.
Com o split de `fs` em:
- `spec 08` (`game` memcard slots);
- agenda `014` (`app` home sandbox);
ficou claro que:
- existe um nucleo de politica que pode ser decidido agora;
- os detalhes por perfil devem ser fechados no contrato de `game` e no de `app`.
Isso permite remover a agenda `003` sem perder rigor.
## Decisao
### 1. Fronteira canonica de falhas para `fs`
`fs` segue o modelo de `16a`:
- `Trap`: violacao estrutural de contrato ABI/chamada.
- `status`: condicao operacional de dominio.
- `Panic`: quebra de invariante interno do runtime/host.
### 2. O que e estrutural (`Trap`) em `fs`
No dominio `fs`, sao estruturais:
- assinatura de chamada invalida (`arg_slots`/`ret_slots`);
- `HeapRef` invalido/dead;
- kind de objeto incompativel para a operacao;
- janela de bytes invalida (offset/length fora do buffer VM-owned).
### 3. O que e operacional (`status`) em `fs`
Sao operacionais (nao estruturais):
- recurso ausente (`not found`/slot vazio quando aplicavel);
- permissao/sandbox negada;
- `storage full`;
- indisponibilidade temporaria do backend;
- conflitos/corrupcao detectados no dominio.
### 4. Integracao obrigatoria com decisao `003`
Operacoes de bytes em `fs` devem usar:
- `HeapRef<Bytes>` VM-owned;
- janela explicita (`offset` + `max_bytes`);
- retorno com `status` e `bytes_transferred` quando aplicavel.
### 5. Regra de escrita parcial
`write` nao pode produzir sucesso parcial silencioso.
Se o dominio nao conseguir concluir a escrita segundo seu contrato de atomicidade:
- retorna `status` de falha;
- nao mascara o resultado como sucesso.
### 6. Responsabilidade por perfil (movida para `spec 08` e agenda `014`)
Fica sob responsabilidade das agendas de superficie:
- catalogo final de codigos `status` por operacao;
- matriz completa por operacao (`status`/`Trap`/`Panic`);
- shape final de retorno para cada operacao de cada perfil.
### 7. Encerramento da agenda `003`
A agenda `003-filesystem-fault-semantics.md` e considerada absorvida e removida.
## Consequencias
### Positivas
- elimina uma agenda transversal que atrasava fechamento;
- preserva um nucleo unico de fault policy para todo `fs`;
- deixa `game` e `app` focados nos detalhes reais de produto.
### Custos
- exige disciplina para manter a matriz de faults distribuida em duas agendas;
- exige revisao de consistencia entre `spec 08` e agenda `014` antes de PR final de implementacao.
## Follow-up Obrigatorio
- `spec 08-save-memory-and-memcard.md` fecha a matriz de fault/status do perfil `game`;
- `014-app-home-filesystem-surface-and-semantics.md` deve incluir a matriz de fault/status do perfil `app`;
- specs `16`/`16a` devem absorver esta decisao quando o contrato estiver implementado e estavel.

View File

@ -1,253 +0,0 @@
# Decision Record - `assets.pa` Autocontained Runtime Contract
## Status
Accepted
## Contexto
A agenda `023-asset-packer-runtime-facing-contract.md` existia para fechar a fronteira runtime-facing do packer de assets sem misturar essa discussao com o `shipper` do `.pmc`.
O ponto de partida atual do runtime ainda e fragmentado:
- `manifest.json` carrega `asset_table` e `preload`;
- `assets.pa` contem apenas os bytes packed de payload;
- o loader le `assets.pa` inteiro para memoria;
- o `AssetManager` mantem esse blob inteiro residente.
Ao mesmo tempo, a direcao desejada para o projeto ja esta clara:
- o `packer` continua responsavel por produzir o artefato de assets;
- o `shipper` continua responsavel por publicar `manifest.json` e montar o cart final;
- o runtime deve consumir um `assets.pa` autocontido;
- `asset_table`, `preload` e payload mantem o mesmo conteudo semantico atual;
- o que muda e onde esses artefatos vivem e como o runtime os carrega.
O alvo de hardware do PROMETEU e um handheld de baixo custo. Portanto, manter o blob inteiro de assets em RAM como regra geral nao e um baseline aceitavel.
## Decisao
### 1. `assets.pa` passa a ser o contrato runtime-facing de assets
O contrato primario de assets consumido pelo runtime passa a ser o proprio `assets.pa`.
`manifest.json` deixa de ser a superficie primaria para:
- `asset_table`;
- `preload`.
O runtime continua agnostico a como o `packer` e o `shipper` produzem artefatos auxiliares.
### 2. `assets.pa` v1 e um binario autocontido
`assets.pa` v1 deve ser estruturado como:
```text
[prelude binario fixo]
[header JSON]
[payload binario]
```
O prelude binario fixo v1 contem, no minimo:
- `magic`
- `schema_version`
- `header_len`
- `payload_offset`
Campos opcionais permitidos no prelude v1:
- `flags`
- `reserved`
- `header_checksum`
### 3. O header JSON carrega `asset_table` e `preload`
O header JSON de `assets.pa` e a estrutura que carrega:
- `asset_table`
- `preload`
Essa decisao nao redefine o conteudo semantico dessas estruturas.
Portanto:
- `AssetEntry` permanece a fonte de verdade para identidade, codec, metadata e offsets;
- `PreloadEntry` permanece um insumo de boot;
- o payload packed continua representando os bytes frios dos assets.
### 4. Offsets da `asset_table` sao relativos ao payload
Os `offset`s de `asset_table` permanecem relativos ao inicio da regiao de payload, nao ao inicio do arquivo inteiro.
Isso preserva a semantica atual do runtime e evita contaminar `AssetEntry` com detalhes do envelope externo.
O runtime resolve cada slice como:
```text
payload_base + entry.offset
```
### 5. Lifecycle de `preload` e `asset_table` no runtime
O runtime deve tratar essas duas estruturas de forma diferente:
- `preload` e dado transitorio de boot;
- `asset_table` e a fonte da verdade para resolucao e carregamento de assets.
Contrato operacional:
1. o runtime materializa `manifest.json`;
2. se `Capability::Asset` estiver presente, o runtime exige `assets.pa` valido imediatamente;
3. o runtime abre `assets.pa`, le o prelude e o header JSON;
4. o runtime materializa `asset_table` em memoria;
5. o runtime usa `preload` na fase de boot;
6. apos o boot, `preload` pode ser descartado;
7. `asset_table` permanece viva enquanto o cart estiver rodando.
### 6. Falha antecipada quando `Capability::Asset` exigir `assets.pa`
Cart sem `assets.pa` continuam validos.
Mas, se o `manifest.json` declarar `Capability::Asset`, a ausencia de `assets.pa` deve falhar o mais cedo possivel, antes da fase de preload.
Essa falha pertence ao bootstrap do cart, nao ao lifecycle de `asset.load`.
### 7. Leitura de payload deve ser sob demanda
O runtime nao deve manter o payload inteiro de `assets.pa` residente em memoria como comportamento baseline.
O contrato de leitura do runtime passa a ser baseado em uma primitiva equivalente a:
```text
open_slice(offset, size)
```
Essa primitiva abre uma view limitada para um asset dentro da regiao de payload.
### 8. Pipeline canonico de carregamento de asset
O caminho canonico de carregamento passa a ser:
```text
ROM -> open_slice -> CODEX/decode -> Bank
```
ou, quando o CODEX exigir materializacao temporaria:
```text
ROM -> open_slice -> blob temporario em memoria -> CODEX/decode -> Bank
```
O runtime nunca deve materializar o `assets.pa` inteiro apenas para suportar carregamento de asset.
### 9. `OP_MODE` de consumo do payload
O runtime deve encapsular o modo operacional de consumo do payload por asset.
Esse `OP_MODE` escolhe entre:
- leitura direta da ROM via view limitada;
- materializacao temporaria do slice em memoria.
Direcao v1:
- o `OP_MODE` e derivado do `codec`/CODEX por padrao;
- hint explicito adicional so deve ser introduzido se algum codec real admitir mais de um modo operacional viavel.
### 10. Artefatos auxiliares do packer continuam permitidos
O `packer` pode continuar emitindo artefatos auxiliares para o `shipper`, por exemplo:
- `asset_table.json`;
- relatorios de build;
- hashes;
- inventarios.
Mas esses artefatos:
- sao derivados;
- nao substituem o header interno de `assets.pa`;
- nao definem o contrato runtime-facing.
## Rationale
Esta decisao fecha a ambiguidade central da agenda `023` sem reabrir a semantica do dominio `asset`.
Ela foi escolhida porque:
- separa claramente `packer` e `shipper`;
- reduz dependencia de metadata de asset espalhada em `manifest.json`;
- preserva o shape semantico atual de `asset_table`, `preload` e payload;
- melhora a adequacao do runtime para hardware barato;
- evita carregar o blob inteiro em RAM;
- permite que codecs com diferentes necessidades de IO operem sobre a mesma fronteira de leitura.
O uso de prelude binario pequeno + header JSON foi adotado porque:
- permite localizar o header com custo fixo;
- mantem o header facil de produzir, inspecionar e depurar;
- evita transformar o payload em estrutura textual;
- reduz complexidade editorial no v1.
## Invariantes / Contrato
- `assets.pa` e o contrato runtime-facing de assets.
- `asset_table` e `preload` deixam de ser contrato primario de runtime no `manifest.json`.
- `asset_table` e carregada do header de `assets.pa` e permanece viva durante toda a execucao do cart.
- `preload` e carregado do header de `assets.pa`, usado no boot e descartavel apos a inicializacao.
- payload offsets em `AssetEntry` sao relativos ao inicio da regiao de payload.
- o runtime deve falhar cedo se `Capability::Asset` exigir `assets.pa` e o artefato nao existir.
- o runtime nao deve manter o `assets.pa` inteiro em RAM como baseline.
- o runtime deve expor leitura sob demanda por slice.
- `OP_MODE` de consumo do slice e resolvido pelo runtime a partir do `codec`/CODEX, salvo decisao futura em contrario.
- auxiliares do `packer` para o `shipper` nao tem autoridade normativa sobre o runtime.
## Impactos
### Specs
- `13-cartridge.md` deve mover `asset_table` e `preload` para dentro do contrato de `assets.pa`.
- `15-asset-management.md` deve descrever `assets.pa` como artefato autocontido, separar lifecycle de `preload` e `asset_table`, e registrar offsets relativos ao payload.
- `16-host-abi-and-syscalls.md` so precisa ser tocada se a superficie host/runtime de inicializacao de assets mudar de forma observavel.
### Runtime
- `cartridge_loader.rs` deve deixar de ler `assets.pa` inteiro para `Vec<u8>` como baseline.
- `cartridge.rs` deve parar de tratar `asset_table` e `preload` como dados vindos do `manifest`.
- o bootstrap deve checar cedo a presenca de `assets.pa` quando `Capability::Asset` estiver declarada.
- o `AssetManager` deve manter `asset_table` viva, aplicar `preload` no boot e ler payload por slice sob demanda.
- a leitura atual baseada em `Arc<RwLock<Vec<u8>>>` deve evoluir para uma origem de leitura por ROM/view/slice.
### Shipper / Packer
- o `packer` deve produzir `assets.pa` com prelude + header JSON + payload.
- o `shipper` continua livre para consumir auxiliares JSON, mas deve tratar `assets.pa` como artefato de verdade para assets.
- o `manifest.json` publicado pelo `shipper` deixa de carregar `asset_table` e `preload` como contrato primario de runtime.
### Firmware / Boot
- a etapa de carga do cart deve abrir `assets.pa`, extrair header e decidir falha cedo antes de preload.
- preload deixa de ser atributo editorial do manifest e passa a ser insumo interno do artefato de assets.
## Referencias
- `../specs/13-cartridge.md`
- `../specs/15-asset-management.md`
- `../agendas/008-packed-cartridge-loader-pmc.md`
- `../../../studio/docs/packer/Prometeu Packer.md`
- `../../crates/console/prometeu-hal/src/cartridge_loader.rs`
- `../../crates/console/prometeu-hal/src/cartridge.rs`
- `../../crates/console/prometeu-drivers/src/asset.rs`
## Propagacao Necessaria
- criar PR/plan para atualizar specs `13` e `15`;
- criar PR/plan de codigo para:
- mudar o loader de cart para abrir header de `assets.pa`;
- mover `asset_table`/`preload` para a leitura do binario de assets;
- introduzir leitura sob demanda por slice;
- remover o baseline de payload inteiro residente;
- falhar cedo quando `Capability::Asset` exigir `assets.pa` ausente;
- agenda `023-asset-packer-runtime-facing-contract.md` deve ser considerada fechada e removida da lista de agendas ativas;
- agenda `008-packed-cartridge-loader-pmc.md` passa a depender desta decisao como base do artefato de assets.

View File

@ -1,157 +0,0 @@
# Decision Record - `assets.pa` Preload Uses `asset_id`
## Status
Accepted
## Contexto
A `decision 011` fechou o envelope runtime-facing de `assets.pa`:
- `assets.pa` e o contrato primario de assets do runtime;
- `asset_table` e `preload` vivem no header interno do artefato;
- `preload` e consumido apenas no bootstrap.
Essa decisao, no entanto, nao definiu a semantica de identidade de `PreloadEntry`.
O estado atual do runtime ainda mistura dois modelos:
- `AssetEntry` ja trata `asset_id` como identidade operacional do asset;
- `PreloadEntry` ainda usa `asset_name` como chave pratica de resolucao no boot.
Isso preserva uma dependencia estrutural de campo mutavel justamente na fase em que o cart deveria ser mais deterministicamente validavel.
## Decisao
### 1. `PreloadEntry` passa a ser `{ asset_id, slot }`
O shape normativo de preload em `assets.pa` passa a ser:
```text
PreloadEntry {
asset_id,
slot
}
```
`asset_name` deixa de fazer parte do contrato operacional de preload.
### 2. `asset_id` tem semantica de `java int`
`asset_id` no contrato runtime-facing de assets passa a ser um inteiro de 32 bits com semantica de `java int`.
Qualquer representacao interna do runtime deve respeitar essa semantica e nao introduzir contrato unsigned por acidente.
### 3. `asset_name` permanece apenas como metadata descritiva
`asset_name` continua permitido em `AssetEntry` para:
- debug;
- observabilidade;
- tooling editorial;
- UX de inspecao.
Mas `asset_name` nao participa:
- da identidade normativa do asset;
- da validacao de preload;
- da resolucao operacional de preload.
### 4. `preload` deve ser validado contra a `asset_table`
Quando `assets.pa` existir, o runtime deve validar `preload` durante o bootstrap usando a `asset_table` carregada do mesmo artefato.
Validacoes minimas obrigatorias:
- todo `preload.asset_id` deve existir na `asset_table`;
- nao pode haver clash de slot por tipo.
### 5. Clash de slot por tipo e proibido
O namespace de slot de preload e derivado de `bank_type` da `asset_table`.
Portanto, depois de resolver cada `preload.asset_id` para sua respectiva `AssetEntry`, o cart e invalido se houver mais de uma entry de preload para o mesmo par:
```text
(bank_type, slot)
```
Isso vale mesmo que as entries apontem para o mesmo asset.
### 6. Nao ha compatibilidade normativa com preload legado por `asset_name`
O contrato do runtime nao oferece modo de compatibilidade para preload legado baseado em `asset_name`.
Artefatos que nao seguirem o shape novo devem ser considerados invalidos para o contrato vigente.
### 7. Falhas de preload invalido sao estruturais de cart
Os seguintes casos sao erros estruturais de formacao do cart:
- `preload.asset_id` ausente da `asset_table`;
- clash de slot por tipo dentro de `preload`.
Esses casos devem falhar no bootstrap do cart, antes da execucao normal, e nao pertencem ao espaco de `status` operacional de `asset.load`.
## Rationale
Esta decisao foi adotada porque:
- alinha preload com a identidade estavel do dominio de assets;
- remove dependencia de metadata mutavel no bootstrap;
- preserva `asset_table` como fonte de verdade unica para identidade e tipo;
- torna a validacao do cart mais deterministica;
- impede que compatibilidade legado vire contrato permanente por inercia.
O uso de `java int` foi escolhido para manter alinhamento de semantica de ID com a fronteira de linguagem/plataforma desejada, em vez de cristalizar um detalhe unsigned especifico da implementacao atual em Rust.
## Invariantes / Contrato
- `PreloadEntry` e normativamente `{ asset_id, slot }`.
- `asset_id` segue semantica de `java int`.
- `asset_name` nao tem autoridade operacional sobre preload.
- `preload` so pode referenciar assets existentes na `asset_table` do mesmo `assets.pa`.
- `preload` nao pode conter mais de uma ocupacao para o mesmo par `(bank_type, slot)`.
- falhas de validacao de preload sao erros estruturais de cart e devem abortar o bootstrap.
- `asset.load(name, kind, slot)` permanece fora do escopo desta decisao.
## Impactos
### Specs
- `15-asset-management.md` deve explicitar o shape normativo de `PreloadEntry`, a semantica de `asset_id` e as validacoes estruturais de preload.
- `13-cartridge.md` deve registrar que `assets.pa` invalido inclui preload com IDs ausentes ou clash de slot por tipo.
### Runtime
- `prometeu-hal/src/asset.rs` deve trocar `PreloadEntry.asset_name` por `asset_id`.
- tipos de `asset_id` expostos no contrato runtime-facing devem ser revisados para semantica de `java int`.
- o loader de `assets.pa` deve rejeitar preload invalido antes de iniciar preload.
- o `AssetManager` deve resolver preload diretamente por `asset_id`, sem ponte nome -> id.
### Tooling / Packer
- o produtor de `assets.pa` deve emitir preload apenas com `asset_id`.
- carts com preload legado por `asset_name` deixam de ser validos no contrato atual.
## Referencias
- `../agendas/024-assets-pa-preload-and-asset-table-id-based-contract.md`
- `../decisions/011-assets-pa-autocontained-runtime-contract.md`
- `../specs/13-cartridge.md`
- `../specs/15-asset-management.md`
- `../../crates/console/prometeu-hal/src/asset.rs`
- `../../crates/console/prometeu-hal/src/cartridge_loader.rs`
- `../../crates/console/prometeu-drivers/src/asset.rs`
## Propagacao Necessaria
- criar PR/plan para atualizar `spec 13` e `spec 15`;
- criar PR/plan de codigo para:
- trocar o shape de `PreloadEntry` para `asset_id`;
- validar preload durante parse/bootstrap de `assets.pa`;
- rejeitar `asset_id` ausente da `asset_table`;
- rejeitar clash de slot por tipo;
- revisar a tipagem de `asset_id` para semantica de `java int`;
- atualizar testes de loader e `AssetManager`;
- remover a `agenda 024` da lista de agendas ativas.

View File

@ -16,14 +16,13 @@ Regra de uso:
Decisoes ativas: Decisoes ativas:
- `003-vm-owned-byte-transfer-protocol.md` Nenhuma no momento.
- `006-vm-owned-stateful-core-contract.md`
- `007-filesystem-fault-core-policy.md`
- `011-assets-pa-autocontained-runtime-contract.md`
- `012-assets-preload-asset-id-contract.md`
Decisoes implementadas e aposentadas (migradas para `learn/`): Decisoes implementadas e aposentadas (migradas para `learn/`):
- `historical-vm-core-and-assets.md`
- decisions: `003`, `006`, `007`, `011`, `012`
- rationales: VM-owned stateful core, byte transfer protocol, FS fault policy, assets.pa contract and ID-based preload.
- `historical-gfx-status-first-fault-and-return-contract.md` - `historical-gfx-status-first-fault-and-return-contract.md`
- spec: `../specs/04-gfx-peripheral.md` - spec: `../specs/04-gfx-peripheral.md`
- impl: `crates/console/prometeu-system/src/virtual_machine_runtime/dispatch.rs`, `crates/console/prometeu-hal/src/syscalls/domains/gfx.rs` - impl: `crates/console/prometeu-system/src/virtual_machine_runtime/dispatch.rs`, `crates/console/prometeu-hal/src/syscalls/domains/gfx.rs`

View File

@ -0,0 +1,53 @@
# Historical VM Core and Assets (Retired Decisions)
This document consolidates the historical rationale and mental models from retired decisions regarding VM-owned stateful core, byte transfer protocol, filesystem fault policies, and asset management.
Status: Pedagogical / Historical (not normative).
## 1. VM-Owned Stateful Core and Byte Transfer
### Rationale for Stateful Core (Retired Decision 006)
- **Problem**: Lack of a canonical contract for stateful VM-owned resources led to divergence in handles, lifecycles, and ABI shapes.
- **Solution**: Represent stateful resources as `HeapRef<TBuiltinState>` with anti-stale mechanisms (index + generation).
- **Lifecycle**: Every stateful domain must explicitly define `create`, `read/query`, `update`, and `destroy`.
- **Fault Model**: `Trap` for structural errors (invalid ABI, stale handles), `status` for domain operational failures.
### Rationale for Byte Transfer Protocol (Retired Decision 003)
- **Goal**: Establish a canonical protocol for moving bytes between host and guest without binary-to-string conversion or host-owned handles.
- **Protocol**: Uses `Value::Byte` as a primitive and `HeapRef(Byte)` (ObjectKind::Bytes) as the canonical buffer.
- **Signatures**:
- `read(host_handle, host_offset, dst_ref, dst_offset, max_bytes) -> (status, bytes_transferred, eof)`
- `write(host_handle, host_offset, src_ref, src_offset, max_bytes) -> (status, bytes_transferred)`
- **Impact**: Unified data plane for `fs` and data banks, giving the guest explicit control over memory.
## 2. Filesystem Fault Policy (Retired Decision 007)
### Core Policy
- **Trap**: Structural violations (invalid signatures, dead HeapRefs, invalid byte windows).
- **Status**: Operational conditions (not found, access denied, storage full, transient backend errors).
- **No Partial Success**: `write` operations must not report silent partial success; failure to complete the full contract results in a domain failure status.
## 3. Asset Management and `assets.pa` Contract
### Autocontained Runtime Contract (Retired Decision 011)
- **Transition**: Moved from fragmented `manifest.json` + `assets.pa` to a single autocontained `assets.pa` artifact.
- **Envelope v1**: Fixed binary prelude + JSON header (asset_table + preload) + Binary payload.
- **Memory Efficiency**: The runtime must not require the entire payload to be resident in RAM; slices are resolved using offsets relative to the payload region.
### Preload and Identity (Retired Decision 012)
- **Identity**: `PreloadEntry` moved from name-based to ID-based (`{ asset_id, slot }`).
- **Semantics**: `asset_id` follows Java `int` (32-bit signed) semantics to ensure cross-platform compatibility.
- **Validation**: Preload is validated during bootstrap against the `asset_table`. Invalid IDs or slot clashes (same bank_type and slot) are structural errors that abort boot.
## References
- **Specs**:
- `../specs/15-asset-management.md`
- `../specs/16-host-abi-and-syscalls.md`
- `../specs/16a-syscall-policies.md`
- **Source Decisions (Archived)**:
- `003-vm-owned-byte-transfer-protocol.md`
- `006-vm-owned-stateful-core-contract.md`
- `007-filesystem-fault-core-policy.md`
- `011-assets-pa-autocontained-runtime-contract.md`
- `012-assets-preload-asset-id-contract.md`

View File

@ -1,69 +0,0 @@
# PR 012 - Propagacao da Decision 012 para Preload por `asset_id`
## Briefing
Esta PR executa a `decision 012`, que fecha a identidade normativa de preload em `assets.pa`.
O objetivo e remover preload por `asset_name`, adotar `asset_id` com semantica de `java int`, e validar preload como parte estrutural da formacao do cart.
## Decisions de Origem
- `../decisions/011-assets-pa-autocontained-runtime-contract.md`
- `../decisions/012-assets-preload-asset-id-contract.md`
## Alvo
Propagar a decisao em specs e codigo do runtime para que:
- `PreloadEntry` seja `{ asset_id, slot }`;
- preload invalido falhe no bootstrap;
- o runtime nao dependa de nome para resolver preload.
## Escopo
- atualizar `spec 13` e `spec 15`;
- atualizar structs e parse do header de `assets.pa`;
- validar preload contra `asset_table`;
- detectar clash de slot por tipo;
- ajustar `AssetManager` e testes para preload por `asset_id`;
- revisar tipos expostos de `asset_id` para semantica de `java int`.
## Fora de Escopo
- mudar a superficie VM-facing de `asset.load(name, kind, slot)`;
- redesenhar `asset_table` alem do necessario para suportar a decisao;
- introduzir compatibilidade legado por `asset_name`;
- alterar politica de bancos/slots fora da validacao de preload.
## Plano de Execucao
1. Atualizar specs `13` e `15` com o shape normativo novo e as regras de validacao estrutural.
2. Trocar `PreloadEntry` em `prometeu-hal` para `asset_id`.
3. Revisar os pontos runtime-facing onde `asset_id` ainda esta fixado como unsigned.
4. Validar, no parse/bootstrap de `assets.pa`, que:
- todo preload referencia `asset_id` existente;
- nao existe duplicidade de `(bank_type, slot)`.
5. Remover a resolucao nome -> id do caminho de preload no `AssetManager`.
6. Atualizar testes de loader, parse e preload em memoria.
## Criterios de Aceite
- `assets.pa` com preload valido por `asset_id` carrega normalmente.
- `assets.pa` com `asset_id` ausente da `asset_table` falha no bootstrap.
- `assets.pa` com clash de slot por tipo falha no bootstrap.
- preload deixa de depender de `asset_name`.
- nenhuma spec vigente continua descrevendo preload por nome.
## Tests / Validacao
- teste de parse do header com `PreloadEntry { asset_id, slot }`;
- teste de rejeicao para `preload.asset_id` inexistente;
- teste de rejeicao para duplicidade de `(bank_type, slot)`;
- teste de inicializacao do `AssetManager` preloading por `asset_id`;
- revisao textual das specs `13` e `15` contra a `decision 012`.
## Riscos
- a troca de semantica de `asset_id` para `java int` pode expor assumptos unsigned espalhados no runtime;
- validacao estrutural no loader pode exigir ajuste em fixtures de teste existentes;
- se houver produtor externo ainda emitindo preload por `asset_name`, ele quebrara imediatamente, como mandado pela decisao.

View File

@ -34,8 +34,10 @@ Uma PR deste diretório deve:
- estabelecer critérios objetivos de aceite; - estabelecer critérios objetivos de aceite;
- definir a estratégia de teste proporcional ao risco da mudança. - definir a estratégia de teste proporcional ao risco da mudança.
## Roadmap Publicado ## Roadmap Atual
PRs propostas para execucao da rodada atual: Nenhuma PR em aberto no momento.
- `012-assets-preload-asset-id-propagation.md` ## PRs Finalizadas
- `012-assets-preload-asset-id-propagation.md`: concluída. Propagação de ID-based preload concluída em specs e prometeu-hal.