README.md

August 22, 2026 · View on GitHub

A3S OCI Runtime binds each container to an exact generation, durable lifecycle, and evidence-gated execution driver

The low-level execution plane for A3S: official OCI types, durable lifecycle replay, and one reviewed Linux executor across native and utility-VM paths.

CI status Latest A3S OCI Runtime release OCI Runtime Specification 1.3.0 Rust workspace MIT License

Inspect · Implementation · Contract · Platforms · Architecture · Qualification · Development


A3S OCI Runtime owns actual Linux-container execution for A3S: exact OCI validation, container and process state, monotonic generations, operation journals, terminal status, platform drivers, utility VMs, the authenticated guest agent, and runtime-scoped cleanup.

It deliberately does not pull images, build images, implement Compose, own product networks or volumes, or become a Docker daemon. Those responsibilities remain in A3S Box, which supplies prepared bundles, an isolation requirement, and a versioned attachment manifest through the public a3s-oci-sdk.

Warning

This repository is in active development. No built-in driver is currently advertised as supported. The default host service exposes discovery only; Native Linux becomes experimental only when explicitly opened as a development instance, Apple Silicon HVF is experimental, and KVM and WHPX remain probe-only. Experimental means the reviewed development profile may launch; it does not imply production certification.

Inspect before you launch

The first successful action is intentionally read-only:

git clone https://github.com/A3S-Lab/OCI-Runtime.git
cd OCI-Runtime
cargo run -p a3s-oci-cli -- features

On the qualified Windows x86_64 host used for the current branch, the command reports an available hypervisor and still refuses to overstate driver readiness:

{
  "schema_version": "a3s.oci.features.v1",
  "platform": "windows",
  "architecture": "x86_64",
  "drivers": [
    {
      "driver": "libkrun-whpx",
      "status": "available",
      "readiness": "probe-only",
      "isolation_classes": [
        "dedicated-vm",
        "shared-guest-kernel"
      ],
      "evidence": {
        "hypervisor_present": "true",
        "win_hv_platform_dll": "true"
      }
    }
  ]
}

The evidence object is host-specific. The selection rule is not:

Reported stateMay launch?Meaning
host available + probe-onlyNoDiagnostics or qualification only
host available + experimentalWith explicit opt-inReviewed development profile; release gates remain
host available + supportedYesCertified profile
host unavailable or unsupportedNoPrerequisite absent or platform does not apply

DriverCapability::can_launch() requires both an available host capability and experimental or supported readiness.

What exists today

