Status: draft Scope: Milestone 11 preflight execution and instruction contract.
WaveIL v0 is a small intermediate instruction format for wave-native apps. It is not a physics DSL and not a user-facing high-level language. It compiles to ABI-level operations that already exist in the kernel.
Primary goals:
- deterministic runtime behavior
- minimal op set that can express apps without Python-side logic
- capability-aware dispatch at each instruction
A WaveIL module is a list of functions and one entrypoint.
Canonical interchange form:
- JSON object with fields:
- module_name
- version
- constants
- functions
- entrypoint
Instruction JSON shape:
- op: opcode string
- args: object with opcode-specific fields
- dst: optional destination register name
- label: optional label identifier
- cap: required capability token string for this instruction
Example instruction: { "op": "CHAN_SEND", "args": {"handle": "r1", "amp": 1.2, "radius": 2}, "cap": "chan.use" }
WaveIL v0 uses a cooperative, tick-driven sequential VM.
Model:
- Each app has one VM context.
- Each VM context has:
- instruction pointer
- register file
- blocked state
- sleep-until tick
- last_status record
- On each kernel tick, runtime dispatch does:
- if blocked, attempt wake condition check
- if sleeping and now < sleep-until, do nothing
- else execute up to max_instructions_per_tick sequentially
Default max_instructions_per_tick:
- 8 (runtime configurable)
Consistency rules:
- SLEEP_TICKS is non-blocking relative to kernel; it yields VM until target tick.
- CHAN_RECV has two modes:
- nonblocking: returns immediately with status empty or message
- blocking_timeout: sets VM blocked until message or timeout tick
- VM blocked state is runtime-level and maps to kernel recv behavior where applicable.
Registers:
- untyped scalar slots keyed by register name, example r0..r31
- allowed runtime values:
- int
- float
- bool
- string
- handle (int with owner metadata in runtime table)
- map/dict for structured syscall results
Special status register:
- st (implicit)
- updated after each instruction with:
- ok: bool
- code: status string
- value: optional payload
Handle in WaveIL is an opaque integer issued by kernel-facing syscall wrappers.
Runtime requirements:
- Handles are never fabricated by program text.
- Handles are stored in register values.
- Runtime maintains side table for each handle:
- owner_app_id
- handle_kind: channel | window | fs | other
- issued_tick
Ownership enforcement:
- Before any handle-using instruction, runtime verifies owner_app_id matches current app.
- On mismatch, instruction is denied and logged as security_denied_handle_owner.
Lifetime:
- Handles are valid until explicit close (future op) or app termination.
- On app stop/restart, runtime drops all transient handles unless manifest says persistent handle restore (not in v0).
JUMP_IF reads predicate from one register.
Form:
- JUMP_IF args:
- cond_reg: register name
- target: label string
Predicate truth rules:
- bool true/false as-is
- int/float: zero is false, nonzero is true
- string: empty false, non-empty true
- other types: false
Errors:
- missing target label: hard fault, VM halted with status code bad_label
- missing cond_reg: false
Minimal control set in v0:
- JUMP
- JUMP_IF
- HALT
No stack in v0. No call/ret in v0.
Core:
- NOP
- HALT
- CONST
- MOVE
- JUMP
- JUMP_IF
- SLEEP_TICKS
Wave/Domain:
- EMIT (domain-local packet emit)
Channels:
- CHAN_OPEN
- CHAN_SEND
- CHAN_RECV
Windows:
- WIN_CREATE
- WIN_FOCUS
- WIN_RAISE
- WIN_SNAP
Filesystem explorer ops:
- FS_LIST
- FS_OPEN
- FS_RENAME
- FS_COPY
- FS_MOVE
- FS_DELETE
- FS_RESTORE
All instructions return status in st and optional value in dst.
Status codes:
- ok
- empty
- timeout
- denied_capability
- denied_handle_owner
- invalid_args
- kernel_error
- bad_label
- halted
Runtime must not throw uncaught exceptions for bad program input. Runtime must return status + halt only on unrecoverable control faults.
WaveIL supports two authoring modes:
- Human-readable assembly form for tests/debugging.
- Compiler target form from higher-level language.
Policy:
- v0 allows direct authoring for bring-up.
- Production app path should target compiler output once toolchain is ready.
For fixed seed, fixed input replay, and fixed runtime config:
- same instruction stream must produce same status sequence
- same syscall sequence and same denials log order
Runtime config fields that must be fixed for deterministic runs:
- max_instructions_per_tick
- recv blocking policy defaults
- scheduler app ordering
A runtime is WaveIL v0 compliant if it:
- implements the execution model in section 3
- enforces handle ownership in section 5
- enforces JUMP_IF semantics in section 6
- returns status codes from section 8
- passes deterministic replay checks in section 10