kind:39002 NIP-29 discovery event drops owner-role members
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
`emit_group_discovery_events` (in `crates/buzz-relay/src/handlers/side_effects.rs`) regenerates the kind:39002 (member list) NIP-29 discovery event after every membership-affecting event (`handle_put_user` for kind:9000, `handle_join_request` for kind:9021). In every case I tested, the generated kind:39002 event's `p` tags never include a member whose role is `owner` — even though that member genuinely holds the role, confirmed multiple ways.
This means any client that determines "which channels am I a member of" by reading kind:39002 (this includes the desktop app's own sidebar, per its Tauri backend `commands/channels.rs`) will never show a channel as joined to its own owner.
## Repro
1. Create a channel as identity A (`channels create ...`) — A becomes the channel's `owner`.
2. `channels members --channel ` → A is **absent** from the result (only later-added non-owner members show up).
3. Confirm A really is an owner-role member: `channels leave --channel ` as A fails with `invalid: cannot remove the last owner` — this only happens if A is a real, current member.
4. To rule out any client-side issue (a separate `nostr`-crate self-p-tag-stripping behavior, see below), submit a fully valid kind:9000 event directly — `h`/`p`(=A)/`role=owner` tags all present, signed with `EventBuilder::allow_self_tagging()` so the tag isn't stripped client-side. Relay responds `accepted:true`.
5. `channels members --channel ` again — A is **still absent**.
Step 4/5 isolates this to `emit_group_discovery_events` itself: a fully accepted, valid `role=owner` membership write never appears in the regenerated discovery event.
## Impact
- Channel creators (and anyone granted `owner`) never see their own channels in the desktop sidebar or in `buzz-cli channels list --member`/`channels members`, despite having full, correct read/write access. It reads as "I'm not a member" when the member row is actually correct — confusing and hard to diagnose from the client side alone.
- Any downstream tooling that trusts kind:39002 for membership enumeration (bots, admin scripts, `channels list --member`) will silently miss every owner.
## Suggested fix
`emit_group_discovery_events`'s query for the kind:39002 `p` tag list should include all active members regardless of role, `owner` included.
Found while deploying a Cognitum-agent integration against a fresh community; happy to provide more detail (relay logs, exact request/response bodies) if useful.
Contributor guide
Research direction
Start in crates/buzz-relay/src/handlers/side_effects.rs at emit_group_discovery_events, then trace its membership query and the handle_put_user and handle_join_request callers. Reproduce with the channels create and channels members commands; done means an owner appears in the regenerated kind:39002 p tags and membership enumeration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100