Air’s layer 0 — introduction (developers)
Overview document, to get up to speed on layer 0 quickly and know where to find the
reference. The ADRs (docs/adrs/) are project-internal documents; this document is
aimed at the developers who consume or study layer 0.
What layer 0 is
Layer 0 is Air’s syscall foundation: a typed, safe Rust API on top of the Linux system calls, without libc. Two crates:
air-sys-types— the pure types (no syscall): typed identifiers (Pid,Tid,Uid/Gid,WatchDescriptor…),Errno, flags/bitflags, mirror types (#[repr(C)]) of the kernel structures.air-sys-syscall— the wrappers that call the kernel viacore::arch::asm!and returnResult<T, Errno>.
What you find here:
- 11 syscall families:
process,fs,mem,signal,time,net,ipc,security,system,device(uevent/evdev),ebpf(bpf()+perf_event_open); - the complete
io_uringmodule (12 “Temps”: core, files, network, async,uring_cmd, registration, provided buffers, linked operations, multishot, multi-thread, confinement, raw access) — the foundation of Air’s asynchronous I/O; - extensions:
fs::inotify, CPU affinity (sched_set/getaffinity),mem::MmapRegion, the privsep extension ofprocess(setgroups/setres*id).
Why this architecture
- No libc, no
rustix. Layer 0 talks to the kernel directly inasm!. Goal: total control of the behavior, no C dependency, and ano_std-compatible target. (ADR-004: Linux tier-1.) - Safety through typing.
Option<T>instead of the kernel sentinels (-1/0),Result<T, Errno>instead of the global errno,OwnedFd/BorrowedFd(RAII, no FD leak), newtypes per identifier. (Conventions carved in stone: ADR-021.) - io_uring as the async foundation. Air’s asynchronous runtime (ADR-023) is built on io_uring (ADR-022/028), not on epoll nor Tokio. A safe, proven “slab S1” ownership model (Miri/loom).
- Modern variants preferred:
clone3(notclone),pidfd_*(not the raw PID),waitid(notwait/waitpid),signalfd(ADR-020), io_uring’s*2register-ops… - Foundational-layer rigor: 100% coverage of lines + branches (excluding
documented exceptions), property-testing, fuzzing on every parser of external
data, Miri/loom on
unsafe/concurrent code. (Principle 1.)
Why a 6.12 kernel minimum
6.12 is an LTS kernel (long-term support, consistent with Air’s durability horizon),
and it is the version where the io_uring surface Air depends on is available (down to
the recent operations and register-ops), alongside Landlock, seccomp-bpf, eBPF, etc.
Targeting a single stable version avoids the hell of compatibility #ifdefs and
keeps layer 0 simple and auditable. The syscall numbers and layouts are verified
per architecture (x86_64 and aarch64) against the 6.12 uapi.
What you will not find here (and why)
- No libc, no
rustix— by design (see above). - The legacy syscalls deliberately set aside, listed and justified in
UNSUPPORTED.md: the old variants superseded by a modern variant (clone,wait/waitpid, raw PIDs…), and the obsolete io_uring mechanisms (PROVIDE_BUFFERS/REMOVE_BUFFERSop-based, untagged v1 register-ops…). - Deferred by decision (present nowhere, and that’s intentional): epoll (the
readiness need is covered by io_uring’s
poll/multishot; only speculativeEpoll*types exist), fanotify (privileged primitive, for a later security service), synchronous futex (will come withair-thread’s in-house futex implementation).
UNSUPPORTED.md is the reference list of these choices.
External dependencies
None in production. Layer 0 is pure Rust + asm! — no C, no
libc, no rustix. The only dependencies are test-only (property-testing,
loom, cargo-fuzz), isolated and subject to deny.toml/cargo audit (carve-out
ADR-030). This is unusual and assumed: the foundation depends on nothing above
the kernel.
For the C/C++ developer
Layer 0 does not expose a C ABI, and that is intentional: all its value lives in
the Rust type system (RAII, lifetimes, Option/Result, io_uring ownership)
— which does not cross a C boundary. If you are in C/C++:
- raw syscalls → use your libc (glibc/musl); io_uring in C → liburing;
- Air features → the C ABI of layers 1+ (
air-base-lib, thenair-runtime/air-aircom), where Air is polyglot by design (ADR-027); - building C tools on top of the Air stack is the subject of a
libc-compattrack (exploration,docs/notes/), not of layer 0.
Reference — to go further
- Per-family specs:
docs/specs/layer-0/family-*.md. - io_uring module: master inventory
io-uring-0-inventaire.md+ one document per Temps (io-uring-1-core.md…io-uring-4-raw.md). - Decisions: ADR-021 (layer 0 conventions), ADR-019 (errors), ADR-020 (signals), ADR-022/028 (io_uring), ADR-029 (naming), ADR-024/030/034 (dependencies), ADR-031/035 (coverage & exception taxonomy).
- Reference lists:
UNSUPPORTED.md(legacy set aside),COVERAGE-EXCEPTIONS.md(justified coverage exceptions). - API: the generated rustdoc reference (
/api/).
Document license: MPL 2.0.