Publish validated location state to authorized CoreLocation clients, keep guest hooks in sync, and add a Release artifact workflow for unsigned CI packages.
vcam_dataplane builds CoreMedia sample buffers, format descriptions and
pixel buffers from the shared vcam frame for both camera hooks. It is
not linked into either hook yet; the third-party client support in #478
is its first user. `make test-vcam-dataplane` runs its 124 host checks,
and CI now runs it with the loader link tests.
Ported from #477 into VPhoneGuestComponents/VCamDataPlane.
Co-authored-by: Alec Armbruster <35377827+alectrocute@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fourteen ports that landed in the last two commits had no caller
outside two in-process call sites, so the installers still ran cfw.py.
They no longer do. Each patch is a `vphone-cli cfw <verb>` carrying the
Python's exact verb name, positional arguments and flags, so the shell
diff is a prefix swap and nothing else — 26 call sites across the four
installers, the two userland wrappers and cfw-kit, whose `cfw_py` seam
became `cfw_cli`.
Every verb was proven through the built binary against the Python it
replaces, on cp -c clones of the real iOS 27.0 / 24A435 references: the
six Mach-O verbs byte-identical, cmp and sha256 both, exit 0 on each
side; the eight DSC verbs diff -rq clean across all 80 cache files on
first run, second run and dry run.
With the callers gone, so is scripts/patchers — 26 Python files. The
parity evidence that used to be measured by spawning that Python at test
time is now frozen into constants recorded from it at 78cbeea, each with
a provenance comment naming the command and the input digest, and each
suite checks the fixture is the one the goldens were taken over, so a
different firmware fails on that line instead of looking like a patcher
bug. Two structural fixes were needed for the freeze to mean anything:
the re-attester parity test was reading .build/release/vphone-letmein, a
build product whose bytes change every build, and the device-tree golden
had to become a digest map keyed by input digest, because that input
exists in two cloudOS IPSWs.
requirements.txt drops capstone, keystone-engine and pyimg4; the venv,
setup_venv*.sh and the Homebrew lists now exist for exactly one program,
scripts/pymobiledevice3_bridge.py. VPhoneResources loses patchersDir,
cfwPy and the whole keystone probe-and-repair path, and its remaining
python probe gained `import pymobiledevice3` — ipsw_parser does not pull
pymobiledevice3 in, so the old probe passed on a venv the bridge could
not actually run on.
scripts/repos/insert_dylib stays. Nothing in the product runs it, and it
is no longer bundled or built in CI, but CFWMachOTests still runs the
real binary as the independent byte-parity reference for CFWInjectDylib,
gated on its presence — removing the submodule would turn that check
into a silent skip rather than a failure.
Two fixes to the library, both found by running the verbs rather than by
reading them:
MachOParser walked the load-command table checking only that each
command's 8-byte header fit, then read fields up to +0x38 inside it. A
Mach-O whose table runs past EOF — 64 bytes is enough — therefore killed
all six patchers with SIGTRAP at BinaryBuffer.swift:9 rather than
raising anything catchable. forEachLoadCommand now bounds every command
by its own cmdsize and by the file, each branch checks its own minimum
command size, and MachOParserBoundsTests covers it; those tests pass by
completing.
patch-camera-dsc over an already-patched cache exits 0 where the Python
raised. That is deliberate and kept: cfw_install_exp.sh:126 tests the
exit status and its failure branch prints "likely build-version
mismatch", which is a wrong diagnosis for a re-install.
README_reference_capture.md moves to research/ instead of leaving with
the tree it documented — CFWJetsam.swift quotes its non-idempotency
finding, and AGENTS.md's own rule puts reveal procedures in a research
doc. The capture facility itself is gone with the Python.
Known and not fixed here: tests/VPhoneCoreTests has a pre-existing
cross-suite race on VPHONE_ROOT (LibraryTests setenv vs
ResourcesTests.cacheDirsAreHomeRelative) that fails about one run in
five; .serialized orders within a suite, not across them. And the 13
boot-chain comparison tests still hard-fail on the absent
ipsws/patch_refactor_input fixture, as they did before this branch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The release workflow ran `make bundle`, which produces a lean .app (binary +
ldid + signcert + icon only) — missing the bundled scripts/patchers/resources/
requirements.txt/vphoned/.tools — so published release assets were not
self-contained and `brew install` copies couldn't run the fw/restore/cfw
pipeline.
Switch to ./scripts/build.sh (the canonical portable build):
- also init the scripts/resources storage submodule + the
scripts/repos/{trustcache,insert_dylib} tool sources
- build .tools/bin/{trustcache,insert_dylib} (mirrors setup_tools steps 2-3;
its venv + sshpass steps aren't needed to build)
- run build.sh, then fail the job if the bundle is missing any runtime asset
or the virtualization entitlement before packaging + uploading
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4VDqWf5pVakcFLqB23CKe
On a published GitHub Release, build vphone-cli.app on macos-26 via
`make bundle` (ad-hoc codesign + sources/vphone.entitlements, matching a
local build), verify the private virtualization entitlement is embedded,
then zip and upload the app as a release asset.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>