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

4.7 KiB

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

[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

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

CALL_INTRINSIC random.new@1
CALL_INTRINSIC random.rng.next@1
CALL_INTRINSIC random.rng.destroy@1

No bytecode final:

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.