Reading a public group needs no permission. Everything past that does, and NIP-29 hands all of it to the relay.
Joining is a kind 9021 carrying an h tag with the group id, published to that group's relay, optionally with a code tag for an invite. The relay answers by adding me to the kind 39002 member list it publishes, or by not doing that. Leaving is a 9022 the same way. Posting into a group is an ordinary event with the h tag added, sent to that one relay, and the relay is entitled to refuse it: a false OK with a reason is the normal answer for a non-member, not a transport failure. Moderation is kinds 9000 to 9007, authored by the relay, which a client reads and never writes.
Two things the current publish path gets wrong for this, both correct for the outbox model.
publishEvent walks every slot marked write and sends the event to all of them. A group post belongs to exactly one relay. Broadcasting an h-tagged event across my own relays hands the group's traffic to hosts with no business seeing it, silently.
And the verdict goes into recordOutboxAck as an accepted or refused bit against a slot index. The OK's message, which is where the relay explains itself, is not read at all, so a membership refusal arrives as a publish that failed rather than as an answer I can act on.
Depends on NIP-42: the relay decides membership by pubkey, so it has to know whose connection this is before a 9021 means anything.
Done
I can send a join request and see what the relay decided, post into a group with the post reaching that relay and no other, read a refusal in the relay's own words, and leave.
Reading a public group needs no permission. Everything past that does, and NIP-29 hands all of it to the relay.
Joining is a kind 9021 carrying an
htag with the group id, published to that group's relay, optionally with acodetag for an invite. The relay answers by adding me to the kind 39002 member list it publishes, or by not doing that. Leaving is a 9022 the same way. Posting into a group is an ordinary event with thehtag added, sent to that one relay, and the relay is entitled to refuse it: afalseOK with a reason is the normal answer for a non-member, not a transport failure. Moderation is kinds 9000 to 9007, authored by the relay, which a client reads and never writes.Two things the current publish path gets wrong for this, both correct for the outbox model.
publishEventwalks every slot marked write and sends the event to all of them. A group post belongs to exactly one relay. Broadcasting anh-tagged event across my own relays hands the group's traffic to hosts with no business seeing it, silently.And the verdict goes into
recordOutboxAckas an accepted or refused bit against a slot index. The OK'smessage, which is where the relay explains itself, is not read at all, so a membership refusal arrives as a publish that failed rather than as an answer I can act on.Depends on NIP-42: the relay decides membership by pubkey, so it has to know whose connection this is before a 9021 means anything.
Done
I can send a join request and see what the relay decided, post into a group with the post reaching that relay and no other, read a refusal in the relay's own words, and leave.