Skip to content

fix(cli): dms list must query the relay-emitted kind:39000, not kind:41001 - #9

Open
lodar wants to merge 1 commit into
upstream-base-f88cda9ebfrom
upstream-pr/dms-list-kind-39000
Open

fix(cli): dms list must query the relay-emitted kind:39000, not kind:41001#9
lodar wants to merge 1 commit into
upstream-base-f88cda9ebfrom
upstream-pr/dms-list-kind-39000

Conversation

@lodar

@lodar lodar commented Aug 20, 2026

Copy link
Copy Markdown

The bug

buzz dms list queries {kinds:[41001], "#p":[me]}. KIND_DM_CREATED (41001) is declared in
buzz-core but no code path in this repo ever emits it, so the verb returns [] for every
account on every relay — while channels list, channels members and messages get all see the
same conversation. Because it returns an empty list rather than an error, it reads as "no DMs
exist" instead of "my predicate matched nothing".

The fix

Query the kind the relay actually emits: kind:39000 NIP-29 group metadata.
emit_group_discovery_events tags it with t=<channel_type> plus one p tag per participant for
DMs.

kind:39000 is absent from required_scope_for_kind's allowlist, so client ingest rejects it as
restricted: unknown event kindonly the relay can author one. t=dm is therefore
relay-attested channel_type rather than a client-supplied name/membership heuristic, which matters
because consumers skip the @-mention test on the DM path.

Changes:

  • dm_list_filter() — extracted, so a regression to a kind nothing emits is a red test rather than
    a silent empty list.
  • parse_query_events() — a relay error object is now an error, not an empty inbox. The old
    unwrap_or_default() made a dead relay indistinguishable from "no DMs".
  • dms_from_group_metadata() — keeps only t=dm with a non-empty d tag that lists us; a valueless
    ["t"] tag no longer masks a later ["t","dm"]; newest revision per channel wins; sorted newest
    first.
  • KIND_DM_CREATED annotated as reserved-and-unemitted.

Testing

9 new buzz-cli unit tests plus an end-to-end arm in buzz-test-client
(e2e_nostr_interop.rs) that pins the wire kind against a live relay, so the relay and the CLI
cannot drift apart again.

Graded on the original tree at 358/0 buzz-cli (9 new), 249/0 buzz-core, clippy clean, fmt clean;
9 mutants all killed (accept any channel_type; drop the participant re-check; accept an empty uuid;
degrade a relay error to []; keep the oldest revision; query the old kind; …).

…d:41001

`dms list` queried `{kinds:[41001], "#p":[me]}`. `KIND_DM_CREATED` (41001) is
declared in buzz-core but no code path in this repo ever emits it, so the verb
returned `[]` for every account on every relay while `channels list`, `channels
members` and `messages get` all saw the same conversation. An empty list rather
than an error is why this reads as "no DMs exist" instead of "my predicate
matched nothing".

The relay-emitted truth is kind:39000 NIP-29 group metadata, which
`emit_group_discovery_events` tags with `t=<channel_type>` plus one `p` tag per
participant for DMs. kind:39000 is absent from `required_scope_for_kind`'s
allowlist, so client ingest rejects it as "restricted: unknown event kind" —
only the relay can author one. `t=dm` is therefore relay-attested channel_type
rather than a client-supplied name/membership heuristic, which matters because
consumers skip the @-mention test on the DM path.

- `dm_list_filter()`: extracted so a regression to a kind nothing emits is a red
  test, not a silent empty list.
- `parse_query_events()`: a relay error object is an error, not an empty inbox.
  The old `unwrap_or_default()` made a dead relay indistinguishable from no DMs.
- `dms_from_group_metadata()`: keeps only `t=dm` with a non-empty `d` tag that
  lists us; a valueless `["t"]` tag no longer masks a later `["t","dm"]`; newest
  revision per channel wins; sorted newest first.
- Annotated `KIND_DM_CREATED` as reserved-and-unemitted.

Adds an end-to-end interop arm in buzz-test-client that pins the wire kind, so
the relay and the CLI cannot drift apart again.

Signed-off-by: lodar <markounik@gmail.com>
@lodar
lodar force-pushed the upstream-pr/dms-list-kind-39000 branch from 14fc3c1 to 7c9f6ed Compare August 26, 2026 03:05
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