railView's doc comment states the rule the primary rail follows: a rail item that goes nowhere is worse than one fewer, which is the same rule that keeps Groups off until NIP-29 ships. Nothing else in the app knows what a group is.
NIP-29 puts the relay in charge. A group is a relay plus a group id. Every event in it carries an h tag whose value is that id. The name, picture and about text come from a kind 39000 the relay itself publishes under a d tag equal to the group id, and 39001 and 39002 carry admins and members the same way. None of it is authored by a member.
The shape is not the outbox model, which routes by author. It is startPlaceFeed and placeFeedWorker: one named relay dialed outside the pool on its own thread, held open past EOSE because a room is somewhere you sit, every write generation-guarded so a reader who leaves does not get the previous room's notes. A group timeline is that worker with an #h filter in place of the bare kinds:[1].
The names collide, so worth stating: a place is Plaza's own place_kind (30078) and has nothing to do with NIP-29. They should not share a code path because they share a rail.
The store needs no change. classify in the library already treats 30000 to 39999 as parameterized-replaceable keyed by the d tag, and every single-letter tag is indexed on ingest.
Pieces: somewhere to paste a group address (the same door #111 asks for); the 39000 metadata query; the #h timeline, with which kinds render (9 chat, 11 threads) decided here and written down where it lands; the NIP-11 gate, so a relay that does not declare 29 says so rather than showing an empty room; and the rail destination once it has somewhere to go.
Done
Given a group address on a NIP-29 relay, Plaza shows the group's name and picture from the relay's own 39000 and renders its timeline live, without joining anything. Deliberately not here: joining, posting, moderation.
railView's doc comment states the rule the primary rail follows: a rail item that goes nowhere is worse than one fewer, which is the same rule that keeps Groups off until NIP-29 ships. Nothing else in the app knows what a group is.NIP-29 puts the relay in charge. A group is a relay plus a group id. Every event in it carries an
htag whose value is that id. The name, picture and about text come from a kind 39000 the relay itself publishes under adtag equal to the group id, and 39001 and 39002 carry admins and members the same way. None of it is authored by a member.The shape is not the outbox model, which routes by author. It is
startPlaceFeedandplaceFeedWorker: one named relay dialed outside the pool on its own thread, held open past EOSE because a room is somewhere you sit, every write generation-guarded so a reader who leaves does not get the previous room's notes. A group timeline is that worker with an#hfilter in place of the barekinds:[1].The names collide, so worth stating: a place is Plaza's own
place_kind(30078) and has nothing to do with NIP-29. They should not share a code path because they share a rail.The store needs no change.
classifyin the library already treats 30000 to 39999 as parameterized-replaceable keyed by thedtag, and every single-letter tag is indexed on ingest.Pieces: somewhere to paste a group address (the same door #111 asks for); the 39000 metadata query; the
#htimeline, with which kinds render (9 chat, 11 threads) decided here and written down where it lands; the NIP-11 gate, so a relay that does not declare 29 says so rather than showing an empty room; and the rail destination once it has somewhere to go.Done
Given a group address on a NIP-29 relay, Plaza shows the group's name and picture from the relay's own 39000 and renders its timeline live, without joining anything. Deliberately not here: joining, posting, moderation.