# How to Assert Bootability with vphone-cli: Pre-flight Validation Guide

> Assert bootability with vphone-cli using the --assert-bootable flag. Verify your virtual iPhone binary launches before a full boot sequence. Ensure pre-flight validation.

- Repository: [Lakr/vphone-cli](https://github.com/Lakr233/vphone-cli)
- Tags: how-to-guide
- Published: 2026-09-12

---

**Use the `--assert-bootable` flag via `make boot`, the `vphone boot` CLI command, or direct script invocation to verify your binary can launch a virtual iPhone before attempting a full boot sequence.**

The Lakr233/vphone-cli project includes a built-in **bootability validation** system that prevents wasting time on broken builds. By asserting bootability before launching a virtual machine, developers can catch missing entitlements, signature issues, or architecture mismatches early in the workflow. This validation relies on a pre-flight script that performs a short launch test of the CLI binary itself.

## What Is Bootability Validation?

Bootability validation is a safety mechanism that confirms the compiled `vphone-cli` binary can actually start a virtual iPhone process. Rather than attempting a full boot cycle only to discover the binary is corrupted or improperly signed, the system runs a lightweight **pre-flight check** using the `--assert-bootable` flag. If the check fails, the process aborts immediately with a non-zero exit code, saving time and preventing false starts in automated pipelines.

## Entry Points for Asserting Bootability

You can trigger the bootability check through three primary interfaces depending on your workflow.

### Using the Makefile (`make boot`)

The root `Makefile` automatically injects the assertion flag when you run the standard boot target. It expands a macro that calls the pre-flight script before launching the virtual machine.

```bash

# Validates the binary, then proceeds with boot if successful

make boot

```

### Using the vphone CLI Directly

When you invoke the Swift-based CLI tool, [`VPhoneVMLaunchCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVMLaunchCLI.swift) automatically appends `--assert-bootable` to the arguments passed to the pre-flight script. You do not need to specify the flag manually.

```bash

# The CLI adds --assert-bootable internally before executing the pre-flight check

vphone boot --manifest path/to/manifest.plist

```

### Direct Script Invocation

For debugging or custom automation, you can call the shell script directly without invoking the full CLI or Makefile logic.

```bash

# Run the validation standalone

scripts/boot_host_preflight.sh --assert-bootable

```

## How the Validation Works Internally

According to the source code in [`sources/vphone-cli/VPhoneVMLaunchCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneVMLaunchCLI.swift), the validation follows a strict three-step sequence:

1. **Locate the executable** – The code calls `VPhoneResources.runningExecutable()` to determine the absolute path of the currently running CLI binary.
2. **Export environment variables** – It sets the `VPHONE_CLI_BIN` environment variable to the discovered path so the pre-flight script knows which binary to test.
3. **Execute the pre-flight script** – The system spawns [`scripts/boot_host_preflight.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/boot_host_preflight.sh) with the `--assert-bootable` argument. The script attempts a minimal VM launch; if it returns a non-zero status, the CLI calls `fatalError` and aborts.

Here is the relevant Swift logic from [`VPhoneVMLaunchCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVMLaunchCLI.swift):

```swift
let bootBinary = VPhoneResources.runningExecutable()
guard FileManager.default.isExecutableFile(atPath: bootBinary.path) else {
    fatalError("error: \(bootBinary.path) not found — build it first (make build/bundle).")
}

var preflightArgs = ["--assert-bootable"]
var preflightEnv = ProcessInfo.processInfo.environment
preflightEnv["VPHONE_CLI_BIN"] = bootBinary.path

// Process spawns boot_host_preflight.sh with preflightArgs and preflightEnv

```

The [`scripts/boot_host_preflight.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/boot_host_preflight.sh) shell script implements the actual bootability test by attempting to launch the binary referenced in `VPHONE_CLI_BIN` in a controlled "boot-only" mode.

## Summary

- **Trigger the check** using `make boot`, `vphone boot`, or `scripts/boot_host_preflight.sh --assert-bootable`.
- **Source logic** resides in [`sources/vphone-cli/VPhoneVMLaunchCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneVMLaunchCLI.swift) for the CLI wrapper and [`scripts/boot_host_preflight.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/boot_host_preflight.sh) for the executable test.
- **Key mechanism** involves `VPhoneResources.runningExecutable()` discovering the binary path and exporting it via the `VPHONE_CLI_BIN` environment variable.
- **Failure handling** causes immediate abort with a fatal error if the binary cannot start a VM, preventing wasted cycles on invalid builds.

## Frequently Asked Questions

### What does the `--assert-bootable` flag actually check?

The flag triggers a short-lived launch of the CLI binary in a special mode that verifies it can initialize the virtual iPhone framework without errors. It confirms code signing, entitlements, and macOS version compatibility without performing a full system boot.

### Where is the bootability logic implemented in the source code?

The high-level orchestration lives in [`sources/vphone-cli/VPhoneVMLaunchCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneVMLaunchCLI.swift), which sets up the environment and arguments. The actual test implementation resides in [`scripts/boot_host_preflight.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/boot_host_preflight.sh), which performs the executable validation.

### Can I run the bootability check without starting the full VM?

Yes. Invoke `scripts/boot_host_preflight.sh --assert-bootable` directly from your terminal or CI pipeline. This runs only the validation step and exits with status `0` if the binary is bootable, or non-zero if it fails.

### What happens if the bootability check fails?

The process terminates immediately with a fatal error message (if using the CLI) or a non-zero exit code (if using the script or Makefile). This indicates the binary is missing required entitlements, is unsigned, was compiled for the wrong architecture, or cannot access the hypervisor.