prometeu-runtime/docs/runtime/learn/011-game-memcard-slots-surface-and-semantics.md
2026-03-24 13:40:51 +00:00

130 lines
4.2 KiB
Markdown

# Decision Record - Game Memcard Slots Surface and Semantics
## Status
Accepted
## Contexto
Jogos precisam de persistencia previsivel e portavel para save/config/blob, sem acesso amplo ao filesystem.
A agenda `013-game-memcard-slots-surface-and-semantics.md` consolidou os inputs de produto:
- `game` usa `32` slots por jogo;
- payload maximo por slot de `32KB`;
- jogo acessa somente slots do proprio `app_id`;
- persistencia explicita com `commit` atomico por slot;
- copia/export/import de saves ocorre fora do jogo (Hub/OS).
Esta decisao fecha o contrato v1 do perfil `game` usando a decisao `003` como data plane de bytes.
## Decisao
### 1. Contrato base de capacidade e ownership
- cada jogo possui exatamente `32` slots logicos (`0..31`);
- cada slot oferece payload util de ate `32 * 1024` bytes;
- acesso em userland e restrito ao `app_id` dono do cart carregado;
- nao existe acesso por path para jogos no v1.
### 2. Surface minima de memcard (status-first)
- `slot_count() -> (status:int, count:int)`
- `slot_stat(slot:int) -> (status:int, state:int, used_bytes:int, generation:int, checksum:int)`
- `slot_read(slot:int, buf:HeapRef<Bytes>, offset:int, max_bytes:int) -> (status:int, bytes_read:int)`
- `slot_write(slot:int, buf:HeapRef<Bytes>, offset:int, len:int) -> (status:int, bytes_written:int)`
- `slot_commit(slot:int) -> status:int`
- `slot_clear(slot:int) -> status:int`
Regras:
- `status` e sempre o primeiro retorno;
- operacoes de bytes usam `HeapRef<Bytes>` + janela explicita (`offset`, `max_bytes`/`len`);
- shape segue politica de `16a`.
### 3. Envelope digital runtime-owned por slot
Cada slot mantem metadados canonicos runtime-owned:
- `app_id` dono;
- `slot_index`;
- `save_uuid`;
- `generation`;
- `payload_size`;
- `checksum`;
- `state` (`EMPTY`, `STAGED`, `COMMITTED`, `CORRUPT`).
`generation` e `checksum` nao sao controlados manualmente pela userland:
- `generation` incrementa a cada `slot_commit` bem-sucedido;
- `checksum` e recalculado pelo runtime no payload persistido.
### 4. Envelope visual para Hub/OS
O slot expoe metadados visuais para UX fora do jogo:
- `label`;
- `subtitle`;
- `updated_at` (ou contador logico equivalente);
- `icon_ref` (v1 estatico, formato extensivel para animacao futura).
### 5. Politica de escrita e atomicidade
- `slot_write` altera staging (nao persiste no destino final);
- `slot_commit` aplica persistencia atomica por slot;
- sucesso parcial silencioso e proibido;
- em falha de commit, retorna `status` de erro e preserva invariante de atomicidade.
### 6. Fronteira de fault class
`memcard(game)` segue `16a`:
- `Trap`: erro estrutural (slot fora da faixa, `HeapRef` invalido/dead, janela invalida, shape ABI invalido);
- `status`: erro operacional de dominio;
- `Panic`: apenas quebra de invariante interna.
Catalogo minimo de status do dominio:
- `OK`;
- `EMPTY`;
- `NOT_FOUND`;
- `NO_SPACE`;
- `ACCESS_DENIED`;
- `CORRUPT`;
- `CONFLICT`;
- `UNAVAILABLE`;
- `INVALID_STATE`.
### 7. Politica de copia/export/import (fora do jogo)
- copia/export/import e responsabilidade do Hub/OS;
- jogo nao recebe API para copiar slots entre apps;
- v1 valida ownership por `app_id` no import;
- conflito e corrupcao devem ser refletidos por status do dominio e UX do Hub.
### 8. Integracao com storage host
- namespace fisico isolado por `app_id`;
- representacao fisica por slot e interna ao runtime/host;
- persistencia deve usar estrategia atomica (arquivo temporario + flush + rename equivalente da plataforma).
## Consequencias
### Positivas
- fecha o contrato de save de `game` sem abrir FS amplo;
- torna copy/export/import um fluxo de sistema (Hub/OS), nao de userland;
- padroniza integridade/versionamento de slot com `generation` + `checksum`.
### Custos
- exige implementacao de staging/commit atomico por slot;
- exige especificacao explicita do formato de export/import no Hub/OS;
- exige alinhamento com specs de memcard e ABI.
## Follow-up Obrigatorio
- a agenda `013-game-memcard-slots-surface-and-semantics.md` deve ser considerada fechada e removida;
- `specs/08-save-memory-and-memcard.md` deve absorver este contrato (`32 x 32KB`, slots por `app_id`, commit atomico);
- `specs/16-host-abi-and-syscalls.md` e `specs/16a-syscall-policies.md` devem absorver a surface e matriz de fault/status.