mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-11 08:47:33 +00:00
Fixes found in a full audit of the NIP-29 relay-groups feature across quartz/commons/amethyst/cli. Correctness (app): - Own group messages never appeared in the timeline until an app restart: the optimistic send is consumed with a null relay, so attachToRelayGroup bailed on the relay==null guard, and the host relay's echo (new==false) was skipped by the "only attach when newly consumed" gate. Attach now runs on every arrival, gated on the note being loaded, and the null-relay case attaches to the already-open channel(s) for that group id. Also avoids the wrong-relay phantom by only fabricating a channel from real provenance. - Roster subscription was frozen after an in-place join/leave (state keyed on the stable account, never re-derived); it now invalidates on every liveRelayGroupList change, so a fresh join's 39002 admission is fetched. - membershipOf demoted a 39001 admin with an empty/unknown role to MEMBER, hiding moderation; presence in the admins list now means at least MODERATOR. - Members roster showed permanent truncated-hex names (one-shot getUserIfExists cached null); uses checkGetOrCreateUser so UsernameDisplay fills in when kind:0 arrives. Protocol / data: - GroupTag had no value equality → joined-group Sets never deduped and the StateFlow re-emitted on every identical re-arrival. Equality is now the (id, relay) pair, excluding the cosmetic name. - create/edit emitted non-canonical ["public"]/["open"] status tags; NIP-29 flags are presence-only, so only private/closed are emitted when set. - Metadata/member/admin supersede guards use <= so an equal-createdAt duplicate isn't reprocessed (first-arrival wins); updatedMetadataAt is now private-set. Relay-group channels are now included in the prune loops. CLI: - join/leave/create updated the kind:10009 list from a network-only drain; a slow/empty fetch could publish a fresh list containing ONLY the new group, wiping the rest. Now reads the local store (source of truth) too. - edit re-asserted both visibility axes from flag presence, so --closed on a private group leaked it public. It now reads current 39000 and merges, with --public/--open counter-flags; only the specified axis changes. - create now tracks the new group in kind:10009 (parity with join/Android). UI polish: - Invite dialog no longer mints a 9009 for open groups and won't copy a code it never displayed. Browse "popular" list normalizes URLs before filtering. Tests: GroupTag identity, unknown-role-admin-moderates, equal-createdAt no-resupersede added; all quartz+commons NIP-29 suites and the amy relaygroup harness pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B5MLY4hq5LXJ2D5WeLRyXj