4.2 KiB
4.2 KiB
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:
gameusa32slots por jogo;- payload maximo por slot de
32KB; - jogo acessa somente slots do proprio
app_id; - persistencia explicita com
commitatomico 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
32slots logicos (0..31); - cada slot oferece payload util de ate
32 * 1024bytes; - acesso em userland e restrito ao
app_iddono 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:intslot_clear(slot:int) -> status:int
Regras:
statuse 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_iddono;slot_index;save_uuid;generation;payload_size;checksum;state(EMPTY,STAGED,COMMITTED,CORRUPT).
generation e checksum nao sao controlados manualmente pela userland:
generationincrementa a cadaslot_commitbem-sucedido;checksume 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_writealtera staging (nao persiste no destino final);slot_commitaplica persistencia atomica por slot;- sucesso parcial silencioso e proibido;
- em falha de commit, retorna
statusde erro e preserva invariante de atomicidade.
6. Fronteira de fault class
memcard(game) segue 16a:
Trap: erro estrutural (slot fora da faixa,HeapRefinvalido/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_idno 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
gamesem 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.mddeve ser considerada fechada e removida; specs/08-save-memory-and-memcard.mddeve absorver este contrato (32 x 32KB, slots porapp_id, commit atomico);specs/16-host-abi-and-syscalls.mdespecs/16a-syscall-policies.mddevem absorver a surface e matriz de fault/status.