LayerImplemented boundary
Public SDKAsync Send + Sync Rust contract using official OCI Spec, Process, LinuxResources, State, and Features types; typed IDs, generations, operation contexts, versioned attachments, I/O, filesystem sessions, stats, events, and stable errors
Validation and transportOCI 1.0.0–1.3.0 schema and semantic validation with forward-compatible unknown-property retention and ignore semantics, an exhaustive 19-case pinned upstream JSON Schema suite, four launch-profile configuration/State/Features matrices, immutable configuration and attachment SHA-256 binding, and bounded protocol-4 local IPC over Unix sockets or protected Windows named pipes
Durable host serviceExact create/state/start/kill/delete, driver-advertised optional operations, global idempotency journals including File upload and Filesystem mkdir/move/remove, replay, generation fencing, startup recovery, quarantine, capability-rooted state traversal with Unix mount-identity fencing, post-commit replay-record acknowledgement for local and utility-VM drivers, sorted list, ordered events, and same-UID multi-container owners for Native Linux and Apple Silicon HVF
Shared Linux executorNamespace create/join, declared-root directory admission before namespace entry, pivot_root, ordered OCI mounts with root-relative legacy destinations and optional-field handling, the complete OCI 1.3 Linux mount-option control registry, exact init/exec argv, environment, cwd, terminal default, UID/GID, supplementary groups, and umask, conditional /dev/fd, /dev/stdin, /dev/stdout, and /dev/stderr links after mount processing, OCI hooks, user mappings, exact absolute and stable relative cgroupsPath resolution plus a private generation-fenced path on omission, complete cgroup v2 CPU shares/quota/burst/period/cpuset/idle mapping with explicit cgroup v1 realtime rejection, exact memory limit/reservation/swap and PIDs create/update mapping with zero preserved and OCI -1 encoded as max, finite total-swap validation, complete cgroup v2 Block I/O default/per-device weight and read/write BPS/IOPS throttle mapping with zero-rate clearing, keyed read-back, partial-update preservation, reverse rollback, and explicit leaf-weight rejection, dynamic HugeTLB usage/reservation controls, keyed RDMA HCA handle/object limits, bounded OCI 1.3 unified control-file writes with dynamic controller enablement, kernel-defined formatting, typed-file conflict rejection, readable no-op/rollback snapshots, and write-only control support, typed rejection of cgroup v1-only memory and network net_cls/net_prio controls, all five capability sets with kernel read-back, exact no_new_privileges verification, all 16 OCI rlimit types with exact kernel read-back, oomScoreAdj, scheduler policy, I/O priority, exact LINUX/LINUX32 init personality, all seven OCI NUMA memory-policy modes and three flags with kernel read-back, parent-owned Intel RDT CLOS, ordered schemata, process assignment, monitoring, and owner-death cleanup, exec CPU affinity applied around cgroup membership, transactional namespaced sysctls with descriptor-confined apply, read-back, and rollback, exact rootful block/character/FIFO nodes, the six default devices, /dev/ptmx, PTY-backed /dev/console, durable placeholder cleanup, immutable declared/default device inventory BPF with ordered resource-rule narrowing, seccomp, PID 1 supervision, pidfds, exec, process I/O, PTY with OCI consoleSize initialization, a bounded Host-acknowledged mutation replay journal, parent-bound launch/session helpers, PID-start-time-bound owner-death tombstones, descriptor-confined file/filesystem sessions, pause/resume, resource updates, normalized CPU/memory/PID/block-I/O stats, and scoped cleanup for the qualified profile
Utility-VM boundaryIsolated libkrun shim, authenticated protocol v10 with v1-v9 compatibility, 20 public workload operations plus one bounded maintenance acknowledgement, clone-wide shutdown, exact-generation VM sessions, and the same Linux executor behind the static guest agent. A platform-neutral one-VM-per-generation lifecycle now backs both the public HVF driver and the Linux KVM candidate, including bundle ownership handoff, concurrent Create fencing, retry and terminal cleanup, stopped recovery tombstones, and bounded shutdown. Durable recovery records remain on the per-generation share, privileged OCI device sources are created only on Guest-local devtmpfs and removed at the Create barrier, and shutdown consumes every retained device-target manifest before deleting the Guest runtime root
containerd runtime-v2SDK-only containerd-shim-a3s-oci-v2 with durable namespace/task identity, lifecycle and exec recovery, and schema-v8 metadata. A retained per-task exec sequence gives every Exec incarnation fresh SDK process and operation identities, so DeleteProcess can be followed by reuse of the same containerd exec ID across daemon restart without replaying the deleted process. Init/exec input, signal, and terminal-resize journals retain Open/Closing/Closed stdin state, output cursors, independent per-process signal and resize sequences, and a per-task control sequence. The shim also provides process/task-scoped serialization, cross-process-stable request fingerprints, bounded FIFO/PTY I/O, live replacement with exact stdin continuation, committed pending-write, close, signal, and resize replay without duplicate effects, correct SIGSTOP→SIGCONT→SIGSTOP→SIGCONT transitions, same-size resize suppression, correct A→B→A terminal restoration, no output replay, repeated pause/resume and update, stats, PID inventory, in-flight Create and committed Start/Kill/Delete/Exec/SignalProcess/Pause/Resume/Update/WriteStdin/CloseStdin/ResizePty recovery, post-commit Native Linux guest-journal reclamation, four-state forced shim-crash cleanup, and a four-task parallel restart gate; compatibility, packaging, and cross-driver release gates remain open
A3S Box consumerPublic-SDK-only lifecycle and attachments; pause/resume; process and filesystem sessions; exact live inventory, normalized stats, bounded ordered events, and replay-safe complete resource updates; explicit Native Linux Sandbox production routing and real-host SDK composition pass, while default and cross-platform cutover remain open
Retained evidenceSchema and normative locks, 189-pair authenticated protocol fault coverage, portable nine-stage Create/State/Start/Kill/Delete/Wait/Exec/SignalProcess/WaitProcess/Pause/Resume/Processes/Update/Stats/ReadOutput/WriteStdin/CloseStdin/Resize/File/Filesystem host reopen with exact post-commit acknowledgement, real-HVF nine-stage Host/Guest Create plus two-stage Host shutdown interruption and cleanup, all nine real-HVF Create, State, Start, Kill, Delete, Wait, Exec, SignalProcess, WaitProcess, Pause, Resume, Processes, Update, Stats, ReadOutput, WriteStdin, CloseStdin, Resize, File, and Filesystem transitions through durable service reopen and VM/session-owner replacement, a real protocol-v10 Apple Silicon Guest boot, native Linux real-container with distinct exact init/exec capability, NoNewPrivs, rlimit, OOM-score, I/O-priority, scheduler, init personality, init NUMA memory policy, exec CPU-affinity, and namespaced-sysctl read-back, rootless default-device and device-policy gates, soak, owner-death safe-termination, and three consecutive same-Host live containerd 2.2 lifecycle/restart/I/O matrices with deleted exec-ID reuse, post-commit guest-journal reclamation, and committed WriteStdin/CloseStdin/SignalProcess/ResizePty shim-replacement gates, fresh-VM HVF soak, fail-closed Linux KVM lifecycle/recovery/25-wave soak entries, and WHPX nominal plus owner-death/service-restart qualification

OCI 1.3 linux.netDevices is implemented by the shared Linux executor. The runtime validates a bounded deterministic move plan, requires a separate network namespace, rejects exact target-name collisions, supports appended %d templates, preserves stable link attributes and permanent global addresses, and brings each moved interface up. A failed Create rolls earlier moves back in reverse order; the rollback lease is released only after the created state is durably committed. Rootless execution rejects the request before mutation because the current helper contract does not grant host network-device authority. The Native Linux gate uses real dummy interfaces to exercise move, rename, address/MTU/MAC preservation, target conflict, partial rollback, rootless rejection, and cleanup.

OCI 1.3 linux.resources.hugepageLimits is also implemented by the shared executor. The SDK preserves the complete normative uint64 range, while the executor validates each canonical page-size name against the live cgroup-v2 inventory, enables hugetlb only when requested, and applies both usage and reservation limits when the kernel exposes reservation accounting. Create and live Update use kernel-representable values with read-back and reverse rollback; partial updates leave omitted page sizes unchanged. In control-workload-v1, HugeTLB remains an exact workload-only limit rather than being copied into the management envelope. Native Linux CI reads the selected host page-size controls back on x86_64 and aarch64 whenever the runner exposes hugetlb.

