block / block/buzz

Threaded replies omit the NIP-10 p tag for the parent author — replying to someone never notifies them

Open
#3,032 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

## Summary

A threaded reply carries NIP-10 `e` tags (root/reply markers) but **no `p` tag for the author being replied to**. Buzz notifications are `#p`-based, so replying to someone in a thread never notifies them unless you *also* type their `@name`. In a thread you are, by definition, replying to a specific person — they should be notified.

This is the same class as #2568 (reactions dropped the `p` tag); @vitorpamplona flagged it as a follow-up on that PR. NIP-10 says a reply's `p` tags SHOULD list the pubkeys being replied to; Buzz emits the `e` markers but omits the matching `p`.

Confirmed on `main` @ `499c5d34`.

## Where the `p` tag is dropped

Every reply builder emits `e` tags for threading but sources `p` tags **only** from explicit `@mentions`:

- **SDK** — `crates/buzz-sdk/src/builders.rs:173` `thread_tags` pushes only `["e", …, "reply"]` / `["e", …, "root"]`. `p` tags come solely from `mention_tags` (builders.rs:188), i.e. parsed `@mentions`. `build_message` (kind 9) threads these two independently.
- **Desktop** — `desktop/src-tauri/src/commands/messages.rs:432` `resolve_thread_ref` already fetches the parent event (to read its root), so `parent.pubkey` — the signer — is right there, but it is discarded. `send_channel_message` p-tags only the composer's `@mention_pubkeys`.
- **Mobile** — `mobile/lib/features/channels/send_message_provider.dart:56` builds `_buildReplyTags` (e-tags) plus `p` tags from `normalizedMentions` (explicit mentions) only.

## Why it's a real notification miss

Notification/feed reads are `#p`-only, with no fallback that derives the parent author from the reply `e`-tag:

- Desktop feed: `{"kinds":[9,40002,1,45001,45003],"#p":[self]}` (`commands/messages.rs`).
- Mobile activity: same kind set, `#p:[self]` (`activity_provider.dart`).
- Push leases advertise kind 9 and subscribe by `#p` (`push_lease.rs`).
- Relay ingest updates thread counters but never injects a `p` tag or notifies the parent author from the `e`-tag (grep of `ingest.rs`/`side_effects.rs`).

So: no `p` tag → the replied-to author gets no feed entry and no push.

## Reproduce

1. User A posts a message in a channel.
2. User B opens the thread on that message and replies **without** typing `@A`.
3. The kind:9 reply carries `[["h",…],["e",,"","root"],["e",,"","reply"]]` and no `["p", ]`.
4. User A's mentions feed (`#p:[A]`) does not include the reply; no push fires.

Expected: A is notified that B replied to them.

## Suggested fix

When building a threaded reply, add the parent event's **signer** as a `p` tag (deduped against existing mentions, self excluded) — mirroring the fix approach in #2634 (use the signer, not the resolved display author):

- Desktop: `resolve_thread_ref` already holds `parent.pubkey`; thread it into the reply's `p` tags — no extra query.
- Mobile: the thread compose bar has the `threadHead` message; pass its author through.
- SDK/CLI/ACP: carry the parent author alongside the existing `ThreadRef`.

## Note / product check

This is standard chat behavior (Slack/Discord notify the parent on a thread reply) and NIP-10-conformant, so I'm treating it as a bug. If the team would rather gate reply-notifications behind a preference, say so and I'll adjust — but the `p` tag being absent from the wire form is a conformance gap regardless.

I have a fix in progress across all surfaces; PR to follow.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.