fix(swift-sdk): isLocal = mine-or-tracked; promote wallet identities, fix observed-entry mislinking - #4375
Merged
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Semantics (owner-decided)
PersistentIdentity.isLocalmeans this identity is yours or deliberately tracked on this device:trueis also the initializer default: a directly-constructed row is a manual add);falseonly for incidental rows — observed foreign identities materialized by sync that nobody asked to track.Promote-only: no sync path ever writes
falseovertrue. The flag makes no claim about signing capability — consumers that need capability compute it live; wallet-owned filtering haswalletOwnedIdentitiesPredicate. Reviews proposing capability/evidence gating of this flag are out of scope by owner decision.Issue being fixed
The persister wrote a constant
isLocal: falsefor every row it created and nothing promoted, so the wallet's own identity (correct wallet relationship,identityIndex0) showed as not-local on a real mainnet device — hiding the identity-key refresh affordances in dashwallet-ios (see dashwallet-ios #981). LoadIdentityView additionally clobbered its own manual adds withfalse.What was done
One commit, no schema change:
persistIdentitiespromotesisLocalon wallet linkage; observed rows stayfalse; existing rows are never demoted.identity_index != nilso observed entries are never mislinked to the changeset's scope wallet; a fabricated scope link clears when its identity re-emits observed; a link matching a declared-but-unresolvable owner survives while one contradicting the declaration clears; another wallet's valid relationship always survives a foreign manager's observed emission.loadWalletList()runs a one-shot promote-only heal for constant-false-era stores.true.!isLocalnetwork-feature gates are removed (they'd hide DPNS/tokens/profile/refresh for every wallet identity under the real semantics); wallet-signing actions gate onhasLoadedWallet.History note
An extensive capability-oriented hardening series (evidence-gated promotion, seed-binding markers, tri-state keychain probes) was built here across 12 review rounds and then superseded by the owner's semantics decision — archived unmerged on
archive/islocal-review-hardening. Genuinely pre-existing defects discovered during that series (forget-key dual-scheme deletion, KeyDetail import dropping its identifier, the out-of-wallet restore channel reserved byIdentityRestoreEntryFFI's doc, FFI error taxonomy for credential failures) should be tracked as separate issues, not re-litigated on this PR.How Has This Been Tested
IdentityIsLocalPersistenceTests(in-memory store through the real persister bridge): promotion (direct + index-fallback), observed rows stay incidental and unlinked, sync never demotes manual adds, declared-owner keep/clear, cross-wallet preservation, startup heal. 335 tests pass on simulator; the twoIdentityResolverSignIntegrationTestskeychain-entitlement failures pre-exist on the baseline.SwiftExampleAppbuilds clean under warnings-as-errors.Companion dashwallet-ios PR #983 aligns the app's badge copy and balance-refresh loop.
🤖 Generated with Claude Code