OCI 1.3 linux.resources.rdma is implemented as a separate keyed cgroup-v2 controller. Each device may limit HCA handles, HCA objects, or both; device names and available kernel entries are checked before device-policy mutation. Create and live Update preserve omitted fields, normalize the kernel's signed counter ceiling to max, read every effective value back, and roll applied devices back in reverse order. RDMA is required only when requested and remains workload-only in control-workload-v1. Native Linux qualification reads the control and workload entries back when a runner exposes both the controller and a usable InfiniBand device.

OCI 1.3 linux.resources.unified accepts bounded cgroup-v2 control-file maps. The executor validates one safe file name per key, rejects runtime-owned cgroup.* state and files already owned by typed OCI resources, preserves stable write order, and carries controller names unknown to the runtime through the live kernel inventory. Needed controllers are enabled before leaf creation; an absent or unenableable controller, missing control file, or unwritable control returns a typed error before device-policy mutation. Create and Update write every value in stable order without imposing a generic read-back format. Update uses readable controls for no-op suppression and reverse rollback, while write-only controls remain valid. control-workload-v1 applies them only to the workload leaf; Native Linux qualification reads memory.high from both children, verifies a kernel-normalized partial io.max write when possible, and exercises rootful and delegated-rootless live updates.

The current Box adapter at A3S-Lab/Box@a16772c3 rechecks every read against the exact runtime binding. File upload/download and filesystem stat/mkdir/move/list/remove now use the same cross-platform session facade; capability and Box-generation checks happen before dispatch, response targets and shapes are revalidated, and one explicitly retryable mutation response is replayed with the same context and one runtime effect. A partial product resource request is compiled into one complete OCI LinuxResources contract, claimed durably before dispatch, and replayed with the same runtime operation after a lost response. Runtime acknowledgement updates Box restart intent atomically without changing the original create identity.

New mutation records use a3s.oci.operation.v3. File uploads and Filesystem mkdir/move/remove retain their exact validated request and typed response in the Host journal. The Host commits the result before acknowledging the Guest replay record, so an acknowledgement disconnect returns a retryable error and the next owner replays the Host result without dispatching the mutation again. The Host journal remains the permanent changed-request fence after the Guest record has been released.

Durable state now pins its canonical root as a directory capability. All descendant reads, enumeration, creation, replacement, and quarantine moves are resolved from retained directory handles. macOS, Linux, and Windows gates prove that an ambient-root rename, layout or transaction symlink/reparse-point substitution, foreign filesystem handle, same-device Linux bind-mount replacement, or racing Windows file/directory destination replacement cannot redirect a mutation. Windows commits each already-open source object relative to a retained destination-parent handle and applies file DACLs through that same opened object.

The exact containerd API, identity, installation, restart, cleanup, and qualification boundary is documented in containerd Runtime V2.

That exact Box revision also validates its managed home, durably prepares the snapshot lower, named volumes, and networking, compiles the product-owned OCI bundle, and starts or reuses this runtime's identity-fenced long-lived Native Linux owner. Its blocking x86_64 and aarch64 Linux lanes drive Rust, Python, TypeScript, and Go Sandbox lifecycle, exec, filesystem, route-aware stats, pause/resume, snapshot restore, restart, and cleanup through the explicit production route.

Box completion and Runtime readiness measure different scopes. Box can finish its current product contract against a qualified Runtime slice; this repository still owns all 20 public workload operations, every advertised driver, owner-replacement semantics, OCI conformance, and release qualification. A completed consumer is therefore not evidence that the lower-level runtime is complete.

Linux file and filesystem calls execute in a fresh internal helper that inherits only the exact retained root, user-namespace, and mount-namespace descriptors. The helper authenticates its parent, rejects duplicate or reordered descriptors, enters the user namespace before the mount namespace, and then performs the bounded openat2 operations. Container IDs therefore remain correct on the rootfs, bind mounts, ID-mapped mounts, and container-created tmpfs filesystems.

The complete release target is every applicable OCI Runtime Specification 1.3.0 requirement for Linux containers and every advertised driver—not a reduced A3S-only profile. ROADMAP.md keeps completed evidence and open release gates separate.

Capability set enforcement remains exact and fail-closed for every value the runtime can grant. When the running kernel or the executor's inherited authority cannot grant a recognized requested capability, init and exec remove only that unavailable set membership and send a bounded structured warning to the supervising agent before crossing exec. Malformed or duplicate warning frames fail closed instead of becoming untrusted log text.

Linux sysctls now follow the same fail-closed boundary. The SDK accepts only known IPC, network, UTS-domain, and user-namespace controls in OCI dot or slash notation. The executor rejects host-global controls and same-host namespace joins, applies a bounded deterministic transaction through retained procfs, verifies each value, and restores earlier values if Create does not commit.

Intel RDT is owned by the runtime-namespace parent rather than the container init process. When linux.intelRdt is present, the parent finds the mounted resctrl filesystem, prepares or verifies the requested CLOS, applies l3CacheSchema, memBwSchema, and complete schemata in OCI order, reads the effective values back, and assigns the authenticated init PID before runtime hooks run. Dedicated monitoring groups and runtime-created CLOS directories are removed on Delete, shutdown, failed Create, or native owner-death recovery. Explicit and root CLOS directories remain externally owned.

The runtime contract

Create and start stay separate

creating ── create committed ──▶ created
created  ── start committed  ──▶ running
running  ── init terminated  ──▶ stopped

create validates and prepares the requested boundary without executing process.args. Only start releases the configured process. Invalid transitions fail without weakening that barrier.

