Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

mode name
-rw-r--r-- README.md
-rw-r--r-- vz.entitlements
-rw-r--r-- vzspike.swift
README

DarwinVmBackend — spike

Goal: run Elpe’s build/isolation on macOS in a VM (Virtualization.framework), the modern replacement for nix-darwin’s weak sandbox-exec. Two guest kinds are wanted:

  • Linux guest — cross-build Linux images/binaries from a Mac (a primary use case), and hermetic isolation without Apple’s security theatre.
  • macOS guest — build/sign macOS packages (2-VMs-max per host, IPSW restore); deferred.

What the spike proved (2026-08-03, on germaine, arm64 macOS 26)

vzspike.swift boots an Alpine Linux guest and streams its console to stdout — reaching the initramfs userspace shell. This burns down the real risks:

  1. Virtualization.framework is present and usable.
  2. The com.apple.security.virtualization entitlement works under an ad-hoc signature (codesign -s -), no paid Team ID / provisioning profile needed on a dev machine.
  3. Our own binary can create + start a VZVirtualMachine.
  4. A Linux guest boots to userspace; the virtio console is captured.

The guest drops to the initramfs emergency shell only because we gave it no root disk (kernel + initramfs only) — expected. Next increment: attach a root disk (VZDiskImageStorageDeviceAttachment) or a virtiofs share of the store (VZVirtioFileSystemDeviceConfiguration).

Recipe / gotchas

  • Kernel format. VZLinuxBootLoader needs an uncompressed arm64 Image (magic 41 52 4d 64 = “ARM\x64” at offset 56). A distro’s vmlinuz is a compressed / EFI-stub PE and fails to start with a generic VZErrorDomain Code=1 "Internal Virtualization error". Extract the raw Image (à la kernel scripts/extract-vmlinux): find the gzip magic 1f 8b 08 and pipe the tail through gunzip (the CLI tolerates the trailing bytes the kernel appends; Python’s strict gzip.decompress does not). Alternatively use VZEFIBootLoader + a bootable disk image, which offloads kernel handling to the guest’s own EFI — the likely path for a full build guest.
  • Entitlement. Sign with --entitlements vz.entitlements; verify with codesign -d --entitlements - vzspike.
  • Run loop. VZVirtualMachine runs on the main queue; keep RunLoop.main alive or nothing happens.

Fetching a test kernel

BASE=https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/aarch64/netboot
curl -fsSLO $BASE/vmlinuz-virt -o vmlinuz
curl -fsSLO $BASE/initramfs-virt -o initramfs
# then extract the uncompressed Image from vmlinuz (see gotchas)

Bindings decision

A thin Swift shim exposing a small C ABI, called from Rust via FFI — rather than driving the verbose Virtualization ObjC API through objc2. (ObjC is not deprecated, but VF is Swift-friendlier and we will want Swift here regardless.) This spike is pure Swift; the C-ABI + Rust wrapper is the next, low-risk step.