feat(navigation): stabilize tab stacks - #111
Conversation
Bead: clarity-nc6.1
Add first-visit mount params and protect activation frames from stale renders. Bead: clarity-nc6.2
Make logout an atomic navigation and persisted-state boundary. Bead: clarity-nc6.5
|
Independently re-reviewed (fresh worktree, no reliance on the authoring session's review) and verified on physical hardware. Approve. The adversarial priorities all held: (1) #103's one-shot reservation and the new activation gate compose — activate_frame nulls the reservation, the gated clause consumes the gate only on :none frames, supersession carry runs only ungated, and crash-during-nav-paint is repaired by substitute/3 copying the token (test exists); (2) component reclaim can't double-free (each server frees its own handle exactly once, before user terminate/2, raising callbacks can't skip it) and a dying predecessor can't deregister a replacement (ETS self()-check + test); (3) version-skew guards are real and individually tested, including transitive coverage of restore_persisted_state. Physical Moto g power (Android 11): tab bar survives 60-switch churn; Back pops in-stack → switches to first stack from a secondary root → exits from the first-stack root; directional animations verified by screen recording, single burst each way; first-visit mount_params delivered and sticky, boot root back-compat with %{}; reset_to scope: :all lands on the login root with every stack fresh, persisted snapshots emptied, and a 12-cycle sign-in/churn/sign-out soak shows registry shrinking, process count flat, zero component_slots_exhausted. Gates: 1327/1327, format/credo-strict/warnings-as-errors/erlfmt/clang-format clean, swiftlint at the 2 known pre-existing warnings. Branch sits directly on the 0.7.36 tag, merge-tree clean. Non-blocking (filing as a follow-up issue): legacy activate/2 and set_active/1 in sender.ex don't clear a pending activation_gate — unreachable today, but a hot-code downgrade mid-navigation could strand a gate and freeze that screen's untokened renders; one-line fix. Plus doc nits: Mob.Test.switch_tab/3 missing from testing.md's helper list; the MOB-115 stack-scope gap note vanished from navigation.md and should return reworded; explicit transition: :none raising on switch_tab while being the documented default is an API wart. Merging and cutting 0.7.37. |
Summary
These changes unblock the downstream app's independent bottom-tab stacks and correct the Android tab-bar disappearance and premature Back behavior reproduced on a Moto g power 5G - 2024.
Beads:
app-nc6.1,app-nc6.2,app-nc6.5Verification
mix format --check-formattedmix credo --strict