sing-box resolves a selector from cache.db before selector.default and
ignores the profile on a hit, and libbox always enables that cache on
Android. The cache is shared and keyed by group tag, so the stuck entry
survived both an offline server choice and a profile switch: choosing any
server changed only the JSON while traffic kept using the cached outbound,
and a dead cached server made every server in the list fail with VPN-200.
Right after the core starts, before the DNS and HTTPS health check, each
selector group is now pinned to the stored server: default, or the first
member when the profile has none, which is what the core would pick with
no cache. The call is idempotent, so a matching selection neither rewrites
the cache nor interrupts connections.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>