Аналитик, который думал
92 subscribers
113 photos
16 links
База для аналитика, который хочет расти в мире ИТ
Все вопросы @innokentyB
Download Telegram
У аналитика есть соблазн считать результат принятым, если его содержание верно. Но у результата есть ещё форма доставки.

На этой неделе у нас вышел пост в LinkedIn. Текст был вычитан и принят, публикация появилась, ссылка сохранилась. Но платформа отобразила форматирование так, что читать стало заметно труднее.

Это не косметический дефект. Если структура помогает отличить условие от вывода, список от пояснения, а абзац от оговорки, то после публикации меняется не только внешний вид. Меняется то, как читатель восстанавливает смысл.

Поэтому для публичного материала полезно разделять три проверки:

1. Содержание соответствует принятой редакции.
2. Платформа сохранила логическую структуру.
3. Результат читается в конечном интерфейсе.

Статус «опубликовано» подтверждает доставку. Приёмка заканчивается после проверки того, что увидел читатель.
Критерий, который не умеет отклонять результат, ничего не проверяет.

Команда заранее описывает позитивный сценарий, превращает его в тест и получает зелёный статус. Кажется, что всё сделано правильно: критерий появился до реализации, агент выполнил работу, тест прошёл.

Но у такого Green есть слабое место. Мы знаем, какой результат проверка принимает. Не знаем, способна ли она отказать хотя бы одному правдоподобному, но неправильному результату.

Поэтому до реализации полезен negative-path gate, проверка отрицательного сценария: назовите один реалистичный исход, который выглядит убедительно, но должен быть отклонён. Затем убедитесь, что критерий действительно его отсекает.

Синтетический пример.

Система должна отменять заказ. Критерий приёмки проверяет три вещи:

— API вернул 200;
— в интерфейсе появился статус «Отменён»;
— создана операция возврата.

Все три условия могут пройти, даже если заказ уже передан в доставку. Получится согласованный набор зелёных сигналов и неправильный бизнес-результат: деньги возвращены, а товар продолжает ехать к клиенту.

Проверка становится содержательной, когда в ней появляется отрицательный сценарий:

если отправление уже передано перевозчику, отмена должна быть отклонена с определённой причиной; статус заказа не меняется; возврат не создаётся; попытка остаётся в журнале.

Теперь критерий умеет не только подтвердить ожидаемое поведение, но и остановить правдоподобную ошибку.

Это не означает, что на каждый сценарий нужно придумать десятки исключений. Достаточно начать с одного исхода, который команда действительно боится пропустить: повторного списания, обхода права доступа, потери ограничения, принятия устаревшего источника, успешного ответа без обещанного артефакта.

В TDPD Red gate нужен не ради красного цвета в отчёте. Он показывает, что проверка способна обнаружить отсутствие нужного поведения до реализации. Green после этого означает инженерное соответствие заданному сценарию, но ещё не финальную пригодность результата.

Последнее решение остаётся на UAT. Человек проверяет, тот ли риск был заложен в критерий, не потерялся ли смысл за формально правильными сигналами и можно ли принять остаточный риск.

Если проверка принимает всё, она не защищает от ошибки. Она только оформляет разрешение двигаться дальше.
У проекта может быть полный набор документов и всё равно не быть ответа, который можно безопасно передать разработке.

В Source Map пробелы выглядят менее впечатляюще, чем готовые строки. Например, документация говорит про exponential backoff, но не задаёт параметры retry policy. Формально материал есть. Практического правила, по которому можно написать проверку, нет.

Самая опасная реакция — позволить агенту заполнить пропуск правдоподобным значением. Так появляется спецификация, которая нигде не была принята. Она выглядит лучше, чем UNKNOWN, но хуже работает в эксплуатации: никто не знает, какое решение пересматривать, когда появится уточнение.

Я разделяю три состояния:

1. Известно. Есть источник, владелец и проверяемое решение.
2. Противоречит. Есть несколько источников, и конфликт вынесен отдельным вопросом.
3. UNKNOWN. Нужного правила нет или его нельзя вывести из доступных материалов.

У каждого состояния должен быть следующий шаг. Для UNKNOWN это не «попросить агента подумать ещё». Это указать, кому задать вопрос, какую часть системы он затрагивает и какая проверка появится после ответа.

Такой формат полезен и при приёмке. Пока вопрос открыт, зелёный технический тест не может считаться доказательством требования. После решения проверка получает основание, владельца и границу применимости.

UNKNOWN не означает, что работа остановлена. Он показывает, где работа ещё не стала решением.
Не начинайте требование со слов «система должна».

Сначала ответьте на три вопроса:
— кто действует;
— в какой ситуации;
— что он пытается изменить.

«Система должна показывать статус заявки» почти ничего не объясняет.

