Начнём с вопроса. Он простой, и ответ на него у вас точно есть — вопрос только в том, за сколько времени.
Возьмите операцию, которую ваша система провела вчера сама. Не спорную, не жалобу — обычную, каких тысячи. Какое условие её пропустило? И в какой редакции это условие было именно вчера, а не сегодня?
Прикиньте честно: час, день, неделя, не соберём.
Запомните свой ответ. К концу он, скорее всего, изменится, и не потому, что я буду вас переубеждать.
Фраза, с которой всё начинается
Её произносил каждый, кто отвечает за процесс.
Если что случится — поднимем и разберёмся.
Звучит разумно. За ней стоит уверенность, что прошлое доступно. Надо только знать, где смотреть, и потратить время.
Дальше я эту уверенность разберу. Не для того, чтобы расстроить. В конце будет очень конкретный вывод, что с этим делать.
Ситуация одна на весь разбор. Год назад система приняла решение сама. Сегодня спрашивают, почему именно так. Кто спрашивает — неважно: жалоба, проверка, суд, свой же начальник.
Ступень первая. Смотрим в отчёт
С чего вы начнёте? Скорее всего, откроете отчёт или карточку операции.
И вот первая ловушка, самая незаметная из всех.
Отчёт строится по тому, что записано. Если процесс упал до того, как что-то записал, в отчёте его нет вообще. Не «нет данных», не «статус неизвестен» — его просто нет, как будто не было.
Отсюда следствие, из-за которого существует целый класс неприятностей. В отчёте «не завершилось» и «не начиналось» выглядят одинаково: никак. Отличить одно от другого невозможно, потому что оба отсутствуют.
Проверить это просто. У вас наверняка есть отчёт, сколько процессов запущено и сколько завершено. А есть ли отчёт, какие не завершились? Это не то же самое, что разность двух чисел. Разность скажет количество, но не скажет, какие именно.
Вот почему про сбой обычно узнают от клиента. Не потому, что плохо смотрели. Потому что смотреть было не на что.
Ступень вторая. Поднимаем логи
Хорошо, скажете вы, у нас всё логируется. Подробно.
Скорее всего, правда. Журналы сейчас есть везде, и они и правда подробные.
Только журнал по своей природе фиксирует действия. Шаг, время, результат, код возврата. Это ответ на вопрос «что произошло».
А спрашивают «на основании чего». Это другая запись, и подробность тут не помогает. Можно иметь терабайт логов и не иметь ответа. Сколько ни увеличивай детальность записи о действии, она не превратится в запись о причине.
И вот что здесь неприятнее всего. Основание нельзя дописать потом. Действие восстанавливается по следам — оно оставило изменения в данных, вызовы к соседям, отметки времени. Основание существует только в момент принятия решения. Если его тогда не записали, его больше нет нигде.
Ступень третья. Записываем правило
Логично. Будем записывать основание — какое правило сработало. Многие так и делают, и это уже сильно лучше среднего.
Записали. Правило RULE-114.
Год спустя открываем RULE-114 и читаем.
И читаем сегодняшний текст. Потому что записан был идентификатор, а идентификатор указывает на правило, а не на его тогдашнее содержание. Правило за год переписали — может быть, десять раз. Номер тот же.
Здесь эта ступень хуже предыдущей, и вот чем.
Когда не записано ничего, вы это знаете и осторожничаете. Когда записан идентификатор, вы уверены, что основание у вас есть. Открываете, читаете уверенно и строите на этом позицию.
Неполная запись опаснее её отсутствия. Она даёт ложную уверенность, а ложная уверенность стоит дороже незнания.
Ступень четвёртая. Храним редакции
Хорошо. Версионируем правила. Записываем не номер, а номер и версию. Это встречается редко, но встречается.
Достали мартовскую редакцию. Прогоняем случай.
Каким входом?
Здесь стоит остановиться, потому что вся ступень в этом вопросе.
Прогон берёт данные. Данные — сегодняшние. Клиент с марта изменился: другой статус, другие лимиты, другая история операций, другие связи. Прогон правильных мартовских правил по сегодняшним данным даёт результат, который не был получен ни в марте, ни сегодня. Он вообще ниоткуда.
И выглядит совершенно нормально. Правила исторические — вы это проверили и в это верите. Про данные вы не подумали, потому что данные ощущаются как часть случая, а не как переменная.
Дальше две дороги, и обе плохие.
Первая. По полученному ответу выходит, что решение было неверным. Вы признаёте нарушение, которого не было: тогда всё отработало как положено.
Вторая. Вы чувствуете, что не сходится, но доказать нечем. Отвечаете обтекаемо. Тот, кто спрашивал, читает это как уход от ответа — и читает правильно, вы действительно ушли, просто не по своей воле.
Ступень пятая. Снимок данных
Последняя попытка, и она честная. Сохраняем снимок данных на момент решения. Правила по версиям, данные снимком. Теперь-то воспроизведём?
Смотрим, из чего ещё состоял вход.
Справочники и реестры. Они обновляются, они не ваши, и запросить их «по состоянию на март» нельзя — там нет такой кнопки, потому что владельцу она не нужна.
Ответы контрагентов и внешних сервисов. Это разовые события. Повторный запрос сегодня — новый ответ, а не тот же самый.
И собственная система. Код переписан, настройки другие, версии библиотек обновлены. Даже с теми же входами она сегодня работает не так, как работала тогда.
Вот вывод, к которому мы шли.
Воспроизведение как метод не работает. Не потому, что вы плохо подготовились или мало вложили. Потому что часть входа вам не принадлежит и никогда не принадлежала.
Значит, фраза «если что — поднимем и разберёмся» неверна целиком. Разобраться потом нельзя. Можно только прочитать то, что записали тогда.
Пять ступеней одной таблицей.
| Что делаем | Чего не хватает |
|---|---|
| Смотрим отчёт | Упавшее до записи в нём отсутствует. «Не завершилось» и «не начиналось» выглядят одинаково |
| Поднимаем логи | Журнал отвечает, что произошло. Основание — другая запись, и дописать её потом нельзя |
| Пишем, какое правило сработало | Записан идентификатор. Через год он приведёт к сегодняшнему тексту |
| Храним редакции правил | Прогон берёт сегодняшние данные. Верные правила по неверным данным дают ответ ниоткуда |
| Сохраняем снимок данных | Справочники, ответы контрагентов и сама система вам не принадлежат |
Это переворачивает задачу. Она перестаёт быть задачей про расследование и становится задачей про то, что положить в запись в момент решения. Расследование — работа с тем, что осталось. А что останется, решается один раз и заранее.
Кстати, это и ответ на вопрос из начала. Вы прикидывали, за сколько соберёте. Правильный ответ: за столько, сколько решили полтора года назад, когда систему настраивали. Сегодня на это уже нельзя повлиять никак.
Что должно остаться
Пять записей, и все пять делаются во время работы, а не потом.
| Что записать | Почему именно так |
|---|---|
| Какое условие сработало | Не итог, а правило, по которому он получен. В большинстве систем записан именно итог, а причина восстанавливается по памяти того, кто настраивал |
| В какой редакции оно было в тот момент | Не ссылка на правило, а его содержание на ту дату. Ссылка через год приведёт к текущему тексту, и подмену не заметить |
| На каких данных | Снимок значений на момент решения, а не ссылка на карточку. Карточка живая, и сегодня в ней другое |
| Какие условия ещё проверялись и почему не сработали | Отрицательный результат должен быть виден так же, как положительный. Иначе «проверили и не сработало» и «не проверяли» выглядят одинаково |
| Кто или что решило и когда | Автоматика — с версией конфигурации. Человек — с названием роли |
Так выглядит четвёртый пункт, когда он есть. Сработавшее условие сверху, под ним десять проверенных и отклонённых, у каждого зачёркнуто своё условие и значение, по которому оно не прошло.

