Skip to content

Commit 1fcaafa

Browse files
Apply suggestions from code review
Excellent, well-crafted! Co-authored-by: fiatjaf <fiatjaf@gmail.com>
1 parent 3af731e commit 1fcaafa

1 file changed

Lines changed: 13 additions & 12 deletions

File tree

29.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,10 @@ Groups MAY be organized hierarchically. A subgroup is an ordinary NIP-29 group (
223223

224224
```jsonc
225225
// root group
226-
{ "kind": 39000, "tags": [["d", "tech"], ["name", "Tech"]] }
226+
{ "kind": 39000, "tags": [["d", "tech"], ["name", "Tech"], ["child", "nostr"]] }
227227

228228
// subgroup
229-
{ "kind": 39000, "tags": [["d", "nostr"], ["name", "Nostr"], ["parent", "tech"]] }
229+
{ "kind": 39000, "tags": [["d", "nostr"], ["name", "Nostr"], ["parent", "tech"], ["child", "nip29"]] }
230230

231231
// sub-subgroup
232232
{ "kind": 39000, "tags": [["d", "nip29"], ["name", "NIP-29"], ["parent", "nostr"]] }
@@ -245,18 +245,17 @@ A relay that supports subgroups SHOULD advertise it in its NIP-11 relay informat
245245
}
246246
```
247247

248-
The `nip29` object is a namespace for NIP-29 feature flags; clients MUST ignore keys they do not understand, and the absence of the object or of `subgroups` means the relay makes no claim of support. This lets a client check capability with a single NIP-11 request, before publishing anything.
249-
250-
Support is also observable directly: a client that receives any `kind:39000` with a `parent` tag knows the relay honors them, whatever NIP-11 says. A relay that does not support subgroups SHOULD ignore the `parent` tag rather than reject the event.
251-
252248
### Rules
253249

254-
- A `kind:9002` SHOULD carry at most one `parent` tag. An empty value (`["parent"]` or `["parent", ""]`) is equivalent to the tag being absent and makes the group a root. The resulting `kind:39000` therefore also carries at most one `parent` tag.
255-
- Relays SHOULD reject a `kind:9002` whose `parent` value would create a cycle, including self-reference, rather than emit the resulting `kind:39000`.
256-
- If a group's declared parent does not exist on the relay, the subgroup is treated as a root. When a parent is deleted (`kind:9008`), its remaining children automatically become roots.
257-
- Re-parenting and promotion to root are triggered by a `kind:9002` (`edit-metadata`) event from an authorized admin with the desired `parent` value (or no `parent` tag to detach); the relay then updates the group's `kind:39000` accordingly. Historical events under the group's `h` tag remain valid across these transitions.
258-
- Relays MUST reject any `kind:9002` carrying `["parent", "X"]` unless the event author is an admin of `X` (per `X`'s `kind:39001`). Because `kind:9002` already requires admin status on the child group it edits, this means a parent-child relationship can only be established or changed by someone authorized on both sides, i.e. bilateral consent enforced at write time by the relay. Moving a group to a new parent requires no consent from its previous parent: only the child's own admin (already required to edit it) and the admin of the new parent need to agree. Detaching or re-parenting is unilateral from the old parent's side, the same way leaving a group never requires the counterparty's permission.
259-
- A parent group's `kind:39000` MAY include `["child", "<id>"]` tags as an optional ordered list of its children; the position of each tag in the array is the order. The list is set by the parent's admin via a `kind:9002` carrying the desired `["child", ...]` tags in order, and each edit replaces the previous list. The `parent` tag on each child remains the source of truth for the relationship; `child` entries that do not correspond to a group whose `parent` tag points back MUST be ignored. This list also lets a client walk the tree top-down without fetching every group: because `parent` is a multi-character tag it cannot be used in a relay filter, so the only way to find a group's children server-side is to read the parent's `child` ids and fetch them by `["#d", ...]`. The list is a convenience hint, not an authoritative list: a child whose `parent` points at the group but that the parent's admin never added will be missed, so a client needing exhaustive discovery still falls back to fetching all `kind:39000` and grouping by `parent`.
250+
- Parenting and promotion to root are triggered by a `kind:9002` (`edit-metadata`) event from an authorized admin with the desired `parent` value (or no `parent` tag to detach); the relay then updates the group's `kind:39000` accordingly. The relay also updates the parent's `kind:39000` to include the newly added child as a `child` tag (and vice-versa). If a group is switching from one parent to another parent the relay also updates the previous parent accordingly.
251+
- Historical events under the group's `h` tag remain valid across these transitions.
252+
- A `kind:9002` MAY carry at most one `parent` tag. The resulting `kind:39000` therefore also carries at most one `parent` tag.
253+
- Absence of the `parent` tag makes the group a root.
254+
- Relays MUST reject a `kind:9002` whose `parent` value would create a cycle, including self-reference.
255+
- If a group's declared parent does not exist on the relay the `kind:9002` MUST be rejected.
256+
- When a parent is deleted (`kind:9008`), its remaining children automatically become roots.
257+
- Relays MUST reject any `kind:9002` carrying `["parent", "X"]` unless the event author is also an admin of `X` (per `X`'s `kind:39001`).
258+
- A parent group's `kind:39000` MUST include `["child", "<id>"]` tags as an ordered list of its children; the position of each tag in the array is the order. By default relays can just append new children to the list as they are created, but the list can be rearranged by the parent's admin via a `kind:9002` carrying the desired `["child", ...]` tags in order, and each edit replaces the previous list. `kind:9002` metadata edits that do not include all the children as `child` tags MUST be rejected.
260259

261260
### Lifecycle example
262261

@@ -265,11 +264,13 @@ Support is also observable directly: a client that receives any `kind:39000` wit
265264
{ "kind": 9002, "tags": [["h", "nostr"], ["parent", "social"]] }
266265
// Relay emits:
267266
{ "kind": 39000, "tags": [["d", "nostr"], ["name", "Nostr"], ["parent", "social"]] }
267+
{ "kind": 39000, "tags": [["d", "social"], ["child", "nostr"]] }
268268

269269
// Admin promotes "nostr" to root (parent dropped)
270270
{ "kind": 9002, "tags": [["h", "nostr"], ["parent", ""]] }
271271
// Relay emits:
272272
{ "kind": 39000, "tags": [["d", "nostr"], ["name", "Nostr"]] }
273+
{ "kind": 39000, "tags": [["d", "social"]] }
273274
```
274275

275276
### Membership

0 commit comments

Comments
 (0)