ec013b76db
botConnectionRoute() stays the strict, throwing dispatch path for real routing (requestForBot, session creation). botRosterMeta() is passive display code and previously reached that throw through a bare catch, which would have swallowed any unrelated failure the same way. It now calls a new non-throwing resolveBotConnectionRoute() and branches on a typed resolved | owner_removed | not_scoped status instead. Adds witnesses for the split: the typed statuses themselves, that strict dispatch still fails closed on an orphaned row, and that an unrelated failure while resolving meta for a live route still propagates instead of being swallowed.