prometeu-runtime/docs/specs/runtime/08-save-memory-and-memcard.md

141 lines
3.9 KiB
Markdown

# Save Memory and MEMCARD
Domain: virtual hardware: save memory
Function: normative
Didactic companion: [`../learn/mental-model-save-memory-and-memcard.md`](../runtime/learn/mental-model-save-memory-and-memcard.md)
## 1 Scope
This chapter defines the `game` persistence surface in PROMETEU.
MEMCARD is a runtime-owned service layered on top of the runtime filesystem.
Games do not get broad path-based filesystem access for saves. They use slot operations only.
## 2 Profile Contract (`game`)
The v1 contract is fixed:
- `32` slots per game (`slot_index: 0..31`);
- each slot has up to `32KB` payload;
- ownership is isolated by `app_id`;
- persistence is explicit through `slot_commit`;
- copy/export/import is a Hub/OS responsibility (outside game userland).
## 3 Slot Identity and Metadata
Each slot has runtime-owned metadata:
- `app_id` owner;
- `slot_index`;
- `save_uuid`;
- `generation`;
- `checksum`;
- `payload_size`;
- `state`.
State values:
- `0 = EMPTY`
- `1 = STAGED`
- `2 = COMMITTED`
- `3 = CORRUPT`
`generation` and `checksum` are not manually controlled by game code:
- `generation` increments on successful `slot_commit`;
- `checksum` is recalculated by runtime for committed payload integrity.
## 4 Host ABI Surface (v1)
Canonical module: `mem` (version `1`).
| Operation | Signature |
| --- | --- |
| `slot_count` | `mem.slot_count() -> (status:int, count:int)` |
| `slot_stat` | `mem.slot_stat(slot:int) -> (status:int, state:int, used_bytes:int, generation:int, checksum:int)` |
| `slot_read` | `mem.slot_read(slot:int, offset:int, max_bytes:int) -> (status:int, payload_hex:string, bytes_read:int)` |
| `slot_write` | `mem.slot_write(slot:int, offset:int, payload_hex:string) -> (status:int, bytes_written:int)` |
| `slot_commit` | `mem.slot_commit(slot:int) -> status:int` |
| `slot_clear` | `mem.slot_clear(slot:int) -> status:int` |
`status` is always the first return slot.
### 4.1 Byte transport note (v1)
Current ABI transport for memcard payload is `payload_hex:string`.
This is a temporary transport form until VM-owned bytes (`HeapRef<Bytes>`) is exposed in the host ABI path.
## 5 Operation Semantics
### `slot_count`
- returns slot capacity visible to game profile (`32`);
- does not depend on slot content.
### `slot_stat`
- returns current state and integrity/version metadata for one slot.
### `slot_read`
- reads from staged content when present, otherwise committed content;
- returns empty payload with success when offset is beyond current payload end.
### `slot_write`
- writes into slot staging buffer (does not persist directly);
- supports offset writes;
- does not allow resulting payload above `32KB`.
### `slot_commit`
- persists staged payload for one slot;
- commit is atomic at slot operation level (all-or-error, no silent partial success).
### `slot_clear`
- clears staged content and removes committed slot payload.
## 6 Status Codes (Domain-Owned)
Minimum status catalog:
- `0 = OK`
- `1 = EMPTY`
- `2 = NOT_FOUND`
- `3 = NO_SPACE`
- `4 = ACCESS_DENIED`
- `5 = CORRUPT`
- `6 = CONFLICT`
- `7 = UNAVAILABLE`
- `8 = INVALID_STATE`
## 7 Fault Classification
MEMCARD follows `16a`:
- `Trap`: structural violations (invalid slot index, invalid call shape, invalid window value type/range);
- `status`: operational domain conditions;
- `Panic`: runtime invariant break only.
Silent no-op is forbidden for operations with operational failure paths.
## 8 Runtime Layering and Storage Mapping
MEMCARD is a domain layer over runtime FS.
Runtime host mapping for v1 is namespace-isolated by `app_id`, for example:
`/user/games/<app_id>/memcard/slot_<NN>.pmem`
The exact host-side file naming is internal to runtime/host as long as ownership and isolation guarantees are preserved.
## 9 Explicit Persistence Rule
PROMETEU does not auto-save slot staging data.
Without `slot_commit`, writes remain staged and are not guaranteed as persisted committed state.]