Completes the search-provider-interface wiring that the catalog hardening
commits already call into:
- Skip the transactional search-index-event write path when Meilisearch is
not the active provider (ItemRepository.WithActiveSearchProvider /
SearchIndexEventRepository.disabledByActiveProvider).
- Dead-letter catalog_search_index_events after 10 attempts instead of
retrying forever.
- Track the rebuild high-water mark (MaxEventID / MarkProcessedThrough) and
persist last_processed_event_id in UpdateStateAfterRebuild so a rebuild
reconciles events enqueued during the rebuild.
- Validate (read-only) the embedding lock when embedding a search query
instead of establishing/mutating it.
- Surface total_exact on the legacy /items browse response.
- Wire the active catalog search provider into the scanner and item repo at
startup.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>