Phase 3 of docs/multiple-profiles.md. The startup screen learns to agree with
the switch.
The table that picks what to open is lifted out of the screen's remember into
StartupChoice.resolve, where it can be read and tested, because its order was
the whole decision and it was wrong in the one way a switch would hit:
"!startWalletImmediately -> null" sat above "desiredWalletId != null", and
nothing ever set the flag back to true. So after the first visit to the
selector, every sign-in on that device landed on the selector instead of the
profile it had just signed in. Two rows move: what a switch or a sign-in
named goes above the user's earlier "show me the list", since it is the more
specific instruction; and the single-identity row drops below it, since when
both are set they name the same thing.
The default is written. GlobalPrefs.getDefaultWallet has been read by startup
since Phoenix and saved by nothing in this app, so a cold boot with two
profiles was the selector every time with no memory of which one was open.
setActiveIdentity now saves the id it activates -- every activation goes
through it, startup for all three kinds and the two tails through startup --
so the default is always the profile most recently open. The two forget tails
clear it, since the default is the one memory of an identity that would
otherwise outlive it. Both writes are wrapped: a default that could not be
recorded is a selector on the next boot, not a crash now. The screen reads
the saved value as a default only when it names a wallet, which is the one
thing left to decide at the call site.
The startup screen's literals go to the catalogue, and "wallet" goes with
them except in the one place a wallet is what is starting: "Starting wallet"
is shown from StartupViewState.StartingBusiness, which only the branch with
a wallet attached reaches, and stays. The rest become "Preparing profiles",
"Opening profile", "Decrypting", "Loading preferences", "Unlock to continue"
and "Could not load the profiles on this device"; the selector's title is
"Choose a profile", and select_a_wallet goes.
Tests: StartupChoiceTest in commonTest, one case per row and the two
orderings this phase is for -- a desired id opens even after the user once
asked for the list, and one identity with the list asked for still shows it.
IdentitySwitchJvmTest gains the cold boot: activate A then B, and a fresh
view model over the same directory resolves B without asking; forget the
default, and it resolves nothing. Found on the way and recorded in the test:
DataStoreManager caches the global preferences once per process, bound to
whichever directory was current when the first test in the JVM asked -- the
same trap the nsec plan recorded for user preferences -- so the test reads
the default through the view model's own instance rather than one of its
own.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Pulled-From: curated/curated@00fc996995