# Syscall Policies Domain: host ABI operational policy Function: normative This chapter defines the operational policies that sit on top of the host ABI. It complements [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md), which defines the structural ABI itself. Unless a domain chapter explicitly narrows behavior further, this chapter is the transversal policy for all syscalls in v1. ## 1 Error Model: Faults vs Status Returns Syscalls use a status-first hybrid model. ### Fault conditions The VM faults when contract rules are violated, for example: - invalid syscall id; - unresolved canonical identity; - missing required capability; - insufficient argument slots; - invalid or dead heap handle. These are not ordinary domain statuses. Faults are split into two runtime classes: - `Trap`: guest-visible structural violation (ABI misuse / invalid call shape). - `Panic`: runtime invariant break (internal inconsistency). `Unavailable` is not a canonical fault class in this policy model. - operational unavailability should be represented as `status`; - structural host/runtime collapse should be treated as `Panic`. ### Status returns Normal operational success and operational failure conditions should be represented as values in return slots. Examples: - asset not yet loaded; - audio voice unavailable; - persistent storage full. When a syscall returns `status`, that `status:int` occupies the first return slot. Any additional payload is domain-defined and follows that leading status slot. ### Return shape policy (`void` vs `status`) This policy is normative: - if an operation has observable operational failure modes, it must return `status:int` explicitly; - if an operation can be operationally rejected, ignored, deferred with failure, or conclude with guest-observable `no_effect`, it is not eligible to remain `void`; - if an operation has no real operational error path, it may remain `void` (`ret_slots = 0`); - `status` coding is domain-owned and may differ by operation, but must be deterministic and documented. Practical rule: - `void` is allowed only for operations whose non-fault path is effectively unconditional success; - any operation with a meaningful operational non-success outcome must surface that outcome through `status`, not through absence of return values. ### No-op policy Silent no-op is not allowed when an operation can fail operationally in a guest-observable way. In those cases, the runtime must return explicit `status` instead of masking failure as implicit success. Implicit fallback is also forbidden when it hides an operational error or state rejection that the guest could observe or reason about. This means operational problems must not be reclassified as: - silent success; - silent ignore; - `Trap`, when the failure is not structural; - `Panic`, when the failure is not an internal invariant break. ## 2 Capability System Each syscall requires a declared capability. Example groups: - `gfx` - `audio` - `asset` - `fs` (includes game memcard module `mem` in v1) Capability checks exist to constrain which host-managed surfaces a cartridge may use. Input in v1 is VM-owned intrinsic surface and is not capability-gated through syscall policy. Game memcard operations (`mem.*`) are status-first and use `fs` capability in v1. `mem` remains layered on runtime `fs`; no parallel persistence channel is introduced. Domain surface, status catalog and slot semantics are defined in [`08-save-memory-and-memcard.md`](08-save-memory-and-memcard.md). ## 3 Interaction with the Garbage Collector The VM heap and host-managed memory are separate. ### Heap vs host memory | Memory | Managed by | GC scanned | | --------------- | ---------- | ---------- | | VM heap objects | VM GC | Yes | | Asset banks | Host | No | | Audio buffers | Host | No | | Framebuffers | Host | No | ### Host root rule If the host stores a VM heap handle beyond the duration of the syscall, that handle must be treated as a host root according to the runtime contract. This rule applies to VM heap objects, not to host-owned asset identifiers or primitive values. ## 4 Determinism Rules Syscalls must obey machine-level determinism. Forbidden patterns: - reading wall-clock time as gameplay state; - non-deterministic OS access in the gameplay contract; - blocking I/O in the execution slice. Allowed patterns: - frame-based timing; - request + poll status models; - deterministic event publication at frame boundaries. ## 5 Cost Model and Budgeting Each syscall contributes to frame cost. The system may account for: - syscall count; - cycles spent in syscalls; - allocations triggered by syscalls. This keeps host interaction visible in certification, telemetry, and profiling. ## 6 Blocking and Long Operations Syscalls must not block the execution model. Long operations should follow explicit staged patterns such as: 1. request; 2. status polling or completion observation. This keeps the host ABI compatible with a deterministic frame machine. ## 7 Relationship to Other Specs - [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md) defines the structural ABI. - [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md) defines VM heap ownership and handles. - [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md) defines visibility of cost and diagnostics. - domain chapters (e.g. `04`, `05`, `15`) define per-operation status tables.