Conversation
…en-filter chokepoint Three of the five requested features (notifications + archive-on-import follow in PR 3). 2a. Three suggested records in contact pickers New ContactSuggestionEngine ranks candidates by contextual similarity to the subject — shared tags (x3), groups (x2), locations (x2), plus a per-field signal — and falls back to relationship score so suggestions are always available. IntroducedToPickerView and MetViaPickerView now show a "Suggested" section (top 3) when not searching, with the rest under "All Contacts". 2b. Click column headers to sort ContactListViewModel gains sortColumn + sortAscending and toggleSort(): clicking a header sorts by that column; clicking the active column flips direction. The active column shows a chevron. Sorts Name, Score, Groups, Locations, Tags, Met via, Introduced to (string columns sort their first value alphabetically with blanks last; numeric columns default to descending). The sort menu was updated to the same model and keeps Recent/Added. Replaces the old ContactSortOrder enum. 2e. Hidden contacts excluded from every search surface Audit found all selection surfaces already filtered !isHidden && !isMergedAway. Added a single chokepoint — `Sequence<Contact>.selectable` — and adopted it in the contact pickers and ContactListViewModel so the CLAUDE.md rule has one enforcement point. (A hidden contact still appearing on another device is sync propagation, not a missing filter — same conflict-resolution family as the score fix in PR #48.) Tests: ContactSuggestionEngineTests (ranking, exclusions, score fallback) and ContactListViewModelTests (+toggle direction, string-column blanks-last, .selectable). Full macOS suite green (226 tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Three of the five requested features. Stacked on #48 (base will retarget to
mainwhen #48 merges). Notifications chiclet + archive-on-import follow in PR 3.2a — Three suggested records in contact pickers
New
ContactSuggestionEngineranks candidates by contextual similarity to the subject — shared tags (×3), groups (×2), locations (×2), plus a per-field signal — with a relationship-score fallback so suggestions are always available.IntroducedToPickerViewandMetViaPickerViewnow show a Suggested section (top 3) when not searching, with the remainder under All Contacts. The engine is reusable for any future record field.2b — Click column headers to sort
ContactListViewModelgainssortColumn+sortAscendingandtoggleSort(). Clicking a header sorts by that column; clicking the active column flips direction (active column shows a ▲/▼ chevron). Covers Name, Score, Groups, Locations, Tags, Met via, Introduced to — string columns sort by their first value alphabetically with blanks last; numeric columns default to descending. The sort menu was migrated to the same model and keeps Recent/Added.2e — Hidden contacts excluded from every search surface
Audit result: every selection surface already filtered
!isHidden && !isMergedAway(the two pickers in the screenshots included). Added a single chokepoint —Sequence<Contact>.selectable— and adopted it in the contact pickers +ContactListViewModel, so the CLAUDE.md rule has one enforcement point and a regression test. A hidden contact still appearing on another device is sync propagation, not a missing filter (same conflict-resolution family as the score fix in #48) — called out, not silently bundled.Tests
ContactSuggestionEngineTests: similarity ranking, exclusion of self/hidden/excluded IDs, score fallback always returns 3.ContactListViewModelTests: direction toggle, string-column blanks-last in both directions,.selectablehelper.🤖 Generated with Claude Code