Each durable container record retains:

  • the exact validated configuration and digest;
  • the complete a3s.oci.attachments.v1 manifest and its digest for newly created records;
  • a monotonically increasing runtime generation;
  • the runtime-selected driver and effective isolation;
  • active operation intent and terminal replay results;
  • the exact init and exec-process exit status when observed;
  • recovery or quarantine state for an interrupted mutation.

A matching retry reproduces the original result. A stale generation, reused operation ID with a different payload, unsupported OCI field, unavailable isolation class, or changed recorded driver fails before mutation.

Isolation is a requirement, not a driver name

RequestBoundaryKernel sharing
DedicatedVmHardware utility VMOne workload or pod owns the guest kernel
SharedGuestKernelHardware utility VMOne declared trust domain shares a guest kernel
SharedHostKernelNative LinuxContainers share the host kernel

The caller requests an isolation class. The runtime selects one launch-ready owner for that class, persists the selected driver, and routes every later operation back to that exact owner—even after the service reopens with drivers registered in a different order. It never reroutes historical state or falls back from a VM boundary to the host kernel.

The SDK is the execution boundary

use a3s_oci_runtime::HostRuntimeService;
use a3s_oci_sdk::RuntimeClient;

#[tokio::main(flavor = "current_thread")]
async fn main() -> a3s_oci_sdk::Result<()> {
    let client = RuntimeClient::new(HostRuntimeService::new());
    let info = client.features().await?;

    println!(
        "host={:?} arch={}",
        info.drivers.platform,
        info.drivers.architecture
    );
    for capability in &info.drivers.drivers {
        println!(
            "{:?}: host={:?}, readiness={:?}, launch={}",
            capability.driver,
            capability.status,
            capability.readiness,
            capability.can_launch()
        );
    }
    println!("operations={:?}", info.operations);
    Ok(())
}

RuntimeClient can wrap an in-process service or connect over bounded local IPC. A broken local stream is reported without hidden replay; the next explicit request reconnects and renegotiates so the caller can retry or reconcile with the original operation identity. Foreground run is only a client composition of durable create/start/wait/delete calls; it does not create a second lifecycle API or state machine.

On Linux, the explicit experimental host owner publishes one durable SDK endpoint without opening KVM:

a3s-oci native-linux-host-service \
  --root /run/a3s/oci-native \
  --agent /usr/libexec/a3s-oci-agent

The owner opens the Native Linux driver and durable state before publishing runtime.sock, serves independently fenced container generations to authenticated same-UID clients, and reaps driver-owned processes on graceful shutdown. Box's explicit A3S_BOX_OCI_MIGRATION=sandbox production route uses this owner. The existing native-linux-service command remains the Sandbox-scoped FD 3/4/5 owner for compatibility and focused qualification.

On Apple Silicon, the public HVF owner exposes the same SDK contract while keeping durable state separate from per-generation VM state:

a3s-oci macos-hvf-host-service \
  --root "$HOME/Library/Application Support/A3S/oci-hvf" \
  --shim /absolute/path/to/a3s-oci-krun-shim \
  --system-image-manifest /absolute/path/to/system-image.json

It prepares an owner-only 0700 root, publishes a same-UID 0600 runtime.sock, accepts concurrent clients, and removes only the socket inode it created. The service advertises all 20 HVF driver operations plus features, list, and events, requires the runtime bundle-handoff extension, and reaps every live dedicated VM on graceful shutdown. The HVF driver advertises only DedicatedVm; shared-guest pooling is not implemented.

The runtime contract suite also restarts the owner across two distinct OS processes on the same Unix socket or Windows named pipe. The replacement opens the same durable HostRuntimeService state, while one retained client recovers the exact generation and a live exec target, replays create/start/exec without duplicate test-driver dispatch, and continues inventory, stdin, signal, wait, output, and cleanup. This proves the generic process and transport boundary, not native Linux or utility-VM reattachment on real hardware.

The real Native Linux gate now crosses that process boundary with the actual driver. The launcher is parent-death-bound before it forks namespace children; after an owner SIGKILL, a replacement process revalidates the immutable configuration plus owner/launcher/init start-time identities, waits for the exact workload to disappear, and exposes a stopped cleanup tombstone. It never claims that a live stream was reattached or fabricates an exit code when no authenticated parent survived to reap it. Idempotent kill, empty inventory, explicit missing-exit evidence, stopped-only delete, and executor/cgroup cleanup are machine-checked on x86_64 and aarch64. Live process-session reattachment remains open for the Box B2 cutover.

Platform status

Host pathRetained real evidenceCurrent readiness and open gate
Native Linux x86_64/aarch64Rootful and helper-backed rootless lifecycle, including all six OCI default devices, /dev/ptmx, configured-init /dev/console, an explicit FIFO outside /dev, the immutable declared/default device boundary, and the bounded A3S Box device policy; SDK service transport; exec/PTY/I/O; init/exec scheduler and namespaced-sysctl read-back; cgroup update/stats; hooks; namespace and mount profiles; multi-container fencing; fault cleanup; owner-SIGKILL safe termination and stopped cleanup; 25 waves × 4 containers; x86_64/aarch64 Box production-owner composition through all four SDKs plus fresh-Box-process owner-death/restart gatesDefault inventory probe-only; explicitly opened development driver experimental. Live session reattachment, default cutover, production security, and OCI conformance remain
Linux KVM utility VMIndependent device/access/ioctl/API-version probes; deterministic x86_64 and AArch64 runtime archives and immutable ext4 roots; exact libkrun, firmware, exported kernel, and static Guest Agent compatibility sets; descriptor-pinned read-only root attachment; isolated create/configure/root/plain-vsock/release context gates; an isolated real-entry worker with descriptor-pinned KVM and runtime-share checks, pidfd owner death, kernel-authenticated Unix peer identity, protocol-v10 negotiation, and fail-closed cleanup evidence when KVM is unavailable. Both architecture lanes retain the 14-case pre-entry compatibility-drift matrix and invoke a KVM-gated 16-case lifecycle matrix, a scoped owner-death/restart gate, and a scoped 25-wave fresh-generation soak. A KVM-independent driver preflight rejects both shared-kernel classes, inexact generations, missing handoff ownership, and missing, linked, non-private, drifted, escaping-rootfs, or absolute-bind handoffs before creating a Guest-visible generation share. The soak audits generation fencing and replay plus per-wave process, marker, endpoint, descriptor, bundle-handoff, runtime-share, recovery-report, and configured Guest cgroupsPath lifetime. The public candidate owns one VM per exact generation, rejects host-kernel fallback, keeps bootstrap and writable shares separate, and remains non-registerableprobe-only; neither architecture has yet retained available lifecycle, recovery, and soak reports from real KVM hardware. Fresh-host reports for x86_64 and AArch64 plus the remaining real-entry negative-isolation profiles are required before promotion
macOS arm64/HVFPublic same-UID SDK host service; one dedicated VM per exact generation; manifest-bound immutable ext4 system image with pinned A3S Linux kernel and agent; read-only root disk plus separate writable runtime share; Guest-local devtmpfs sources for privileged OCI device nodes; a real protocol-v10 bridge with all 21 Guest operations; retained full protocol-v9 lifecycle, multi-container, namespace/rootfs enforcement, 3 no-delete cleanup points, 11 transport fault points, 180/180 workload-operation replacement paths, negative asset/authentication gates, and 25 fresh-VM waves; source revision a5a6b53 passed the revision-bound public-path gate across all 20 driver operations plus features/list/events, Host Service SIGKILL recovery, and a separate 25/25 fresh-VM soak with zero transient leaksexperimental on Apple Silicon. Every currently advertised public macOS/HVF function is implemented and the protocol-v10 public path is qualified at the recorded revision. Signed release-package qualification, OCI conformance, security review, upgrade/rollback compatibility, and longer release soak remain before supported
Windows x86_64/WHPXReal partition/context/guest gates, protocol-v9 lifecycle and filesystem sessions, direct driver qualification, protected per-generation shares, exact exit replay, owner death at both recovery fault boundaries, host-service reopen, stopped-only delete, and complete transient cleanup. The current implementation also builds a reproducible x86_64 ext4 system image, pins Linux 6.12.91 and all native boot assets, attaches the root read-only, and keeps the runtime share separateprobe-only; the complete SDK/recovery matrix must still pass with those exact assets on a fresh WHPX host. The v7 shim and Host retain the v6 in-process handle-restoration contract, but the complete fresh-host matrix has not retained that evidence yet

All retained Linux KVM entry, compatibility, lifecycle, recovery, and soak artifacts carry the shared provenance contract described below. This closes artifact identity ambiguity; it does not substitute unavailable-runner output for successful real-KVM evidence.

Linux discovery and Native Linux development must work when /dev/kvm is missing or unusable. KVM is an optional utility-VM driver, never a prerequisite for host-kernel execution.

On August 15, 2026, a focused Apple Silicon rerun passed all 14 journaled guest-after-response-write mutation cases with post-commit Guest acknowledgement. File and Filesystem also passed their complete nine-stage reopen and real owner-replacement matrices, 18/18 paths in total. The run used agent SHA-256 eea01813858f5dd16bed70cbfba87221da6daebb4201b7a628665aad3f615a7d and system-image SHA-256 e888c52e35ba8ed8f747d55bdc32316190dc317865e6919014e434a1e644e6ef.

The latest WHPX owner-death gate emitted a3s.oci.whpx-recovery-smoke-run.v1 from clean runtime commit 2d91cd0. That closes the service-restart evidence item. The immutable-image code and qualification artifact are now present, but they have not yet produced the fresh-host matrix required to promote the public candidate. The current shim also records its Windows handle inventory immediately before libkrun context creation and after VM exit; Host validation and the hardware soak reject any drift. This remains implementation evidence until the fresh-host matrix retains matching counts in every session.

Architecture

A3S Box (current Sandbox consumer; explicit Native Linux production route
         owns bundle/resource preparation and uses the long-lived SDK owner;
         default, MicroVM, and cross-platform cutover remain open)
a3s-oci CLI
containerd runtime-v2 shim


                  RuntimeClient
             in-process or bounded local IPC


              ┌──────────────────────┐
              │ HostRuntimeService   │
              │ validation           │
              │ generations + replay │
              │ recovery + quarantine│
              └──────────┬───────────┘

                 DriverRegistry
             isolation owner selected once
                 ┌───────┴────────┐
                 │                │
       NativeLinuxDriver     utility-VM driver
          host kernel        KVM · HVF · WHPX
                 │                │
                 │        isolated libkrun shim
                 │                │
                 │        authenticated guest agent
                 └───────┬────────┘

                   LinuxExecutor
          namespaces · mounts · hooks · pidfds
          cgroups · process I/O · confined filesystem · exact cleanup

Only the isolated a3s-oci-krun-shim loads checksum-pinned native libkrun assets. The SDK, CLI discovery path, durable host service, and Native Linux driver do not initialize a hypervisor library.

On Linux x86_64 and AArch64, a3s-oci-krun-shim context-smoke verifies and loads the selected native bundle, checks the firmware-exported kernel, and creates, configures, and releases one libkrun context. That command does not open /dev/kvm, enter a VM, or change the KVM driver's probe-only readiness. The stronger pre-entry gate also binds the exact static agent and immutable root disk from the same target manifest:

a3s-oci-krun-shim system-image-context-smoke \
  --system-image-manifest /absolute/path/to/system-image.json

It pins the manifest and raw image with read-only descriptors, rechecks every byte immediately before native API use, attaches the root read-only, and then releases the context. It still does not enter KVM or claim guest execution.

The public Linux API exposes KvmRuntimeDriver::open_candidate with a KvmRuntimeDriverConfig containing the isolated shim, writable runtime root, and immutable system-image manifest. It prepares an empty private bootstrap root separately from exact-generation runtime shares, delegates all 20 workload operations and six OCI hook phases through the shared utility-VM core, and disables Native Linux fallback. Its capability deliberately remains probe-only, so HostRuntimeService rejects normal registration until the real-host promotion gates below pass.

The separate authenticated entry gate adds a UID-owned mode-0700 generation share, a same-UID Unix endpoint, a pidfd-bound shim owner, and a direct isolated VM worker. The worker revalidates every non-KVM entry asset before it opens /dev/kvm, then repeats the complete compatibility and device checks after pinning the device and requiring API version 12. It enters only through the immutable system root. The Host accepts only the kernel-reported direct worker child before protocol-v10 token negotiation:

A3S_OCI_LINUX_KVM_SYSTEM_IMAGE_MANIFEST=/absolute/path/to/system-image.json \
  bash .github/scripts/linux-kvm-agent-entry.sh

The separate compatibility matrix stops at the configured worker boundary and does not require KVM:

A3S_OCI_LINUX_KVM_SYSTEM_IMAGE_MANIFEST=/absolute/path/to/system-image.json \
  bash .github/scripts/linux-kvm-compatibility-drift.sh

Its 14 cases cover manifest and raw-image replacement, same-size content mutation, and symlinks; architecture and runtime-target mismatches; Guest Agent version and digest drift; and runtime archive, libkrun, firmware, and exported kernel provenance drift. Every case must fail with no KVM-device access or VM entry and restore endpoint, shim-process, token-handoff, and runtime-share inventories. The machine-readable result uses a3s.oci.linux-kvm-compatibility-drift.v2.

On a host without usable KVM the authenticated entry command must fail after non-KVM setup, retain nested KVM evidence, and restore endpoint, process, and handoff inventories. When KVM is usable, the gate first requires a real authenticated boot and then runs a hidden qualification-only failure after /dev/kvm and API version 12 are verified but before libkrun enters the VM. Shim schema v7 records that exact boundary and the script rejects any endpoint, process, token, or runtime-share residue. This implementation does not promote the driver: successful real-entry evidence on both x86_64 and AArch64 plus the complete lifecycle, recovery, and soak matrices remain required.

The script retains normal entry in a3s.oci.linux-kvm-agent-entry.v1 and the injected boundary in a3s.oci.linux-kvm-post-probe-failure.v1. Both wrap the raw v10/v7 Host and shim reports with a3s.oci.linux-kvm-provenance.v1. The common object requires a clean checkout, binds the Git object format, actual checkout commit and tree, Linux platform and target architecture, and hashes the CLI, shim, runtime-assets manifest, selected runtime files, and system-image manifest. It also records the exact build profile, qualification profile, libkrun-kvm driver, and dedicated-vm isolation class. The other KVM gates reuse the same contract, so an otherwise green report from different source or runtime bytes cannot satisfy a promotion gate.

The KVM-gated lifecycle entry reuses the same Utility VM implementation as the Apple Silicon qualification instead of maintaining a second Linux-only test harness:

A3S_OCI_LINUX_KVM_SYSTEM_IMAGE_MANIFEST=/absolute/path/to/system-image.json \
  bash .github/scripts/linux-kvm-lifecycle.sh

The separate owner-death/restart entry exercises that candidate through an explicitly scoped Unix Host Service without making it normally registerable:

A3S_OCI_LINUX_KVM_SYSTEM_IMAGE_MANIFEST=/absolute/path/to/system-image.json \
  bash .github/scripts/linux-kvm-recovery.sh

The bounded soak uses its own qualification scope and one durable Host Service:

A3S_OCI_LINUX_KVM_SYSTEM_IMAGE_MANIFEST=/absolute/path/to/system-image.json \
  bash .github/scripts/linux-kvm-soak.sh

When KVM is available, the lifecycle entry downloads the pinned Alpine fixture, prepares two bundles under a private runtime share, and runs 16 cases: one full lifecycle, one multi-container lifecycle, three no-delete cleanup boundaries, and all 11 transport fault points. The a3s.oci.linux-kvm-lifecycle-matrix.v2 report retains every nested runtime report plus endpoint, process, runtime-state, bootstrap, token/recovery, and marker cleanup checks. Without usable KVM it skips the fixture download and emits status: unavailable with zero cases. That keeps CI honest about runner capability; it does not count as a hardware pass. The a3s.oci.linux-kvm-recovery-matrix.v2 entry likewise skips Alpine when KVM is unavailable. With KVM it kills the live Host Service, requires authenticated SIGKILL recovery, opens a distinct replacement socket owner, replays exact stopped state and Wait, and proves stopped-only Delete plus transient cleanup. The soak also skips Alpine on an unavailable host; its retained aggregate schema is a3s.oci.linux-kvm-soak-matrix.v2. On KVM it runs 25 fresh generations and requires every process, descriptor, endpoint, handoff, share, recovery record, and Guest marker to return to baseline after each wave. Available lifecycle, recovery, and soak reports are still required from fresh x86_64 and AArch64 KVM hosts, followed by the remaining real-entry negative-isolation profiles.