«Оператор перед звонком клиенту проверяет, можно ли продолжить обработку заявки» уже показывает участника, момент и решение, которое ему нужно принять.

Техническое поведение можно описать следующим шагом. Сначала нужен смысл действия.

На этой неделе каждый день будем разбирать по одному простому вопросу, который делает требование проверяемым.
CRM показывает APPROVED. Сервис риска — REVIEW_REQUIRED. Какой статус должен увидеть оператор?

Названия поля недостаточно. В требовании нужно зафиксировать две вещи: какой источник имеет право определять решение и как долго его ответ считается актуальным.

В нашем синтетическом примере решение о продолжении обработки приходит из сервиса риска. CRM хранит состояние процесса, но не переопределяет риск. Поэтому оператор видит REVIEW_REQUIRED, даже если в CRM осталось APPROVED.

Есть и вторая граница — свежесть. Допустим, ответ сервиса риска старше 15 минут. Эти 15 минут — учебное значение, не отраслевой норматив и не реальная политика. Правило примера простое: устаревший ответ нельзя показывать как текущий; сначала нужно запросить новый.

Так одно поле превращается в проверяемое требование:
— назван авторитетный источник;
— задан срок актуальности;
— описано поведение при конфликте;
— описано поведение при устаревании.

Если не записать авторитет и свежесть, система всё равно выберет значение. Только это будет технический порядок чтения данных, а не принятое решение.
Позитивный сценарий обычно помещается в одну строку: оператор запускает проверку, сервис риска отвечает, обработка продолжается.

А что произойдёт, если сервис недоступен?

Плохой ответ — молча показать последнее известное решение. Интерфейс будет выглядеть рабочим, но оператор примет старые данные за текущие.

Проверяемый отрицательный путь выглядит иначе:
— обработка остаётся заблокированной;
— оператор видит, что проверка не завершилась;
— прошлый результат не помечается как актуальный;
— повторная попытка возможна, но не превращается в скрытое разрешение продолжить работу.

Такое описание не требует перечислять все будущие ошибки. Достаточно назвать один реалистичный сбой, видимый результат и действие, которое система точно не должна совершать.

Позитивный путь показывает демонстрацию. Отрицательный — границу доверия к результату.
«Показывать статус заявки» — так требование выглядело в начале.

После уточнений оказалось, что важен не любой статус. Решение о продолжении обработки принимает сервис риска, а CRM только хранит состояние процесса. Старый или недоступный ответ нельзя выдавать за текущий.

Финальная формулировка стала другой:

«Показывать оператору актуальное решение сервиса риска. Если ответ недоступен или устарел, блокировать продолжение обработки и показывать причину».

Полезно сохранить рядом четыре записи:
— было: «показывать статус заявки»;
— вопрос: какой источник определяет решение;
— решение: авторитетен сервис риска;
— стало: показывать его актуальный ответ и явно обрабатывать отсутствие данных.

Так видно не только последнюю фразу, но и причину изменения. Если источник или правило свежести поменяются, команда поймёт, какое решение и какие проверки нужно пересмотреть.

Хорошее требование — не текст, который однажды красиво сформулировали. Это короткий след принятых уточнений.
Что на самом деле доказывает зелёный тест?

Он показывает, что реализация соответствует записанному правилу.

Но если само правило неверно, тест может идеально охранять ошибку.

Независимая приёмка начинается не с повторения постановки. Она начинается с ожидаемого пользовательского сценария и решения команды, принятых до оценки реализации.

Проверьте один свой зелёный тест: откуда взялся ожидаемый результат?
return_url не означает payment.succeeded

Возврат пользователя в интерфейс сообщает только о переходе пользователя.

Он не подтверждает, что платёж успешно завершён.

В синтетическом учебном кейсе заказ можно перевести в paid только после валидированного события payment.succeeded. pending, processing и succeeded остаются разными состояниями.

Какое событие в вашей системе действительно имеет право изменить состояние бизнес-объекта?
Промежуточное состояние нужно проектировать, а не скрывать

processing не является неудобной паузой между запросом и успехом.

У него должны быть собственные переходы, разрешённые действия и понятное отображение для пользователя.

Если система показывает только «не оплачено» и «оплачено», команда всё равно будет принимать решения в промежутке. Просто эти решения останутся неявными.

Какое промежуточное состояние ваша система сейчас маскирует спиннером?
Потерянный webhook остаётся открытым решением

Таймаут не сообщает, произошло событие или нет. Повтор запроса может помочь, а может создать второй внешний эффект.

Пока команда не приняла recovery contract, нельзя молча достраивать политику восстановления за владельца.

Нужно явно решить: кто проверяет состояние, когда допустим повтор, как распознаётся дубль и кому принадлежит остаточный риск.

Где в вашем процессе записаны эти решения?