Внешний ответ начинается с байтов, когда у приложения ещё нет оснований считать его конкретным вариантом. В гипотетическом клиенте сначала выполняются декодирование текста и разбор JSON, у каждого со своими путями отказа. Затем разобранное значение должно поступить на проверку как unknown.
Допустим, поддерживаемый ответ содержит метку ready с массивом строк items либо метку failed со строкой message. Проверка времени выполнения должна установить, что значение является объектом, его метка известна, а соответствующие данные имеют требуемую форму. Объект с ready, но без items, неполон. Метка waiting выходит за пределы этого контракта. Утверждение типа с именем желаемого объединения не делает ни один из этих объектов допустимым.
После успешной проверки декодер может вернуть размеченное объединение. Тогда ветвь с проверкой ready сузит тип, и приложение сможет использовать элементы. Проверка полноты через never помогает обнаружить необработанный вариант в объявленной модели. Это полезная информация для сопровождения, но байты ответа она не проверяет.
Клиенту также нужна политика для отвергнутого ввода. Можно сообщить об ошибке декодирования или намеренно представить неизвестный ответ отдельным вариантом. Незаметное приведение к принятому объединению пропускает этот выбор. Я бы держал фактическую проверку рядом с созданием типизированного значения, а вычисления каждого обработчика рассматривал отдельно. Наличие ветви ещё не устанавливает правильность её результата.