Problem
Apple VZ (applevz) is not available from a plain npm i -g hotcell on any Apple-Silicon Mac — Mac Mini or MacBook alike. Selecting it (or having it configured) fails at daemon start because the signed helper + guest kernel aren't present. Hardware is irrelevant; every Apple-Silicon Mac is VZ-capable. This is a packaging gap, not a design decision.
Repro
npm i -g hotcell
HOTCELL_DRIVER=applevz hotcell start # from any directory
# → "The Apple VZ driver isn't available in this install — its helper (hotcell-vz) isn't bundled…"
Intent vs. reality
The plan says these artifacts are supposed to ship:
docs/plan.md:274 — "hotcell-vz … Ships as a prebuilt binary in the repo / release; path overridable via HOTCELL_VZ_HELPER_PATH."
docs/plan.md:356–357 — env defaults documented as "bundled hotcell-vz" and "bundled vmlinuz".
But packaging never delivered them:
@hotcell/daemon ships files: ["dist"] only.
- The helper (
helpers/hotcell-vz/dist/hotcell-vz) and guest kernel (helpers/hotcell-vz/guest/vmlinux-vz) are gitignored build outputs — not committed, not in any package tarball.
Net: the container (Docker) driver delivers the baseline "runs on a Mac Mini" promise today (docs/plan.md:141), but the documented Apple VZ isolation upgrade is source-checkout-only (npm run build:vz), which is how it's been developed/tested (check:applevz 21/21 on the dev Mac).
Artifacts that must reach the user
hotcell-vz — code-signed Swift binary (Virtualization entitlement). Requires a macOS build + signing; cannot be produced on the current ubuntu-latest release runner.
vmlinux-vz — prebuilt arm64 guest kernel (from build-kernel.sh).
- Rootfs is not needed as a shipped artifact — it's converted on-demand from the OCI image and cached in
~/.hotcell/vz/images (see plan M6b). The in-guest hotcell-agent (amd64/arm64) is injected during conversion.
Constraints / considerations
- Codesigning + notarization. The helper is currently ad-hoc signed (
codesign --sign -). For distribution to other Macs, ad-hoc may be tripped by Gatekeeper/quarantine depending on how the file arrives; a Developer ID signature + notarization is the robust path. Needs a signing identity in CI secrets.
- Release pipeline.
release.yml runs ubuntu-latest. Building/signing the macOS helper needs a macos-latest job (Apple Silicon runner) added, with the kernel built or fetched separately.
- Quarantine. A downloaded binary gets the
com.apple.quarantine xattr; the daemon (or install step) must clear it (xattr -d) or the download must avoid it.
- Path resolution is already fixed in 0.1.17 (absolute, cwd-independent;
RUNNING_FROM_SOURCE gates the install-aware message + the hotcell setup driver menu), so whichever option lands only needs to place the artifacts where the resolver looks (or point HOTCELL_VZ_HELPER_PATH/HOTCELL_VZ_KERNEL at them).
Options
Option A — bundle in the npm package
Build + sign the helper and kernel in CI, copy them into @hotcell/daemon at publish (prepack + files), resolve defaults to the package dir.
- ➕ Zero runtime network; works offline; version-locked to the daemon.
- ➖ Fattens every install (helper + kernel, several MB) for the majority who use Docker; npm tarball carries a signed macOS binary; must gate/skip on non-macOS installs.
Option B — fetch on first use (recommended)
Daemon downloads the signed helper + kernel from the GitHub release matching its version into ~/.hotcell/vz/, verifies checksum/signature, clears quarantine, caches.
- ➕ Small npm tarball; only VZ users pay the download; can re-fetch/repair; naturally per-arch.
- ➖ Needs network on first VZ use; must verify integrity (checksum + ideally signature) and handle air-gapped hosts (fall back to the current honest message +
HOTCELL_VZ_HELPER_PATH override).
Recommendation: Option B, with the release adding a macos job that builds, signs (Developer ID + notarize), and uploads hotcell-vz + vmlinux-vz as release assets.
Acceptance criteria
Related
- Fixed in 0.1.17 (interim): cwd-independent artifact paths, install-aware "use Docker" message, and
hotcell setup no longer offering microVM drivers outside a source checkout.
Problem
Apple VZ (
applevz) is not available from a plainnpm i -g hotcellon any Apple-Silicon Mac — Mac Mini or MacBook alike. Selecting it (or having it configured) fails at daemon start because the signed helper + guest kernel aren't present. Hardware is irrelevant; every Apple-Silicon Mac is VZ-capable. This is a packaging gap, not a design decision.Repro
Intent vs. reality
The plan says these artifacts are supposed to ship:
docs/plan.md:274— "hotcell-vz… Ships as a prebuilt binary in the repo / release; path overridable viaHOTCELL_VZ_HELPER_PATH."docs/plan.md:356–357— env defaults documented as "bundledhotcell-vz" and "bundledvmlinuz".But packaging never delivered them:
@hotcell/daemonshipsfiles: ["dist"]only.helpers/hotcell-vz/dist/hotcell-vz) and guest kernel (helpers/hotcell-vz/guest/vmlinux-vz) are gitignored build outputs — not committed, not in any package tarball.Net: the container (Docker) driver delivers the baseline "runs on a Mac Mini" promise today (
docs/plan.md:141), but the documented Apple VZ isolation upgrade is source-checkout-only (npm run build:vz), which is how it's been developed/tested (check:applevz21/21 on the dev Mac).Artifacts that must reach the user
hotcell-vz— code-signed Swift binary (Virtualization entitlement). Requires a macOS build + signing; cannot be produced on the currentubuntu-latestrelease runner.vmlinux-vz— prebuilt arm64 guest kernel (frombuild-kernel.sh).~/.hotcell/vz/images(see plan M6b). The in-guesthotcell-agent(amd64/arm64) is injected during conversion.Constraints / considerations
codesign --sign -). For distribution to other Macs, ad-hoc may be tripped by Gatekeeper/quarantine depending on how the file arrives; a Developer ID signature + notarization is the robust path. Needs a signing identity in CI secrets.release.ymlrunsubuntu-latest. Building/signing the macOS helper needs amacos-latestjob (Apple Silicon runner) added, with the kernel built or fetched separately.com.apple.quarantinexattr; the daemon (or install step) must clear it (xattr -d) or the download must avoid it.RUNNING_FROM_SOURCEgates the install-aware message + thehotcell setupdriver menu), so whichever option lands only needs to place the artifacts where the resolver looks (or pointHOTCELL_VZ_HELPER_PATH/HOTCELL_VZ_KERNELat them).Options
Option A — bundle in the npm package
Build + sign the helper and kernel in CI, copy them into
@hotcell/daemonat publish (prepack+files), resolve defaults to the package dir.Option B — fetch on first use (recommended)
Daemon downloads the signed helper + kernel from the GitHub release matching its version into
~/.hotcell/vz/, verifies checksum/signature, clears quarantine, caches.HOTCELL_VZ_HELPER_PATHoverride).Recommendation: Option B, with the release adding a
macosjob that builds, signs (Developer ID + notarize), and uploadshotcell-vz+vmlinux-vzas release assets.Acceptance criteria
hotcell-vz(arm64) +vmlinux-vzas versioned assets.npm i -g hotcell+hotcell setup→ Apple VZ boots a sandbox (parity withcheck:applevz), from any working directory.hotcell setupoffers Apple VZ once the artifacts are obtainable (extend the currentRUNNING_FROM_SOURCEgate to "source or fetched").docs/plan.mdAppendix A) updated to describe the real distribution mechanism.Related
hotcell setupno longer offering microVM drivers outside a source checkout.