Windows WHPX Development
August 20, 2026 · View on GitHub
Current scope
The Windows foundation establishes an honest evidence boundary before OCI lifecycle code is allowed to launch workloads.
The runtime:
- loads
WinHvPlatform.dllonly from the Windows system directory search scope; - resolves
WHvGetCapability,WHvCreatePartition, andWHvDeletePartition; - queries
WHvCapabilityCodeHypervisorPresent; - optionally creates and deletes a WHPX partition object as a smoke test;
- links the
a3s-libkrun-sys 3.1.0FFI ABI only into an isolated shim and stages a runtime-owned, checksum-verified native bundle with firmware provenance fromA3S-Lab/Box@93fc281and segmented WHPX stream plus writable virtio-fs flush fixes fromA3S-Lab/libkrun@dc5519f; - creates, configures for one vCPU and 128 MiB, replaces implicit TSI with a zero-feature plain-vsock device, maps guest port 4093 to a validated bare Windows pipe name, and releases one real libkrun context without entering a VM;
- creates the host side of that mapping as a first-instance-only local named pipe, limits its protected DACL to the runtime principal and LocalSystem, verifies the live handle's owner and access entries, requires the connected client PID to equal the previously spawned shim PID, and negotiates the authenticated agent protocol with a simulated local guest;
- enters a one-vCPU, 512 MiB utility VM, executes
/bin/shfrom a supplied Linux rootfs, and verifies a guest-written marker through virtiofs; - boots
/usr/bin/a3s-oci-agent, carries its host-CID port 4093 connection through libkrun to the protected pipe, authenticates the exact shim PID and one-time token, negotiates protocol version 10, advertises 20 workload operations plus the maintenance acknowledgement, and waits for zero guest/shim exit; - runs a fixed OCI bundle through distinct create, start, init signal/wait, exact-target exec, process signal/wait, live resource update and stats, pause/resume, process inventory, captured output, piped stdin, controlling PTYs, terminal resize, and delete calls, verifies replay and cleanup, and keeps the built-in driver disabled;
- emits stable JSON evidence through
a3s-oci features,a3s-oci whpx-smoke,a3s-oci-krun-shim context-smoke, anda3s-oci-krun-shim vm-smoke, plus nested host/shim evidence througha3s-oci agent-vm-smokeanda3s-oci oci-vm-smoke; - stages the one-time guest token in a create-new, fixed-size bootstrap file instead of exposing it in the Windows guest command line or environment, rejects alternate paths and links, and removes the file on every exit;
- binds each shim to the exact host owner process and terminates the VM if that owner disappears, including during startup and a stuck shutdown;
- exposes a repeatable hardware soak covering serial, parallel, same-VM multi-container, network, storage, init, typed-negative, lifecycle-fault, and owner-death profiles with machine-readable resource and inventory evidence;
- gives each candidate-driver VM only its exact protected
shares/<container>/<generation>directory through a second virtio-fs device, mounts the fixeda3s-oci-runtimetag before guest token access, and leaves the system root disjoint from writable bundle and handoff data; - exposes a versioned, qualification-only direct
RuntimeDrivergate that verifies create/start/kill/wait replay, authenticated shutdown-report publication, stopped-only delete, and complete nominal cleanup while preservingprobe-onlyreadiness; - exposes a separate multi-process gate that force-terminates the exact
host-service owner, injects the before- and after-
Recoverboundaries, reopens durable state, replays the authenticated signal-9 exit result, and proves stopped-only delete plus complete host/share cleanup. Its launch override is crate-private and scoped only to this gate, so normal discovery remainsprobe-only; - builds a byte-reproducible Alpine 3.22.5 x86_64 ext4 image containing the
protocol-v10 agent, binds Linux 6.12.91 and every Box/libkrun/firmware
revision and digest in
a3s.oci.windows-system-image.v1, pins all boot inputs with read-only Windows handles, and switches from the empty bootstrap share to that read-only block root before starting the agent.
Product bundle preparation no longer needs to guess the runtime generation.
An explicitly annotated, digest-bound dev.a3s.bundle-handoff attachment lets
the product stage one portable bundle below the protected create-operation
path. Once durable state allocates the exact generation, the WHPX driver moves
that directory atomically into its exact runtime share. Retries require the
same source or matching destination evidence, while cleanup removes only a
marker-proven runtime-owned bundle. Requests without the extension retain the
strict fixed-bundle containment behavior used by qualification gates.
The capability query follows the
Windows Hypervisor Platform API.
The smoke operation uses
WHvCreatePartition
and always attempts the matching delete operation.
What the smoke proves
A successful WHPX smoke proves that:
- the WHPX API DLL and required symbols are present;
- the Windows hypervisor reports itself present;
- the process can create and release a WHPX partition object.
A successful libkrun context smoke additionally proves that:
- the exact packaged native runtime pair can be loaded;
krun_create_ctxsucceeds;krun_set_vm_configaccepts the certified single-vCPU configuration;krun_disable_implicit_vsock,krun_add_vsock(..., 0), andkrun_add_vsock_port_windowsaccept the fixed agent mapping;krun_free_ctxreleases the context.
The real Windows host-pipe test additionally proves that:
- the runtime and shim consume one validated endpoint type and fixed port;
- the runtime obtains an unguessable endpoint nonce and a nonzero 256-bit session token from the OS random source;
- the pipe rejects remote clients and competing first-instance ownership;
- the live pipe owner is the runtime principal;
- its protected DACL contains only full-access entries for that principal and LocalSystem, with no inherited or unexpected entries;
- an unexpected connected process is rejected before the session token is written;
- protocol version negotiation and token authentication succeed over the protected pipe with the exact core operation advertisement.
A successful libkrun VM smoke additionally proves that:
- the packaged kernel reaches Linux userspace through WHPX;
/bin/shexecutes from the supplied rootfs;- Windows virtiofs preserves Linux
READLINKsyntax for standard absolute OCI rootfs links; - the guest can write through the shared root and the host observes the exact marker contents;
- the guest returns exit code zero and the host removes the marker;
- fatal WHPX exits are not accepted as successful workload completion.
A successful end-to-end agent VM smoke additionally proves that:
- the manifest-bound ext4 image supplies the static musl guest agent and fixed Linux userspace;
- the image is attached read-only and remains separate from the writable runtime share;
- the manifest, raw image,
krun.dll, andlibkrunfw.dllretain their exact sizes, SHA-256 digests, file identities, and loaded-module paths through VM entry; - guest AF_VSOCK reaches the protected Windows named pipe through libkrun;
- only the exact spawned shim PID is accepted before the token is sent;
- the real guest authenticates the one-time token and negotiates protocol version 10;
- the agent version and
x86_64guest architecture are reported; - the guest advertises exactly create, state, start, kill, delete, wait, exec, signal-process, wait-process, pause, resume, processes, update, stats, read-output, write-stdin, close-stdin, resize, file, and filesystem;
- the shim reports every VM configuration stage and a zero guest exit;
- the host rejects an existing console destination rather than overwriting it.
A successful fixed OCI VM smoke additionally proves that:
- the accepted bundle is a strict descendant of the supplied writable runtime
share and is addressed below
/run/a3s-oci-runtimein the guest; - create establishes a new UTS namespace, applies the configured hostname and domainname, and reports ready only afterward;
- when configured, create establishes a new mount namespace, makes
/recursively private, self-binds the rootfs, completespivot_root, and reports ready only afterward; - create applies existing-target mount entries in listed order, including relative bundle bind sources, common VFS flags, propagation modes, and filesystem-specific data;
- create atomically enters requested IPC, network, cgroup, and PID namespace setup before reporting ready;
- create returns
createdand the authenticated host-visible configured process PID without running it; a dedicated supervisor is PID 1 and the configured process is PID 2+ in a requested new PID namespace; - state and an exact create retry match the original result;
- start releases a randomly named abstract Unix socket only after the parent verifies the launcher → PID 1 → configured-process identity chain;
- the wrapper applies the accepted rootfs, credentials, umask, and
no_new_privileges, then callsexecve; - the host observes
runningand the exact workload marker; - a bounded wait returns
DeadlineExceededwhile the workload is running; - exact-target exec and its retry return the same authenticated process, a duplicate process ID is rejected, bounded process wait times out while the process runs, pidfd signal and its retry succeed, and repeated process wait returns the same terminal signal;
- process inventory returns exactly the live init and exec; replayed pause freezes their shared cgroup and stops an observed progress counter, while replayed resume thaws it and the counter advances again;
- an exact resource update and its retry apply memory, CPU, cpuset, and PID controls, while repeated stats return normalized generation-fenced cgroup counters;
- an exact-target process accepts piped stdin, returns captured stdout/stderr through bounded byte-cursor pagination with EOF, accepts repeated close, and rejects writes after close or exit;
- a terminal process proves controlling-PTY allocation, exact initial and
resized dimensions, interactive input, merged output, one ordered cursor,
EOF, and idempotent
VEOFclose; - another live exec is terminated and reaped automatically when init exits;
- kill delivers
SIGTERM, its exact retry replays the original result, wait returns and replays exit code zero, and state then observesstopped; - stopped-only delete and its exact retry succeed;
- state returns NotFound after delete;
- the marker is removed and VM shutdown leaves no new agent runtime directory or A3S process.
A successful direct WHPX RuntimeDriver smoke additionally proves that:
- the formal driver accepts only a bundle strictly below the exact protected
shares/<container>/<generation>directory; - the candidate remains non-registerable and
probe-onlythroughout the run; - create, state, create replay, start, start replay, bounded running wait, kill, kill replay, exact wait, repeated wait, stopped state, and stopped-only delete all cross the driver boundary;
- the guest durably publishes its authenticated shutdown report through the writable virtio-fs share and the shim verifies the v2 share contract;
- delete removes the driver attachment, VM session, transient token/report directories, normalized recovery artifacts, workload marker, and host processes.
A successful WHPX owner-death recovery smoke additionally proves that:
- the parent starts with no A3S OCI process and force-terminates only the exact owner PID after one exact-generation workload is running and its marker is visible;
- the owner-bound shim survives long enough to stop the VM, collect the guest's authenticated shutdown report, and persist the exact signal-9 init result;
- a
Recoverbefore-call fault retains the protected pending/report handoff, and an after-call fault retains the normalized report for the next service; - a newly opened
HostRuntimeServiceobserves stopped state and replays the exact wait result, while the recovered driver tombstone replays kill without claiming that a new service-level signal was delivered to a stopped process; - stopped-only delete removes durable state, the driver attachment, VM session, session/report handoff directories, normalized recovery artifacts, workload marker, and every owned host process;
- the ordinary candidate remains
probe-only, and only the crate-private qualification constructor reports its exact scoped override.
A3S Box qualification owner
a3s-oci box-whpx-qualification-service exposes the same durable SDK service
over a protected local Windows named pipe for the explicit A3S Box product
lifecycle gate. It does not register or promote the public WHPX candidate. The
service opens a separate crate-private override whose capability evidence is
exactly qualification_override=box-product-lifecycle-only; the owner-death
gate retains its different host-service-owner-death-only scope.
a3s-oci box-whpx-qualification-service `
--shim C:\a3s\bin\a3s-oci-krun-shim.exe `
--runtime-root C:\a3s\oci-runtime `
--vm-rootfs C:\a3s\oci-runtime\bootstrap `
--system-image-manifest C:\a3s\system-image\system-image.json `
--state-root C:\a3s\oci-runtime\state `
--pipe '\\.\pipe\a3s-oci-box-qualification' `
--ready-file C:\a3s\oci-runtime\box-service-ready.json
The optional readiness file is created atomically only after the driver,
durable state, protected pipe ACL, and first pipe instance are ready. It uses
schema a3s.oci.box-whpx-service-ready.v2, records the owner PID, exact
endpoint and roots, and selected system-image manifest, and is removed on
graceful shutdown. A stale file after owner death is never connection
evidence; clients must still complete the SDK handshake and feature preflight.
This owner accepts the operation-scoped portable-bundle handoff contract used
by Box. The source must be exactly
bundle-handoffs/<container>/<create-operation>/bundle below the runtime root,
with a normalized relative root.path and no absolute bind source. The driver
atomically moves a valid source into its allocated generation before launch.
Box converts its host-side image manifest to the SDK-owned portable contract
and adds
dev.a3s.oci.rootfs-metadata=a3s.oci.rootfs-metadata.v1. Before any OCI mount
is installed, the guest validates and consumes the fixed
.a3s-oci-rootfs-metadata.v1.json manifest from the relative rootfs, then
restores Linux ownership and mode data that cannot be represented directly by
the Windows backing filesystem. Replay rejects an absolute root, a user or
missing mount namespace, a wrong annotation, manifests above 16 MiB or 250,000
entries, duplicate/reserved/escaping paths, symlink parents, type or
symlink-target drift, and any failed lchown, chmod, deletion, or directory
sync. All entries are validated before the first metadata mutation.
Hardware soak gate
Run the complete gate from an x86-64 Windows host with WHPX enabled:
Every successful CI run retains windows-whpx-qualification for 14 days. Its
v2 manifest binds the exact source and workflow commits, and lists every file
size and SHA-256 digest. bin/ contains the CLI, shim, krun.dll, and
libkrunfw.dll; the disjoint system-image/ directory contains the raw ext4
image, compressed release copy, and a3s.oci.windows-system-image.v1
manifest. CI also publishes the same image separately as
windows-system-image. guest-agents-musl remains available for development,
but these qualification scripts boot the agent embedded in the immutable
image and do not copy a loose agent into a guest root.
gh run download <run-id> --repo A3S-Lab/OCI-Runtime `
--name windows-whpx-qualification --dir C:\a3s\oci-artifacts\windows
For a build-free qualification, copy the four files from bin/ into
target\debug, keep system-image/ separate, and pass its
system-image.json path with -SystemImageManifest. Then pass -SkipBuild to
the focused scripts. The scripts still bind their report to the checked-out
commit, so that checkout must match source_commit in the artifact manifest.
A pull-request artifact can name GitHub's temporary merge commit as
workflow_commit; a main push artifact has identical source and workflow
commits.
powershell.exe -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\windows-whpx-soak.ps1 `
-RootfsArchive C:\path\to\alpine-minirootfs.tar `
-SystemImageManifest C:\a3s\oci-artifacts\windows\system-image\system-image.json
Run the nominal formal-driver gate separately:
powershell.exe -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\windows-whpx-driver-smoke.ps1 `
-RootfsArchive C:\path\to\alpine-minirootfs.tar `
-SystemImageManifest C:\a3s\oci-artifacts\windows\system-image\system-image.json
Run the owner-death and host-service recovery gate separately:
powershell.exe -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\windows-whpx-recovery-smoke.ps1 `
-RootfsArchive C:\path\to\alpine-minirootfs.tar `
-SystemImageManifest C:\a3s\oci-artifacts\windows\system-image\system-image.json
The default profile requires:
- 25 consecutive full protocol-v10 OCI lifecycles;
- three waves of two independent VMs and three two-container lifecycles inside one authenticated VM;
- cleanup without a normal delete after create, start, and kill;
- isolated and inherited network namespace identities;
- persistent read-write and enforced read-only bind volumes;
- a delayed successful init script and an expected nonzero init failure, both with state written through a bind volume;
- ten exact host/guest validation rejections;
- owner termination at 0, 250, 1000, and 2500 milliseconds after shim spawn.
Success additionally requires exact requested/completed counts, no bootstrap
token directory, guest runtime directory, marker, host CLI, or host shim
remaining, every operation sample marked pass, a bounded owner-to-shim exit,
and bounded host working-set and log growth. The evidence directory contains
host.json, start/final process inventories, capability-results.tsv,
operations.tsv, resource-samples.tsv, every command report and console,
summary.json, and a final verify.out.
The August 1, 2026 direct-driver qualification ran from clean commit
7bb09dff81b5445e275c31faff6592ad4c32a45f and emitted
a3s.oci.whpx-driver-smoke-run.v1. From 12:50:37Z through 12:51:08Z it built
the pinned artifacts and passed every nominal lifecycle, replay, exact-share,
authenticated recovery-publication, and cleanup field. It used rootfs SHA-256
4b4daa9fe2fc696c4919c4412a4c3d3e770d8fb70292a004a2c72f5096175282,
agent SHA-256
b97ba3f0989432a13873f825e37d66cbb4244bbe7c126d537b0518190ff4091d,
shim SHA-256
e41c337f8454d3276f8062a92458e7eb8e264fa90e10cc452c96d5c5f4728eb3,
and krun.dll SHA-256
f21293b65ee16058c9014b543c708d84c50dc28d7775dbd77bac32faabafa59e.
The retained report and summary SHA-256 values are respectively
b9442b1d8da3d091f5a1b4099697fdf50dda932fe3bcb31a95c100fd361aec6e
and 64d898fcad1f1ad597e8ad98a19233dec260a3d7831de39178ef24562766047f.
The August 1, 2026 owner-death qualification ran from clean commit
2d91cd04f6ec1ecd9ea3fce4673be6fdc2b6f631 with an empty recorded worktree and
emitted a3s.oci.whpx-recovery-smoke-run.v1. From 13:41:20Z through 13:41:30Z
it rebuilt the artifacts, force-terminated owner PID 57496 only after running
and marker readiness, injected both Recover fault boundaries, reopened the host
service, replayed exact signal 9, replayed the recovered driver tombstone kill,
completed stopped-only delete, and passed every cleanup field. It used rootfs
SHA-256 4b4daa9fe2fc696c4919c4412a4c3d3e770d8fb70292a004a2c72f5096175282,
agent SHA-256 b97ba3f0989432a13873f825e37d66cbb4244bbe7c126d537b0518190ff4091d,
CLI SHA-256 23db303dfae37a1b2cb2973cb74d3d52a441abe91f588b41fdf9a26686cc488e,
shim SHA-256 8072612e5a1e5f0dea69b80697bdffa2a19fa54dd0c7f1e2f43a4d821146e189,
and krun.dll SHA-256
f21293b65ee16058c9014b543c708d84c50dc28d7775dbd77bac32faabafa59e.
The retained report and summary SHA-256 values are respectively
db7daff5d912d9d0786a660c9321274aa3ee1d666368792b3985412a5a682734
and c8179b2f2f4ed38f1820103645a2d96487ea0cdfb98a7884181e2082737d5270.
The focused August 1, 2026 transport qualification used the Alpine minirootfs
SHA-256
4b4daa9fe2fc696c4919c4412a4c3d3e770d8fb70292a004a2c72f5096175282,
guest-agent SHA-256
e78261ee3c6628045692003d59c948e965eafbf44291797ce705319dccfc9826,
and krun.dll SHA-256
ab8ceb013795fa8b43a3793f9579179c0afb9608430af1c21f6e9145cf27d7d9.
In 63.970 seconds it passed one serial lifecycle, two parallel lifecycles,
five workload cases, nine typed negative cases, and owner termination at four
timing points. Its storage create request crossed the 4 KiB WHPX stream
boundary, and every case left zero A3S host processes and zero guest
bootstrap/runtime directories. This is focused transport regression evidence;
the default profile above remains the broader hardware gate.
fixtures/utility-vm/config.windows.json is an explicit Windows qualification
profile. It requests UTS, mount, IPC, network, cgroup, and PID namespaces. It
does not request user or time namespaces because those paths hang in the
current WHPX utility kernel, and the resource update omits only the unavailable
swap controller. The compatibility marker still has its historical
user-time-v1 payload; the soak never treats that string as evidence that
Windows applied user or time namespaces.
The July 24, 2026 qualification used the untouched Alpine 3.22.5 x86_64
minirootfs archive with SHA-256
4b4daa9fe2fc696c4919c4412a4c3d3e770d8fb70292a004a2c72f5096175282.
The fixed runtime completed five consecutive marker runs without setting
LIBKRUN_WINDOWS_HYPERV_ENLIGHTENMENTS.
The fixed OCI lifecycle qualification used the 6,328,408-byte static musl agent
with SHA-256
4b21a230d4183abe053823a63893f5ab0663c118811c81229bdfba0816fc9b81.
Its report selected protocol version 1, identified the guest as x86_64,
verified every then-current fixed lifecycle field, retained the complete
successful shim report, and returned exit status zero. This historical run
predates the protocol-v2 wait gate and does not qualify the current report
schemas.
The UTS qualification configured hostname a3s-smoke and domainname
runtime.test, checked the hostname from the workload, and crossed the create
barrier only after the wrapper read both applied values back with uname.
The mount qualification requested new UTS and mount namespaces in the same
bundle. It first rbind-mounted a relative bundle source onto /mnt, then
mounted proc at /mnt/proc, a destination that only existed because the first
entry had already run, and finally mounted tmpfs from a relative destination
onto /tmp. The workload verified both filesystem types through
/proc/self/mountinfo and completed the full lifecycle after pivot_root. A
companion bundle omitted the mount namespace; create retained the exact typed
Unsupported rejection and left no guest runtime directory. A joined-mount
namespace negative was rejected by that historical agent.
The namespace qualification combined that ordered mount sequence with new IPC,
network, and cgroup namespaces. The workload compared
/proc/self/ns/{ipc,net,cgroup} with guest PID 1 and produced its marker only
after all three identities differed. The full lifecycle and cleanup report
passed. A companion bundle supplied /proc/1/ns/net as a network namespace
join path; the historical agent retained the exact typed Unsupported
rejection and left no guest runtime directory.
The PID qualification used the 6,371,704-byte static musl agent with SHA-256
45d27bfdfec50ddedabd1f11a143dba4c11b4f472e7d2627a686594a0c514f6d.
The supervisor forked a container init that required shell PID 1 and a matching
/proc/1/ns/pid identity before writing the marker. Create returned
authenticated host-visible PID 396, the complete lifecycle and cleanup report
passed, and the VM exited cleanly. A companion bundle joined
/proc/1/ns/pid; create retained Unsupported at
linux.namespaces[5].path and left no guest runtime directory.
The libkrun dependency is target-specific to the isolated shim. The main runtime, CLI, and SDK dependency graphs do not contain it, and the Linux target does not build it.
The fixed-bundle smokes do not prove that:
- the pinned immutable A3S system image boots;
- the rootful user/time namespace slice now exercised on native Linux and macOS, namespace joins, recursive or ID-mapped mounts, tmpfs, capabilities, seccomp, or hooks work through WHPX;
- arbitrary shared-guest-kernel isolation policies work; the current driver intentionally owns one dedicated VM per container;
- the driver is production ready.
For that reason, driver readiness remains probe-only even after all smokes
succeed. Driver resolution must reject probe-only readiness rather than
silently treating host capability as runtime support.
The runtime contains a qualification-only WhpxRuntimeDriver candidate.
It uses the same twenty-operation adapter as native Linux, owns one VM per
exact dedicated-VM generation, retains the VM across retryable create calls,
and reaps terminal create failures, deletes, and driver shutdown exactly once.
Opening it requires an empty bootstrap directory below the protected runtime
root, a manifest and image outside that mutable tree, and a disjoint
runtime-created shares parent. Create accepts a bundle only below the exact
<container>/<generation> share, exports only that directory, and rejects
cross-generation or external paths before launching a VM. The shim stages
token and recovery files in the share and emits v4 evidence for the read-only
block root, fixed native boot assets, and separate virtio-fs device; the host
requires the same manifest digest it retained before launch and includes that
digest in the durable driver binding used after host-service reopen. Its
reported readiness deliberately stays probe-only, so the durable host
service cannot register it yet.
The generic host now has an idempotent startup recovery handshake. WHPX uses
the shim's existing owner-PID watcher as its fail-closed contract: when a new
host process has no live in-process session for a durable generation, the old
VM is treated as owner-death-terminated and an exact stopped tombstone is
installed. state, idempotent kill, empty processes, and delete remain
safe. A live session in the same process is queried through the authenticated
agent and its generation plus configuration digest are revalidated.
An interrupted durable creating transition cannot legally become stopped
directly, so recovery retains its tombstone without committing an observation;
replaying the original create then returns a terminal error and the existing
durable failure path quarantines that generation.
The guest side of the next recovery gate is implemented: complete executor
shutdown emits a bounded, exact-generation report containing the canonical
configuration digest and real init exit status, authenticated with the
ephemeral session token. The owner-PID shim preserves the one-time guest path
during its 15-second cleanup grace, validates the authentication tag after the
VM exits, removes the guest copy, and atomically commits only the normalized
report into a protected host recovery directory outside the writable share. A
plain, protected pending marker spans VM launch through successful or failed
handoff. A restarted host now parses only the normalized report, rechecks the
exact target and durable configuration digest, commits stopped, and caches
the real init result through the durable wait path. When only the marker is
present it waits through the shim's bounded owner-death grace and fails
retryably on overrun instead of racing ahead. The report is retained across
both sides of the recovery fault boundary and removed only by exact-generation
delete. If neither authenticated evidence nor a pending handoff exists, the
stopped tombstone remains usable for cleanup while wait still fails instead
of inventing a result. The nominal direct-driver path and the
owner-death/service-restart path now have real WHPX evidence. The retained
a3s.oci.whpx-recovery-smoke-run.v1 report at clean commit 2d91cd0 covers
exact owner termination, both recovery fault boundaries, service reopen,
terminal replay, stopped-only delete, and complete transient cleanup.
Next Windows gate
The version-pinned image, read-only root attachment, source/digest manifest, pre-entry drift checks, and separate runtime-share path are implemented. They do not count as real WHPX evidence until the following two gates pass:
- rerun the complete WHPX SDK, soak, owner-death, and service-recovery matrices against the exact v1 manifest on a fresh WHPX-enabled Windows host, retaining the v4 boot evidence in every session;
- retain the current v7 shim report from every matrix session and require its
inherited v6 handle-reclamation fields, including nonzero
windows_handles_before_vmandwindows_handles_after_vmvalues to match, withwindows_handle_inventory_restored=true.
The implementation now captures those two inventories in the libkrun shim,
after immutable assets are pinned and again immediately after
krun_start_enter returns. Host validation and the hardware soak script reject
missing, zero, mismatched, or false evidence. This closes the code path but not
the release gate: the complete fresh-host rerun must still retain the evidence
before WHPX can become experimental.
Broader namespace, mount, capability, resource, seccomp, hook, and shared-guest coverage remains part of the shared executor, OCI conformance, and later readiness gates. It does not reopen the already-qualified owner-death recovery contract.
Only completion of that gate may promote Windows driver readiness to
experimental.