prometeu-runtime/docs/runtime/decisions/006-vm-owned-stateful-core-contract.md
2026-03-24 13:40:49 +00:00

172 lines
4.7 KiB
Markdown

# 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.