mirror of
https://github.com/Lakr233/vphone-cli.git
synced 2026-10-02 08:04:32 +08:00
The pipeline patched each boot-chain component in place: load the file, run the patchers, save over the same path. A second run therefore handed the patchers the first run's output, they found none of the shapes they had already replaced, and the component died with `Patch site not found: iBSS`. `fw prepare` refuses to re-extract over an existing restore tree, so there was no way back either — a VM could be patched exactly once, for its whole life, and turning a patch off in its PatchSelection.plist could not change anything on disk. The first run now copies each component into <vm>/FirmwareOriginals/, mirroring its path, before anything is written, and every later run patches those bytes. The shipped container also goes back immediately before `loader.save`, because ContainerFirmwareLoader repackages whatever IM4P it finds at the destination and would otherwise wrap the second run's payload in the first run's container. Same VM and same plan now produce the same file however many times fw patch runs. A plan that selects nothing for a component — every patch blocked, or the whole set dropped so no patcher is built — restores the unpatched image instead of leaving the last run's patches stranded with nothing selecting them. A component nobody ever patched is not rewritten, so it keeps the modification date the restore gave it. Filesystem and Manifest opt out. Both name BuildManifest.plist, but neither is a patcher over that one file: one rewrites cryptex images across the restore tree, the other rewrites hashes describing files other steps produced, so putting the manifest back alone would describe a tree that no longer exists. `.less` is excluded outright, so a `.less` run over a patched VM cannot read "this variant builds no boot-chain patchers" as "put the boot chain back". A VM patched by an older build has no originals, so the first run would otherwise adopt its already-patched bytes as pristine. If the component then fails to patch, the copy is deleted and the error says to remove the restore tree and run fw prepare again. fw prepare also deletes a stash left over from previous firmware — AVPBooter's file name carries no version, so a stale copy would be silently reused — and a slim export leaves the originals out along with the restore tree they describe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>