OwnerKeepsMust not absorb
A3S Box product planeDesired state, images/builds, named volumes, product networks, Compose, health/restart policy, log retention, and secret authorizationActual PID/VM identity or runtime operation journals
OCI Runtime control planeExact OCI validation, actual state, generations, replay, exit status, driver selection, recovery, and cleanupRegistry pulls, image builds, Compose, or silent isolation fallback
Platform execution planeLinux enforcement, utility VM, transport, process control, and runtime attachmentsProduct orchestration or a second durable lifecycle

Run the real gates

The portable workspace gate is:

cargo fmt --all -- --check
cargo test --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings

Real execution gates require a prepared host and isolated runtime root.

HostEntry pointGuide
Linux x86_64/aarch64bash .github/scripts/native-linux-smoke.sh and bash .github/scripts/linux-kvm-lifecycle.sh with the pinned KVM manifestNative Linux development
Apple Siliconcargo run -p a3s-oci-cli -- hvf-smoke followed by the signed utility-VM profilesmacOS HVF development
Windows x86_64scripts/windows-whpx-driver-smoke.ps1 and scripts/windows-whpx-recovery-smoke.ps1 with a verified container-rootfs archive and windows-system-image manifestWindows WHPX development

The Linux smoke prepares an explicit user-owned cgroup-v2 subtree for the rootless v4 gate. Before Tokio starts, the CLI retains that exact delegation, starts a parent-bound effective-root helper, and permanently drops the runtime owner to its real identity. Ordinary rootless launch uses the helper to provide the six OCI default device nodes and install the same immutable inventory boundary as rootful execution; it does not invent a linux.resources.devices policy. The separate A3S Box profile also exercises bounded device-access BPF replacement and rollback. Runtime commit bed43d2 passed the full policy profile on x86_64 and aarch64 in CI run 31714178349. The v4 gates verify create, live update/stats, workload-proven pause/resume, durable events, all six nodes, exact policy updates where requested, and complete cgroup, runtime, session, and marker cleanup. Broader delegated profiles remain unadvertised promotion work.

The rootful device-boundary profile intentionally omits linux.cgroupsPath, grants CAP_MKNOD, and proves that only declared/default identities remain usable. It also remounts a nodev bind source with dev inside the workload and verifies that the late device access still fails with EPERM. Run the focused gate with A3S_OCI_NATIVE_FOCUS=device-boundary bash .github/scripts/native-linux-smoke.sh.

Writable OCI cgroup mounts now follow the OCI 1.3 delegation boundary. The executor changes ownership only for an exact source: "cgroup" mount at /sys/fs/cgroup, with no ro option and a newly created cgroup namespace. It maps process.user.uid to the host UID, preserves the group, and changes only the container cgroup directory plus existing files listed by /sys/kernel/cgroup/delegate; if that inventory is absent, it uses the three normative fallback files. The focused Native Linux gate also proves that a read-only cgroup mount and unlisted controller files keep their ownership: A3S_OCI_NATIVE_FOCUS=cgroup-ownership bash .github/scripts/native-linux-smoke.sh.

The rootful terminal-init profile derives init I/O from process.terminal, applies the configured 120x40 size before launch, and binds the exact PTY slave to /dev/console. It also creates a configured FIFO outside /dev with mapped mode and ownership. The gate runs once with a new console target and once with a caller-owned placeholder; Delete removes only runtime-created targets and restores the pre-existing file unchanged.

When a container creates a private mount namespace but joins an existing user namespace, the executor pins and type-checks that namespace, observes its real UID/GID maps through a short-lived namespace helper, and rechecks the namespace identity before entry. The same detached-mount path then supplies the six default devices with namespace-root ownership. Native Linux multi-container v19 and real Apple Silicon utility-VM multi-container v11 both verify the device type, major/minor number, mode, ownership, workload access, and cleanup. The same reports cover the image's /dev with a fresh tmpfs and require the four OCI Linux links to resolve to their exact /proc/self/fd targets after every configured mount is in place.

Mount-option discovery and execution now share the SDK's pinned 61-entry OCI 1.3 registry. The executor consumes all required and recommended control options without leaking them into filesystem data, treats unknown strings as filesystem-specific data, and returns a typed Unsupported error for the optional tmpcopyup behavior. Feature discovery reports the 60 implemented OCI names plus the rnodev extension, in sorted order, and does not advertise tmpcopyup.

Configured host services also report every built-in annotation that can alter runtime behavior, together with annotation-backed extensions implemented by their active drivers. Probe-only discovery stays empty, and driver-specific extensions such as bundle handoff appear only when the selected driver set actually advertises them.

These commands can require root privileges, hypervisor access, signed artifacts, or destructive cleanup within an explicitly supplied test root. Read the linked host guide before running them.

Evidence, not slogans

The repository turns release claims into checked inventories:

