Codex review on c905b3a flagged two real issues:
1. Explicit `service: 'sms'` (e.g. `sms:+15551234567`) was still being
routed to iMessage whenever both chats existed, because the iMessage-
first preference was hardcoded. Make the preferred service
parameterized off `target.service`: SMS for explicit `sms` intent,
iMessage otherwise (covers `imessage`, `auto`, and undefined).
2. Codex also flagged on the prior commit that breaking on
`participantIMessageMatch` could skip a higher-priority direct
`iMessage;-;<handle>` match on a later page. Direct > participant in
our preference order, so the early break was unsound. Remove it
entirely \u2014 only a direct preferred-service match can short-circuit
pagination (and that branch already `return`s immediately).
Final return preference is now:
participantPreferredMatch
\u2192 directHandleOtherServiceMatch
\u2192 participantOtherServiceMatch
\u2192 directHandleUnknownServiceMatch
\u2192 participantUnknownServiceMatch
Adds three regression tests:
- explicit `service: 'sms'` prefers SMS direct over iMessage direct
- explicit `service: 'sms'` falls back to iMessage when no SMS exists
- later-page direct iMessage beats earlier participant iMessage