Skip to content

feat(sandbox): add the Virtualization.framework provider (sandbox Phase 2) - #198

Merged
quickbeard merged 1 commit into
mainfrom
sandbox-vz-provider
Aug 12, 2026
Merged

quickbeard merged 1 commit into
mainfrom
sandbox-vz-provider

Conversation

@quickbeard

Copy link
Copy Markdown
Owner

Summary

Phase 2 of the desktop sandbox: the macOS backend — a small Swift helper (codev-vmm) driving Virtualization.framework, plus the vz SandboxProvider that manages it. Implements the agreed design: NIC-less guest (the VM has no network device; its only egress is vsock), virtio-fs mounts, hard block below macOS 12, and the same server/broker bridge contract Phase 1 (#197) established for bwrap.

The Swift helper (native/vzhelper)

A ~350-line SwiftPM executable (macOS 12+, compiles clean on Swift 6.3 toolchain in Swift 5 mode):

  • Boot: VZLinuxBootLoader with kernel + initrd + virtio block disk; cpu/memory clamped to framework limits; entropy + balloon devices; guest serial console routed to stderr so boot problems land in the provider's captured diagnostics.
  • Shares: virtio-fs tags workspace (rw), bundle (ro, the server bundle for automatic version parity), config (ro, per-boot credentials).
  • vsock bridging: host-to-guest — a POSIX unix-socket listener per forward, each accepted connection dialed into the guest via VZVirtioSocketDevice.connect(toPort:); guest-to-host — VZVirtioSocketListener dials the host unix socket (where the egress broker listens). Bidirectional fd relays with proper half-close semantics.
  • Protocol: argv[1] = VmConfig JSON; newline-delimited {"event":"state"|"error"} JSON on stdout; stop via stdin command, stdin EOF (parent death), or SIGTERM.
  • Signing: bun run build:vzhelper builds and ad-hoc signs with the com.apple.security.virtualization entitlement for dev (--universal for arm64+x86_64); release packaging re-signs with the app identity when the desktop wiring lands.

The TS provider (src/vz/)

  • protocol.ts — typed wire protocol + a line-buffering event reader (chunks may split/batch events arbitrarily).
  • provider.ts — availability() enforces the plan's asymmetric policy: hard block below macOS 12 with the explanatory message (via macosSandboxAvailability, versions read from sw_vers), plus a helper-binary presence check. create() stages + unpacks the vz image tarball (vmlinux/initrd/rootfs.img, validated) and clones the instance disk copy-on-write via COPYFILE_FICLONE (APFS clonefile, plain copy fallback). start() writes the guest boot.json, waits for the helper's running event, then reuses the Phase 1 TCP→unix forwarder + health gate; failures carry the helper's stderr tail (guest serial console included). reset() just re-clones the pristine disk — instant, no re-download.

Verification

  • 61 tests pass / 2 skip (the Phase 1 bwrap integration tests, skipped on macOS), 172 assertions. New vz provider tests spawn a fake helper process speaking the real protocol — real spawn, real unix-socket bridge, real HTTP health through the forwarder, stop→exit — plus error-event, timeout, missing-image-file, and availability-gate cases.
  • bun typecheck clean.
  • The real binary builds via bun run build:vzhelper and its error protocol was smoke-verified (cannot read config, invalid virtual machine configuration events with correct exit codes). Actually booting a VM requires the guest image from the image pipeline (parallel track) — the README documents the guest agent contract the image must implement (mount the three tags, run the bundle per boot.json, bridge vsock 4096/8788).

Notes

  • Fork-only files throughout — no upstream edits, no DIVERGENCES.md rows needed this time.
  • .build/ and dist/ are gitignored; the helper binary is built, not committed.
  • Still no CHANGELOG entry — nothing user-facing until the desktop wiring phase.

🤖 Generated with Claude Code

…se 2)

macOS backend for the sandbox: a small Swift helper (codev-vmm) plus the
vz SandboxProvider that drives it.

- native/vzhelper: SwiftPM executable (macOS 12+) that boots one Linux
  VM via VZLinuxBootLoader (kernel + initrd + virtio disk), mounts
  virtio-fs shares (workspace rw, bundle ro, guest-config ro), routes
  the guest serial console to stderr, and attaches NO network device —
  the guest's only egress is vsock, bridged by the helper to host unix
  sockets (host-to-guest server path, guest-to-host broker path).
  Protocol: VmConfig JSON in, newline-delimited JSON events on stdout,
  stop via stdin/EOF/SIGTERM. Ad-hoc signed in dev with the
  com.apple.security.virtualization entitlement (build:vzhelper).
- vz/protocol.ts: typed wire protocol + line-buffered event reader
- vz/provider.ts: availability hard-blocks below macOS 12 per plan and
  requires the helper binary; create unpacks the vz image tarball and
  clones the instance disk copy-on-write (FICLONE/APFS clonefile);
  start writes guest boot.json (credentials + serve args via the
  config share), gates on the helper's running event then the health
  poll, and reuses the Phase 1 TCP-to-unix forwarder; reset re-clones
  the pristine disk without re-downloading.

Provider tests drive a fake helper process speaking the real protocol
(spawn, events, unix-socket bridge, health, stop). The real binary
compiles and its error protocol is smoke-verified; actually booting a
VM needs the guest image from the image pipeline (parallel track).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@quickbeard
quickbeard merged commit f29cc71 into main Aug 12, 2026
0 of 5 checks passed
@quickbeard
quickbeard deleted the sandbox-vz-provider branch August 12, 2026 01:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant