feat(desktop): hide archived identities from discovery surfaces (NIP-IA)#734
Merged
Conversation
Implements Dawn's discovery-sweep contract (v2, stamped by Eva): every
forward-looking discovery surface in the desktop hides archived
identities, while history and audit surfaces leave them visible.
The shape:
- One predicate, applied uniformly. `useIsArchivedPredicate` wraps the
`kind:13535` snapshot in a Set for O(1) lookup, fails open while
loading (cold-start can't briefly hide everyone), no `currentPubkey`
carve-out (NIP-IA's anti-shadowban property surfaces in the UI; the
profile pane's flair and `selfMember` role lookup are independent of
bucket — self folds where archive state puts it).
- `useClassifiedMembers` peels archived FIRST, then splits remainder
into people/bots. Archived wins over bot — a zombie agent under
"Bots" defeats NIP-IA's headline use case.
- Filter at consumers, never at the query — `extractMentionPubkeys`
must still resolve archived authors' historical @-mentions.
Surfaces touched (Dawn's table):
- MembersSidebar.tsx: foldable "Archived (N)" `<details>` section
below People + Bots, only rendered when archived.length > 0.
- useMentions.ts: `.filter` pre-scoring in `suggestions` memo only —
`members` source stays unfiltered for history resolution.
- NewDirectMessageDialog.tsx, ChannelMemberInviteCard.tsx,
RespondToField.tsx: one `!isArchivedDiscovery(user.pubkey)` clause
added to each existing search-results `.filter`.
Surfaces deliberately left alone (per Dawn's table): channel-members
count pill, ChannelManagementSheet internal lookups, ChannelScreen
timeline/typing enrichment, extractMentionPubkeys, AddAgentToChannel
"already in channel" predicate. All consume `useChannelMembersQuery`
but render history / role state / internal-only — Tyler's "never hide
messages" rule.
Tests (tests/e2e/identity-archive-hide.spec.ts, in smoke project):
1. Archived member folds under "Archived (N)", not active People list.
2. No Archived section when no archived members.
3. Mention autocomplete filters archived; non-archived still
suggestable (proves autocomplete is functional, not always-empty).
4. DM picker hides archived from search; non-archived still searchable.
5. History invariant: archived user's existing message still renders
with their display name in the timeline.
Bonus: `mention-suggestion-${pubkey}` testid added in
MentionAutocomplete.tsx so the autocomplete spec can assert
presence/absence by pubkey rather than text matching.
Verification:
- `pnpm exec playwright test --project=smoke`: 110 passed (was 105;
+5 new, 0 regressions).
- `pnpm typecheck`, `pnpm check`: clean.
- Pre-commit (rust-fmt, desktop-tauri-fmt, desktop-check, web-check,
mobile-check): all green.
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
ff1e561 shipped Shape B — predicate identity-only, no `currentPubkey` carve-out, self folds in own Archived section. Eva's final stamp in the thread (msg [10], superseding her earlier [8]) is Shape A: self is *never* filtered or folded from their own client, NIP-IA §Self Requests anti-shadowban property. I built from Dawn's intermediate [9] message before the final stamp landed. Two design points worth recording: 1. **Where self-exemption lives.** Dawn's locked v2 helper takes `currentPubkey` as an arg and threads it through every caller. Reading identity inside the predicate via `useIdentityQuery` (global, infinite-staleTime) is materially better: - No prop drilling through useMentions, RespondToField, etc. - Impossible for a future caller to forget the self-exemption. - One source of truth for "what is self". Net diff vs. arg-threading: ~zero callers change, one helper gains 3 lines. 2. **Why this is a real bug, not a polish.** Without self-exemption, a self-archived user loses their own seat in the members sidebar AND drops from their own @-autocomplete — both reproducible with the new tests. That's exactly the shadowban NIP-IA §Self Requests exists to prevent. Tests added: - self-exemption: archived current user still appears in their own People list (not folded). Asserts "You" + "deadbeef" prefix in members-sidebar-people AND members-sidebar-archived has count 0. - self-exemption: archived current user can still self-mention in their own autocomplete. Confirms the predicate's self-exemption fires at the suggestion filter, not just the panel partition. Verification: - `pnpm exec playwright test --project=smoke`: 112 passed (was 110, +2 new self-exemption cases). Pre-existing 5 cases unchanged. - `pnpm typecheck`, `pnpm check`: clean. Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Adds the channel member-adder (ChannelMemberInviteCard) to the hide e2e matrix — the one hard-filter surface Max's review flagged as code-correct but untested. Tested in #agents (where Alice is a non-member) with a paired control run so the assertion proves the archive filter drops her, not member-exclusion.
f3d55ed to
c95d140
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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
NIP-IA follow-up: hide archived identities from forward-looking discovery surfaces in the desktop GUI. Never hides messages in channels or DMs — history stays fully intact; an archived person's past posts render normally with their name. They simply stop appearing in "who's here / who can I add / who can I mention" surfaces.
Builds on #733 (the relay backend +
kind:13535archived-set client plumbing). No backend change.Behavior
extractMentionPubkeys(resolves archived authors' past @-mentions), internal membership predicates.Key design decisions
useIsArchivedPredicate()reads the archived set + the current identity internally — the current user is never hidden or folded from their own client (NIP-IA §Self Requests anti-shadowban property). Self-exemption is structural, not a caller parameter, so it can't be forgotten.Verification
identity-archive-hide.spec.ts: 7 cases (fold, no-section-when-empty, autocomplete filter + positive, DM filter + positive, history invariant, 2× self-exemption).pnpm exec playwright test --project=smoke: 112 passed (was 105 on main; +7, 0 regressions).pnpm typecheck+pnpm checkclean; full pre-push gate green.