Shared matcher core migration
FuzzyMatcher now subclasses the shared FuzzyMatcherCore, vendored byte-identically into the inner folder as matching_core.py. Channel-Maparr is a PARTIAL subclass: it keeps its OTA normalize_name, the channel_lookup callsign rescue, and the single-digit token-overlap guard, and inherits the body-compatible primitives.
- matching_core.py is sha256-pinned (scripts/core_manifest.json) and enforced by a parity gate plus a golden gate in CI. It ships with the code: fuzzy_matcher.py imports FuzzyMatcherCore from it, so the plugin will not load without it.
- Rebrand and abbreviation aliases ported from Lineuparr (FXM to FX Movie Channel, HBO2 to HBO Hits, HBO Zone to HBO Movies, EPIX to MGM+, DIY to Magnolia, MoreMax to Cinemax Hits). Also fixed a reverse-index collision where a redundant FXM canonical shadowed FX Movie Channel.
- calculate_similarity applies a Python ">= min_ratio" gate (replacing rapidfuzz score_cutoff). No change to live match decisions.
Packaging built with git archive (core.autocrlf=false: forward-slash paths, LF line endings) and validated with scripts/validate_zip.py (matching_core.py included).