Skip to content

fix: preserve tags when restoring a profile - #1303

Merged
piotr-iohk merged 1 commit into
masterfrom
codex/preserve-restored-profile-tags
Nov 12, 2026
Merged

piotr-iohk merged 1 commit into
masterfrom
codex/preserve-restored-profile-tags

Conversation

@piotr-iohk

@piotr-iohk piotr-iohk commented Nov 12, 2026 •

Copy link
Copy Markdown
Collaborator

Twin: synonymdev/bitkit-android#1884

Description

The restore form can open when the pubky.app profile is available and its Paykit copy cannot be read. A refresh can recover the stored tags while the open form still holds an empty list. Preserve the form’s original unread-tags flag through identity creation so the save keeps those stored tags. Finding on the 3.1.1 release PR

Out of Scope

  • Verify the persisted Paykit copy in an iOS restore regression (#1307, review note).

QA Notes

Setup

Run PubkyProfileManagerTests.testCreateIdentityPreservesUnreadTagsFromTheRestoreFormAfterRefresh in the Bitkit scheme. It uses an injected profile reader and publisher on an iOS simulator.

Automated Checks

  • Added PubkyProfileManagerTests.swift to verify the restore snapshot’s unread flag reaches publication after a successful background refresh.

Evidence

The iOS simulator build passed. The unit suite finished with 3,218 passes and one skip, including the new regression. SwiftFormat 0.64.6 passed on all three changed Swift files. Local Xcode 26.0 needed the dependency’s default secp256k1 C modules enabled explicitly.

Models used

  • Planning/scoping: GPT-6 (reasoning: Not exposed)
  • Implementation: GPT-6 (reasoning: Not exposed)
  • Review: Not performed

The session exposes the model family. It does not expose the variant or reasoning setting.

@greptile-apps

greptile-apps Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

Preserves the restore form’s original unread-tags flag through identity creation.

  • Restored profiles keep their saved tags when the form opened without them.

Reviews (1) · Last reviewed commit: "fix: preserve tags when restoring a prof..." · Reviewed by Greptile

@talosmachina talosmachina left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No findings. Passes the restore form's own unread-tags flag from CreateProfileView into createIdentity, so a restore save still merges the stored Paykit tags after a later load cleared tagsUnavailable. Reviewed 1f32d37, light tier, static (iOS does not build on this reviewer's Linux host; CI covers the build).

What I checked, and 3 candidates I ruled out

Read in full: createIdentity, createProfile, writeProfile in PubkyProfileManager.swift; load and save in PubkyAppProfileStore.swift; loadInitialData and remoteProfile in CreateProfileView.swift
Call sites traced: every createIdentity( caller (only CreateProfileView), every baseTagsUnread: caller (EditProfileView, ProfileView already passed it)
CI: SwiftFormat, validate and integration tests green; Run Tests still running at review time

Ruled out

  • The bug before the fix: save computed copyUnread = data.baseTagsUnread || tagsUnavailable.contains(key); a successful refresh removes the key, so storedCopy returned (nil, nil) and tags(data.tags, keeping: nil) wrote the form's empty list. With the flag carried, storedCopy re-reads the copy and tags(_:keeping:) keeps it.
  • Signed-out restore path: remoteProfile falls back to fetchRemoteProfile, whose profile never sets tagsUnread, so it passes false as before; unchanged behaviour, not this diff.
  • Copy still unreadable at save: storedCopy returns nil, tags stays nil, and the profile is stored with tagsUnread kept true, so nothing is overwritten.

Merge confidence: 4/5, the unit-test job was still running when this was posted; the new test covers the change.

@ovitrif ovitrif added this to the 3.2.0 milestone Nov 12, 2026
@ovitrif

ovitrif commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator

Triage: milestone 3.2.0, as its Android twin synonymdev/bitkit-android#1884. This PR fixes the pubky.app profile restore on master and closes no issue, so it carries the milestone itself. Cherry-picking it into 3.1.1 stays your call.

@jvsena42 jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No findings.

  • CreateProfileView passes the snapshot's tagsUnread (existingProfile is @State, set once in loadInitialData, so a manager refresh can't change it) through PubkyProfileManager to profileData.baseTagsUnread.
  • PubkyAppProfileStore.save then re-reads the stored copy and unions the tags.
  • If the copy is unreadable at save, nothing is written and the stored profile keeps tagsUnread = true. That is stricter than Android, which doesn't re-arm the flag in that case.
  • Everything is keyed by the normalized public key.

Two notes, neither blocking:

  • PubkyProfileManagerTests.swift:1317 only checks that the flag reaches the publisher. No test runs PubkyAppProfileStore.save with baseTagsUnread, while the Android twin synonymdev/bitkit-android#1884 covers it end to end.
  • The same changelog point as on Android applies if iOS release-3.1.1 carries this fix.

Device gate: no device check needed: no UI change, and the state needs fault injection. perf: one conditional extra read. CI: 8 pass, 1 pending.

Reviewer model: Claude Fable 5.2 (claude-fable-5-2), Claude Opus 5.5 (claude-opus-5-5)
Reasoning effort: not exposed

Copy link
Copy Markdown
Collaborator Author

Following up on the approval notes.

  • The regression checks that the restore snapshot’s unread flag reaches the publisher after a refresh. The persisted-copy assertion is tracked in test: verify that an iOS restore save preserves stored Pubky profile tags #1307 because it needs to exercise the store’s Paykit read and write.
  • The repository requires a changelog fragment for each user-facing fix, so the fragment stays with this master PR.

@ovi-reviewer ovi-reviewer Bot mentioned this pull request Nov 12, 2026
3 tasks
@piotr-iohk
piotr-iohk merged commit 5557e80 into master Nov 12, 2026
23 checks passed
@piotr-iohk
piotr-iohk deleted the codex/preserve-restored-profile-tags branch November 12, 2026 12:33
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.

4 participants