First of all, I like the change that sorts MB candidates above non-MB ones. Thanks for that -- this prioritization definitely seems like something we want to do in general.
Thinking about how to do this kind of thing more generally got me thinking about how the matching logic was originally designed and how we can keep it simple. Specifically, the matching logic gets a lot of simplicity out of segregating the core matching/ranking stuff from the distance components. Because all the comparison stuff is complicated and messy, it's really helpful to have it hidden behind a single abstraction: distance. This also lets us add on new distance components easily without affecting the core logic.
Every time we add new special cases to the ranking and recommendation logic, we break a little bit of this abstraction. That's fine, especially when it brings features that aren't possible otherwise (like the max_rec
feature), but for th