Nine files in libraries/ were importing from unicode-search/, pulling
plugin-layer types and Obsidian APIs into supposedly agnostic code.
Root cause: search result types lived in unicode-search/components/,
UnicodeSearchError lived in unicode-search/errors/, and toSearchQueryMatch
imported directly from obsidian.
- Move search result types to libraries/types/characterSearch.ts;
characterSearch.ts becomes a re-export facade
- Define SearchMatchResult inline (no obsidian import)
- Inline toSearchQueryMatch as FuzzySearchModal.toSearchMatch(); delete the file
- Introduce LibraryError in libraries/errors/ for library-layer throws;
retire the UnicodeSearchError imports from persistCache and getRandomItem
- Delete characterSearchAttributes.ts (absorbed into the new types file)
- Document the two-tier custom error policy in ADR-0015
The 14-file comparison cluster exposed one public seam per leaf function,
forcing callers and tests to understand the entire call graph to reason
about ranking. A single rankCharacterSearchResults module concentrates
the logic, reduces the public interface to one function, and lets tests
target the ranking behaviour directly rather than internal comparators.