Пример на кадре намеренно игрушечный. Нарисуй я здесь ваш процесс, вы за минуту нашли бы в нём десять неточностей: предметную область знаете вы, а не я.
Отдельно про модели
Про ИИ в исполняющемся процессе спрашивают все, поэтому скажу коротко.
Новых проблем он не создаёт. Он обостряет уже описанные.
У обычного правила ответ выведен из условия — есть строка, на которую можно показать пальцем. У модели ответ не выведен, он порождён. Строки нет. Вы возвращаетесь на вторую ступень, где журнал говорит, что произошло, но не говорит, на основании чего — только теперь основания нет не потому, что его забыли записать, а потому что его не существует в читаемом виде.
Задайте один и тот же вопрос одной и той же модели дважды — ответы будут разные. Это её свойство, а не сбой. Обновили версию, сменили поставщика, поправили инструкцию — прежнего ответа больше нет нигде.
И третье, самое практичное. Модель, поставленную на шаг, который считают некритичным, обычно ставят туда со спокойной душой. Она разобрала обращение и определила его тип. Тип определил маршрут. Маршрут определил срок и исполнителя. Срок нарушен.
Модель не приняла ни одного критичного решения. Ни одного. А исход критичный.
Некритичный шаг, стоящий перед критичным, делает критичным весь путь.
Отсюда единственная рабочая граница.
Список допустимого считают правила, а не модель. Модель предлагает, правило разрешает, система исполняет. Предсказуемой становится не модель, а граница её полномочий.
Как это выглядит в записи. Сверху — что ушло решателю: перечень разрешённых шагов, посчитанный правилами до обращения к нему, и контекст. Снизу — что он предложил и с каким обоснованием. Две разные записи, и предложение не равно исполнению.

Что можно сделать завтра
Пять вопросов своим. Ни на один не нужно ничего покупать и ничего внедрять — это проверка, а не проект.
- Есть ли отчёт, какие процессы не завершились? Не «сколько запущено», а какие именно не дошли.
- Что происходит при повторе запроса: выполнится второй раз или будет распознан как повтор? И сколько живёт ключ, по которому распознаётся?
- Написано ли где-нибудь, что делать, если процесс упал на середине, а компенсация тоже упала?
- Записана ли редакция условия текстом или ссылкой?
- Сохраняется ли дословный ответ внешнего источника — или только то, что вы из него достали?
Отвечать на них будут неохотно, и это само по себе ответ.
С четвёртым и пятым осторожнее. На них почти всегда отвечают «да, конечно». Попросите показать. Не потому что вам врут, а потому что отвечающий имеет в виду «у нас это есть», а вопрос был про то, как именно.
Чего я не знаю
Вашей предметной области. Всё, что выше, — про устройство систем, которые исполняют процесс без постоянного присмотра, и я говорю только с этой стороны.
Если ваш процесс устроен так, что описанное к нему не относится, значит не относится. Проверка из предыдущего раздела делается без меня и честнее любой презентации.
А вот если на четыре вопроса из пяти ответ «зависит от конкретного человека» — тот самый расход у вас есть, просто он не выглядит расходом. Он выглядит как занятые люди.
Мы делаем Вердикт — он про то, чтобы у процесса, который идёт по правилам и без присмотра, была память и тормоза. Описание процесса проверяется до выпуска, а каждое решение оставляет запись, из которой видно, что выбрали, что отклонили и по какому правилу.
Если вспомните последний раз, когда пришлось объяснять уже принятое решение или искать обязательство, которое не выполнилось, — напишите, сколько человек в этом участвовало и сколько это заняло. Если история регулярная, поговорим предметно.