This repository was archived by the owner on Apr 20, 2026. It is now read-only.
Subgroups: NIP-29 hierarchy, manifests, and inherited membership enforcement#21
Open
Anderson-Juhasc wants to merge 1 commit into
Open
Subgroups: NIP-29 hierarchy, manifests, and inherited membership enforcement#21Anderson-Juhasc wants to merge 1 commit into
Anderson-Juhasc wants to merge 1 commit into
Conversation
- parent tag with optional admin attestation pubkey (third element) - bilateral child declaration with optional order/flags - closed-children / open-children paired flags - explicit clear markers: bare ["parent"] / ["parent",""] and bare ["child"] - cycle rejection at pre-save AND at startup replay - detach, delete-promotes-children-to-roots, independent membership - global chronological replay of kind:9002 to rebuild wrapper state - 15 integration tests in khatru29/subgroups_test.go Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
78cb54d to
f9641ca
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the NIP-29 subgroups section in full:
parenttag with optional admin attestation, bilateral child declaration, and pairedclosed-children/open-childrenflags. Cycle rejection runs both at event-accept time and at startup replay.Changes
groups.go:Parent,ParentAttester,Children,ChildEntries,ClosedChildrenonGroup;ChildEntrystruct. Load now runs a second pass that replays everykind:9002in global chronological order and cycle-checks each parent update — a runtime-rejected event that still lives in the DB can no longer corrupt the in-memory tree.subgroups.go(new):ToMetadataEventoverride emits theparenttag with attester, anychildtags (with optionalorder/flags), and theclosed-childrenflag when set.WouldCreateCycle;Reparent(group, newParent, attester)serialized viareparentMu;promoteChildrenToRootsclears both parent and attester.moderation_actions.go:EditMetadatagainsParentValue *string,ChildEntriesValue *[]ChildEntry,ClosedChildrenValue *bool. Parsing handles bare["child"]as a clear marker and["open-children"]as the unset pair forclosed-children.event_policy.go: cycle rejection atRejectEvent; applies child-list / closed-children under the wrapper lock; threads the authoring admin's pubkey as the attester intoReparent. Onkind:9008, detaches from parent and promotes each child to root (broadcasting a freshkind:39000withoutparent).state.go:reparentMu sync.Mutex.Behavior
kind:39000carries["parent", "<d>", "<admin-pk>"]when set; on detach the attester is cleared.["parent"]and["parent", ""].["child", "<id>", "<order>", "<flags>...]tags round-trip viakind:9002→kind:39000. Replacement semantics: akind:9002with anychildtags replaces the whole list. A bare["child"]tag clears it.["closed-children"]/["open-children"]flip a single flag symmetrically, mirroring the existingopen/closedandpublic/privatepairs.kind:39000for each former child withoutparent.Test plan
go test ./...passeskhatru29/subgroups_test.go— 15 integration tests covering:kind:39000childtags withorder/flagsround-tripclosed-childrenset and unset viaopen-children["child"]clears the listkind:9002ignored