Skip to content

iOS: load deployed BEAMs from numbered, committed directories (MOB-408) - #207

Merged
GenericJam merged 3 commits into
masterfrom
mob-408-ios-otp-pointer
Oct 15, 2026
Merged

GenericJam merged 3 commits into
masterfrom
mob-408-ios-otp-pointer

Conversation

@GenericJam

@GenericJam GenericJam commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

MOB-408, runtime half. Pairs with GenericJam/mob_dev#142 (deployer half, mob_dev 0.7.28).

Problem

mob_beam.m loaded a physical iPhone's deployed BEAMs from Documents/otp/<app> whenever that directory existed. mob_dev had to replace it in place with devicectl --remove-existing-content, which empties the app's whole data container (measured on an iPhone SE, devicectl 642.16, iOS 26.5.2: Documents, the SQLite DB, Library and tmp all gone), and an interrupted copy left an override the app couldn't boot from.

Change

ios/mob_code_versions.h (header-only C, run by test/native/code_versions_test.c):

  • load the highest Documents/otp/<app>.versions/<N> that has its .mob_complete marker (mob_dev copies the marker only after the upload is verified), else the legacy Documents/otp/<app>, else the bundle;
  • having chosen N, delete lower Ns (marker first) and the legacy dir; keep higher uncommitted ones (may be a deploy in progress);
  • development builds create <app>.versions/ at each boot, which tells mob_dev the runtime reads the layout.

Decision: decisions/2026-10-15-ios-versioned-code-dirs.md (and an amendment to 2026-10-01-ios-dist-cookie-file.md). CI's native_lint lists the new header and test.

Verification

  • make -C test/native run: code_versions_test: ok; a mutation that ignores the marker, one that GCs N == keep only, and one that drops FTW_PHYS each fail it.
  • Kevin's iPhone, blank host d408 on this branch + the mob_dev branch: sentinels (Documents file, SQLite row, nested dir, Library file, a sibling in Documents/otp) survived ~16 deploys; versions 1→12 loaded and older ones deleted; a deploy whose devicectl copy was killed mid-upload (382 of 448 entries) and one whose mix was killed both left the previous version booting; the next deploy removed the partial dirs. A --native downgrade to mob 0.9.19 then deploys into the legacy dir without wiping anything.

Review

Codex rate-limited (until 17:26) → reviewer subagent: MERGE (no blocking; doc claims fixed in d7df5c1; the cross-version should-fix is handled by mob_dev's boot check). Re-review: see comment below.

mob_beam.m loaded a physical iPhone's deployed BEAMs from Documents/otp/<app>
whenever it existed, so mob_dev had to replace that directory in place, with
devicectl --remove-existing-content, which empties the app's whole data
container; and a copy that died part-way left an override the app could not
boot from.

ios/mob_code_versions.h (header-only, run by test/native/code_versions_test.c):
load the highest Documents/otp/<app>.versions/<N> that has its .mob_complete
marker, else the legacy Documents/otp/<app>, else the bundle. Having chosen a
version, delete the lower-numbered ones (marker first) and the legacy dir;
keep higher uncommitted ones (a deploy may be in progress). Development builds
create <app>.versions/ at boot, which is how mob_dev knows the runtime reads it.

Decision: decisions/2026-10-15-ios-versioned-code-dirs.md.
…8 review)

Review: the decision record claimed a downgrade was always caught and called the --native run's own push 'the first deploy after'. Say that moving mob across 0.9.20 without --native needs --native (mob_dev's boot check reports it), list every legacy writer in the header, note that concurrent deploys can pick the same N.
mob_dev waits for mob_diag_beams_dir.txt after relaunching; write it as soon as the choice is final rather than after deleting old versions. CHANGELOG: the boot check runs when mob_dev relaunches the app. Rewrap the decision record.
@GenericJam
GenericJam merged commit 6461b6f into master Oct 15, 2026
4 checks passed
@GenericJam
GenericJam deleted the mob-408-ios-otp-pointer branch October 15, 2026 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant