Guide device installation with app discovery, account inventory, logs and full IPA mode

This commit is contained in:
Erick Sanchez committed 2026-10-27 10:51:18 -06:00
1 parent b861784375
commit 7e3fc97a18
16 files changed
+553 -104

No files matched your search

+6
View File
@@ -22,6 +22,12 @@ appear everywhere without being forgotten. No recurring schedule is implied.
Keep personal commit attribution, original upstream authors and licensing.
Preserve the isideload exact-identifier patch, signed/profile identity checks,
Keychain session storage, redacted stdio and RomFS-only transfer capability.
Preserve UDID deduplication (USB preferred), device metadata/search/update
selection, separate connected/registered inventories and logs without raw
credential/provider payloads. Full/light packaging must retain the bundled
RomFS priority flag and legacy-record rebuild gate; never delete external
content or saves to switch modes. Show actual registration results, not an
invented remaining free-account quota.
Never add automatic certificate revocation, account/team changes, save-folder
writes or password logging. Helper tests use synthetic credentials and no device;
compilation never counts as successful Apple login or physical installation.
+1
View File
@@ -13,6 +13,7 @@ One line per symptom in the [subsystem references](../reference/): what you see
- preparation appears stuck; the player cannot inspect compilation output until a failure. → [Desktop preparation shows a spinner with no build activity](../reference/packing.md#desktop-preparation-shows-a-spinner-with-no-build-activity)
- the official Rust component shell installer rejects part of `--prefix` as an unknown option; a partial LLVM setup can also make `rust-objcopy` fail to load `libLLVM.dylib`. → [Native sideload toolchain install rejects a workspace path with spaces](../reference/packing.md#native-sideload-toolchain-install-rejects-a-workspace-path-with-spaces)
- a replacement signer can append a second team suffix or produce another app identifier, separating the user from the existing app container. → [A sideload signer changes an existing game's bundle identifier](../reference/packing.md#a-sideload-signer-changes-an-existing-games-bundle-identifier)
- a complete game update includes new bundled RomFS but an existing Documents/romfs can take priority when the app boots. → [A complete iOS IPA can still select older external game data](../reference/packing.md#a-complete-ios-ipa-can-still-select-older-external-game-data)
## Rewriter
+26
View File
@@ -435,3 +435,29 @@ assertions, account rejection and non-destructive record removal. The production
ARM64 bundle compiled and its signature verified; localization, documentation and
78-profile catalog checks passed. No runtime, shader or Rust helper change was
needed. No real account login, signing or physical-device install was performed.
## Guided device workspace and complete iOS packaging (1.9)
The device workspace now exposes metadata, transport/readiness, installed app
search, update selection, Apple-account access and separate team registration
queries. USB/Wi-Fi duplicates merge by UDID with USB preferred. After preparing
an iOS game the installer opens, but signing/installing still needs explicit
approval in the UI. Lightweight mode remains default; full-only mode includes
RomFS and skips separate transfer. The new `DMPreferBundledRomFS` runtime flag
prevents an older Documents/romfs from shadowing a complete native installation;
unflagged apps retain legacy overrides. No saves or external directories are
removed. Installation activity is bounded, timestamped, copyable and privately
retained, without raw protocol/account credentials.
Validation: 11 Rust cases passed; the expanded Swift fixture covers duplicate
connections, metadata, installed-target continuity, explicit team-account device
queries, full/light output selection, legacy full-record refusal and private log
permissions/redaction. All 64 script cases completed (two optional dependency/
compiled-helper checks skipped in that suite); documentation/localization and
78-profile catalog gates passed. The unsigned iOS compile check compiled 178
files with zero failures. Read-only real-device probing returned one unique
connected iPhone with model/OS and 184 installed user apps. No Apple-account
login, registration query, signing or installation was performed. The Mac
regression harness was invoked but found no registered Mac Dread build; no
physical gameplay or full/light migration comparison is claimed. The shader
chain is unchanged. Cloud work remains paused; saves remain local/manual.
+7
View File
@@ -70,3 +70,10 @@
- **Cause:** isideload 0.5.0 unconditionally appended the team ID to the supplied bundle ID, even when the caller already knows the effective installed identifier.
- **Fix:** the small vendored MIT patch preserves the caller's exact final ID. Our helper selects an actual existing device app, checks that it matches the game, verifies the signed/provisioned identity and never uninstalls the previous app to force an update. Original preparation IPAs stay unsigned. Tests cover custom identifiers and mismatch refusal; real-account/device migration still requires validation.
- **Found on:** source review and synthetic tests for the [integrated installer](../sideloading.md#user-flow), with no existing user installation modified.
### A complete iOS IPA can still select older external game data
- **Symptom:** a complete game update includes new bundled RomFS but an existing Documents/romfs can take priority when the app boots.
- **Cause:** the legacy iOS boot search intentionally checks Documents first to support external game-content overrides; preserving the container across an update also preserves that older directory.
- **Fix:** the native signer marks bundles containing RomFS with `DMPreferBundledRomFS`. The iOS boot search honors the flag by checking bundled content first, with Documents as fallback. Unflagged apps retain the old override behavior. The desktop full-mode preparation gate requires a new preparation record; it does not silently reuse an older runtime. No save or external content is deleted. Physical mode migration remains unvalidated.
- **Found on:** [native installer source review](../sideloading.md#guided-device-workspace-19), not a verified gameplay regression.
+71
View File
@@ -162,3 +162,74 @@ The implementation covers our prepared-game installation lifecycle. It is not a
full binary/source migration of Sideloadly: no proprietary code is available to
port, and arbitrary IPA injection/plugins and all of its advanced options are
not implemented. Intel Sideloadly is not required by the native code path.
## Guided device workspace (1.9)
The device workspace separates three different inventories:
- **Connected devices:** read-only usbmuxd/Lockdown discovery. Duplicate USB/Wi-Fi
entries are merged by UDID, preferring USB for operations. Device cards show
Apple's model identifier, OS version, available transports and trust/readiness.
A model identifier is not a guessed marketing model name.
- **Installed apps:** the selected device's actual installation-proxy user-app
list, with names, effective bundle IDs, versions and search. These do not need
an Apple-account login and include apps outside nxnative. **Update using my
files** retains that target/device, returns to game-folder preparation and
carries the target into installation. Matching game identity is checked again
before overwriting; selecting an unrelated app does not authorize replacing it.
- **Apple-account devices:** after login and explicit team selection, **Read my
Apple account devices** queries that team's actual registrations. This is not
the same as a list of devices currently connected. A query failure is shown,
not interpreted as zero registrations or available free slots.
Apple documents a Personal Team limit of up to three test devices and seven-day
profiles in its [account overview](https://developer.apple.com/help/account/basics/about-your-developer-account).
Sideloadly's [FAQ](https://sideloadly.io/faq.html) also describes the three-active-app
limit for free accounts. The UI shows returned registrations and team type; it
cannot infer a reliable remaining quota from installed user-app counts, count
paid teams as free, remove registrations or bypass Apple's limits. No speculative
"slots remaining" counter is displayed.
### Folder to device
Choose iPhone/iPad, select your own game folder and keys, select packaging, and
press Prepare. Compilation already exposes live and retained compiler logs.
After success the native installer opens automatically: select the device, sign
in with your Apple account/2FA, explicitly choose your team and existing target,
then approve signing/installing. Installation remains an explicit button; finishing
compilation never signs or installs silently. Device-workspace account access is
also available before preparing a game. A new source folder alone does not
install anything.
**Lightweight IPA** is the default. RomFS remains separate and the installer
copies it with bounded progress and staging/recovery. **Complete IPA** uses
`--full-only`, omits separate content transfer and includes the game inside the
app; every signature renewal must transfer that larger app. Archive expansion is
bounded to 64 GiB; use lightweight mode for larger content or constrained storage. Older preparation
records require a new full preparation before using this mode. During native
signing a bundle with RomFS gets `DMPreferBundledRomFS`; the updated game runtime
then checks bundled content first, falling back to Documents when absent. This
prevents a complete game update from booting an older external RomFS. It does not
delete the previous external directory or touch saves. Legacy apps without the
flag retain their intentional Documents override. Physical content-mode migration
still needs device validation.
**Installation activity** shows timestamped, bounded events for discovery, login
state, device registration, signing, signature verification, installation and
content transfer. Percentages come from actual helper callbacks when available;
otherwise progress is indeterminate with elapsed time. The viewer can copy the
log and reveal a retained `nxnative-tools/logs/install-<id>.log` in the game folder.
Only fixed local status/error messages and numeric progress/Apple error codes
are logged, never raw protocol payloads, passwords, 2FA codes, Apple responses,
account names, device IDs or session tokens. The compiler log remains separate.
### Honest parity boundary
The REA investigation was read-only Mach-O inspection, not full decompilation or
a recovered Sideloadly source tree. This project implements our game workflow
using a separately licensed open-source signer. It has no claim of full Sideloadly
parity: arbitrary IPA/plugin injection, all advanced signing options and its
unattended background-daemon behavior are not implemented. Auto-renewal requires
our launcher running. Real connected-device metadata and installed-app discovery
were checked locally; account registrations, real provisioning/signing, physical
RomFS recovery and unattended renewal remain unvalidated. Keep the fallback.