Threaded replies omit the NIP-10 p tag for the parent author — replying to someone never notifies them
- 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
Assessment
This issue has not been assessed yet.