EvidenceCurrent lock
Named OCI schema properties and enum values classified423
OCI schema dispositions257 enforced · 2 validated · 75 rejected unsupported · 89 rejected inapplicable · 0 pending · 0 conformant
Reviewed schema evidence334 applicable items in 29 bindings · 131 rules · 95 tests
Pinned OCI JSON Schema suites19 / 19 upstream fixtures · 4 / 4 launch profiles with configuration, Features, and created/running/stopped State documents
RFC 2119 occurrences across 15 pinned normative OCI 1.3 documents764
Typed semantic validation rules95
Owner-bound non-semantic rules156
OCI normative dispositions578 enforced · 51 validated · 12 conformant · 14 reviewed external · 0 pending review
Registered durable commit fault stages741
Durable-state replacement qualificationmacOS/Linux/Windows complete, including a real Linux bind mount and the Windows reparse-point matrix
Before/after RuntimeDriver fault boundaries44
Authenticated agent operation-stage fault pairs180
Portable Create/State/Start/Kill/Delete/Wait/Exec/SignalProcess/WaitProcess/Pause/Resume/Processes/Update/Stats/ReadOutput/WriteStdin/CloseStdin/Resize/File/Filesystem host-service reopen pairs180
Real HVF Create Host/Guest plus Host shutdown interruption and cleanup stages11
Real HVF durable Create reopen plus VM/session-owner replacement paths9
Real HVF durable State reopen plus VM/session-owner replacement paths9
Real HVF durable Start reopen plus VM/session-owner replacement paths9
Real HVF durable Kill reopen plus VM/session-owner replacement paths9
Real HVF durable Delete reopen plus VM/session-owner replacement paths9
Real HVF durable Wait reopen plus VM/session-owner replacement paths9
Real HVF durable Exec reopen plus VM/session-owner replacement paths9
Real HVF durable SignalProcess reopen plus VM/session-owner replacement paths9
Real HVF durable WaitProcess reopen plus VM/session-owner replacement paths9
Real HVF durable Pause reopen plus VM/session-owner replacement paths9
Real HVF durable Resume reopen plus VM/session-owner replacement paths9
Real HVF durable Processes reopen plus VM/session-owner replacement paths9
Real HVF durable Update reopen plus VM/session-owner replacement paths9
Real HVF durable Stats reopen plus VM/session-owner replacement paths9
Real HVF durable ReadOutput reopen plus VM/session-owner replacement paths9
Real HVF durable WriteStdin reopen plus VM/session-owner replacement paths9
Real HVF durable CloseStdin reopen plus VM/session-owner replacement paths9
Real HVF durable Resize reopen plus VM/session-owner replacement paths9
Real HVF durable File reopen plus VM/session-owner replacement paths9
Real HVF durable Filesystem reopen plus VM/session-owner replacement paths9
Real HVF operation replacement coverage180 / 180 paths (20 / 20 operations)
Real HVF journaled post-response acknowledgement rerun14 / 14 mutations on August 15, 2026
Real HVF lifecycle/transport cleanup fault points14 / 14
Real HVF immutable-system-image soak25 / 25 fresh VMs (75 primary generations)
macOS HVF R2M implementation gates15 / 15
Public macOS HVF Host Service implementationComplete; revision a5a6b53 passed 23/23 operations, owner replacement, and 25/25 fresh VMs
Linux KVM owner-death/restart entryImplemented for x86_64 and AArch64; fresh-host available evidence remains 0 / 2 architectures
Linux KVM bounded soak entryImplemented at 25 fresh generations for x86_64 and AArch64; fresh-host available evidence remains 0 / 2 architectures
Guest operations behind protocol v1021 (20 public workload operations + 1 maintenance acknowledgement)

The locks prove inventory and exercised boundaries, not full conformance by themselves. The OCI 1.3 normative inventory has no unclassified entries, but upstream lifecycle suites, adversarial security, upgrade compatibility, and exact release-artifact qualification must all pass before a driver becomes supported.

Still intentionally open

  • real-kernel Intel RDT qualification on CAT/MBA-capable Linux hosts;
  • real-host qualification of descriptor-confined filesystem sessions on each remaining utility-VM driver;
  • production-ready Native Linux and utility-VM drivers;
  • live Native Linux process-I/O reattachment across owner death and exact terminal evidence when a persistent authenticated reaper can retain it;
  • fresh-host qualification of the implemented immutable WHPX system root, and real-entry qualification of the implemented KVM system root;
  • utility-VM hook recovery and security certification;
  • the default and cross-platform A3S Box cutover, plus the remaining containerd compatibility, packaging, and cross-driver gates;
  • checkpoint/restore and later attachment extensions;
  • signed-package, upgrade, rollback, security, and long-duration release gates.

Workspace map

crates/sdk/             public async OCI contract, bundle validation, local IPC
crates/core/            lifecycle, isolation, readiness, and capability types
crates/runtime/         durable host service, drivers, probes, state, reports
crates/agent-protocol/  authenticated host/guest wire contract
crates/agent/           static Linux guest agent and shared LinuxExecutor
crates/krun/            isolated shim plus pinned native runtime bundles
crates/cli/             capability inspection and real-host qualification gates

Documentation

Development

Run checks from the repository root:

cargo fmt --all -- --check
cargo test --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps

Cross-check the supported Linux compilation targets without treating a parent monorepo as the Rust workspace:

cargo clippy --target x86_64-unknown-linux-gnu \
  --workspace --all-targets -- -D warnings
cargo clippy --target aarch64-unknown-linux-gnu \
  --workspace --all-targets -- -D warnings

Tagged archives contain host diagnostics and the matching platform assets. Package availability never overrides the readiness reported by the exact binary's features result.

License

A3S OCI Runtime is available under the MIT License.