Skip to content

fix: relay confirmation before merge and welcome (MIP-02/MIP-03)#46

Open
alltheseas wants to merge 1 commit intoVectorPrivacy:masterfrom
alltheseas:fix/relay-confirmation-before-merge
Open

fix: relay confirmation before merge and welcome (MIP-02/MIP-03)#46
alltheseas wants to merge 1 commit intoVectorPrivacy:masterfrom
alltheseas:fix/relay-confirmation-before-merge

Conversation

@alltheseas
Copy link

@alltheseas alltheseas commented Feb 16, 2026

What this fixes

When you add someone to a group chat, Vector immediately updates its own local state as if everything worked — then tries to tell the relay network about it in the background with no retries. If the relay is down or rejects the message, the person you invited never gets their welcome message, and your group is now permanently broken. Messages you send won't decrypt for other members. The only fix is to create a new group.

After this fix, when you add someone to a group chat, the button clears instantly (no change in feel). Behind the scenes, Vector now waits for at least one relay to confirm it received the group update before finalizing. Only then does it send the welcome to the invited person. If all relays are down, nothing changes locally — your group stays in a working state and you can try again later.

Same thing for removing someone from a group.

Technical details

  • Defer merge_pending_commit until relay confirmation: add_member_device and remove_member_device no longer merge the pending commit before publishing. Instead, the commit is created, and a background task handles relay publish → merge → welcome delivery in the correct order.
  • Add publish_event_with_retries helper: 5-attempt exponential backoff (250ms base) matching pika core's pattern, with NIP-42 auth retry handling.
  • Non-blocking Tauri commands: Both functions return immediately after creating the commit. The background task handles the rest, so the frontend "Inviting..."/"Removing..." UI clears instantly.

Before:

engine.add_members()
engine.merge_pending_commit()   ← merged before relay confirm
tokio::spawn(send_event(...))   ← fire-and-forget, no retries
send welcomes immediately       ← no ordering guarantee

After:

engine.add_members()            ← create commit, don't merge
return Ok(())                   ← frontend unblocked
background:
  publish_event_with_retries()  ← relay confirmation with retries
  engine.merge_pending_commit() ← only after relay ack
  send welcomes                 ← only after commit is on relay
  emit UI update
  • MIP-02: Welcome now arrives only after the commit it references is on a relay
  • MIP-03: Local state only advances after relay confirms — no permanent divergence if all relays reject
  • MDK docs: merge_pending_commit docstring says "This should be called AFTER publishing the Kind:445 message"

Test plan

  • cargo check in src-tauri/
  • Add member to group → UI clears immediately, member appears after background merge, welcome arrives after commit is on relay
  • Remove member from group → UI clears immediately, member list updates after background merge
  • Kill all relays → commit is not merged locally, no silent state divergence

🤖 Generated with Claude Code

Rewrite add_member_device and remove_member_device to defer
merge_pending_commit until after relay confirmation, matching
MDK's documented ordering requirement.

Before: merge locally → fire-and-forget publish → send welcomes
After:  create commit → return immediately → background: relay
        publish with retries → merge → send welcomes → UI update

The Tauri command returns immediately (no UX blocking). A new
publish_event_with_retries helper provides 5-attempt exponential
backoff matching pika core's pattern.

This prevents permanent group state divergence when all relays
reject the commit, and ensures welcomes reference a commit that
is actually available on relays (MIP-02).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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