Обратная сторона автоматизации: как скрытые ошибки живут в бизнес-системах
Есть кое-что специфическое в моменте, когда ты разворачиваешь собственную автоматизацию для другого человека и смотришь, как она ломается способами, которыми никогда не ломалась у тебя дома. Твою собственную систему ты знаешь со всеми её странностями. Видел её капризы, привык к некоторым шероховатостям, выработал обходные пути, которые уже не замечаешь. Но когда рядом стоит третий человек — он ждёт результата, а не понимания почему иногда так бывает.
Именно это произошло со мной в мае 2026. За одну неделю я нашёл три категории ошибок в своих собственных системах — не в чужих, а именно в тех, которые я считал рабочими. Бот ушёл в crash-loop на 33 часа. Финансовая формула год давала неправильный результат. Данные оказались в тысячу раз больше нормы из-за путаницы единиц. Ни одна из этих ошибок не сгенерировала алерт. Ни одна не прислала мне уведомление. Все три нашлись вручную — либо я случайно на что-то наткнулся, либо последствия стали слишком видны, чтобы их игнорировать.
Это статья не про «как автоматизировать правильно с первого раза». Это про то, что происходит потом, когда система работает — но работает не так. И почему это гораздо опаснее, чем система, которая упала с очевидной ошибкой.
Первый клиент как зеркало
Когда ты используешь автоматизацию только для себя, у тебя вырабатывается толерантность к её шероховатостям. Ты знаешь историю системы. Ты помнишь, что вот это поле работает странно потому, что три месяца назад поменяли формат данных. Ты знаешь, что этот скрипт иногда зависает на 10 секунд, но это нормально. Ты уже выработал ментальные обходные пути, которые настолько вошли в привычку, что ты их вообще не замечаешь.
Когда ты разворачиваешь систему для кого-то другого — предпринимателя с клиникой в Москве, который заплатил за автоматизацию и хочет видеть результат — всё меняется. У него нет твоей истории системы. Он не знает про странное поле с форматом. У него нет обходных путей. Он просто видит: «сломалось».
Это не значит, что ты плохо строил. Это значит, что внешняя точка зрения убирает привычный шум и показывает реальное состояние. То, что ты принял за «работает нормально», иногда оказывается «работает в обходной системе допущений, которую ты выстраивал месяцами».
В мае 2026 я впервые столкнулся с тем, как мои собственные системы — не экспериментальные, не тестовые, а рабочие, которые я считал надёжными — начали показывать изнанку. Три ошибки разного класса, три урока о том, как автоматизация молчит.
Ошибка первая: незавершённая миграция и 33 часа простоя
Техническое решение казалось разумным: зашифровать базу данных для защиты данных клиента. SQLite без шифрования — стандартный выбор для локального хранения, но для продакшн-данных с реальными людьми нужно что-то надёжнее. Перейти на зашифрованный формат — правильное решение.
План был простым: добавить ключ шифрования в переменные окружения, обновить стартовый код бота, а затем зашифровать существующую базу данных специальным инструментом. Три шага. Казалось бы, ничего сложного.
Что произошло на самом деле: первые два шага были выполнены в одну сессию, третий отложен на несколько часов. Логика была такой: «код готов, потом зашифруем базу». Но между «кодом готов» и «базой зашифрованной» система оказалась в состоянии неопределённости. Новый код ожидал зашифрованную базу. Старая база была незашифрованной. Бот стартовал, пытался прочитать базу с ключом дешифрования, получал ошибку и падал. Рестартовал. Падал снова.
За 33 часа бот перезапустился 47 раз. Снаружи это выглядело нормально: процесс запущен, ошибок в мониторинге нет, статус «активен». Watchdog на количество рестартов не был настроен — такой класс ошибок не был предусмотрен. Алерт не сработал ни разу.
Как я это нашёл: зашёл на сервер проверить что-то не связанное, случайно посмотрел на логи и увидел счётчик рестартов. Не алерт, не уведомление — случайный взгляд в нужное место.
Починил за 20 минут: нашёл незашифрованный файл базы, запустил инструмент шифрования, перезапустил сервис. Но урок стоил 33 часов простоя для клиента. После этого я добавил жёсткое правило в свою конституцию систем: многошаговая деструктивная миграция выполняется только атомарно — либо весь процесс за одну сессию от начала до конца, либо не начинается совсем. «Сделаю половину сейчас, закончу потом» — запрещено для любой операции, которая оставляет систему в промежуточном состоянии. Один шаг назад должен быть возможен из любой точки. Если такого шага нет — шаг не делается.
Помимо этого: smoke-тест до перезапуска зависимых сервисов. Проверить новую конфигурацию standalone, убедиться что она читает данные корректно — только потом перезапускать бота. Двадцать минут проверки экономят тридцать три часа простоя.
Ошибка вторая: год неправильного учёта
Вторая ошибка была старше и дороже. И точно так же никогда не генерировала алерт.
У меня портфель из 16 активных вилл на Бали. У каждой — расходы, доходы, инвесторы. Финансовый дашборд считает P&L по каждой вилле по каждому месяцу. Я строил его несколько месяцев, поэтапно, начиная с реальных данных. Каждый шаг проверял по отдельности. Система работала.
В начале мая я открыл показатели апреля и увидел минус 1.2 миллиарда рупий (примерно 75 тысяч долларов) убытка по портфелю за год. Маржа: минус 171 процент. Расходы превышали выручку почти вдвое. Если бы я отправил это инвестору в отчёте, у него был бы разговор со мной об очень других вещах, чем я рассчитывал.
Первая реакция — «данные неправильные». Но выручка выглядела корректно. Расходы тоже выглядели корректно — по отдельности. Проблема оказалась в том, как записывались долгосрочные контракты.
Когда я платил 90 миллионов рупий вперёд за двухлетнюю аренду виллы у арендодателя, система записывала 90 миллионов в расходы того месяца, когда была произведена оплата. Без амортизации — весь двухлетний контракт ударял по одному месяцу. Это кассовый метод учёта: потратил деньги в январе — в январе и записываем.
Проблема в том, что кассовый метод создаёт огромные осцилляции в P&L: месяц обновления контракта показывает гигантский убыток, следующие 23 месяца показывают нулевые расходы по аренде. Это не отражает экономическую реальность — вилла используется каждый месяц, аренда стоит ежемесячно, просто оплачена вперёд.
Правильный подход — метод начислений: 90 миллионов за 24 месяца это 3.75 миллиона в месяц. Этот расход соответствует реальному потреблению актива. Я написал амортизационную таблицу: каждый долгосрочный контракт разбивается на ежемесячные части согласно сроку действия.
После пересчёта: плюс 190 миллионов рупий прибыли, маржа 26 процентов. Те же исходные данные, другая методология. Система год считала правильно под своими правилами. Просто правила были неправильными.
Это другой класс ошибки, чем crash-loop. Crash-loop — баг: система делает что-то не то. Неправильная методология — это допущение, которое никогда не проверялось критически. Система не предупреждает об устаревших допущениях. Она продолжает считать под ними бесконечно, аккуратно и без ошибок.
Ошибка третья: данные в тысячу раз больше нормы
Третья ошибка была самой простой по механике и самой показательной по тому, как легко такое проходит незамеченным. Путаница единиц измерения.
В финансовой базе данных часть полей хранит суммы в полных рупиях. Другая часть — в тысячах рупий (kIDR, «кило-рупии»), потому что числа большие и лишняя точность не нужна. Это архитектурное решение появилось органически: разные части системы строились в разное время, и где-то хранили IDR, где-то kIDR. Это нормальная эволюция реального кода, не катастрофическая ошибка проектирования.
Поле investor_balances.amount хранит суммы в полных рупиях. В какой-то момент я написал расчёт, который предположил, что оно хранит kIDR — как соседние поля расходов и прибыли. Результат: балансы инвесторов в расчётах оказывались в тысячу раз больше реальных.
Алерт не сработал: ничто не проверяло «согласован ли этот баланс с суммой транзакций?». Баланс был числом. Число было вычислено и записано. Оно было математически корректным — при неправильном предположении об единицах. Неправильной была интерпретация, а не арифметика.
Нашёл я это при разработке нового представления для инвесторов. Сравнил ожидаемый доход одного инвестора с тем, что показывала база. Расхождение в три порядка. Не ошибка округления — ровно в тысячу раз.
Починить это оказалось несложно: исправить расчёт, перепроверить все смежные формулы. Сложнее было убедиться, что такая же ошибка не сидит ещё где-нибудь. Для этого я ввёл реестр единиц: каждое числовое поле в финансовой базе имеет запись в документации — имя поля, таблица, единица (IDR или kIDR), дата последней проверки. Любой новый расчёт, который использует финансовые поля, начинается с проверки реестра, а не с предположения.
Почему автоматизация скрывает ошибки лучше любого сотрудника
Все три ошибки объединяет одно: они были тихими. Не в смысле «негромкими» — в смысле «не производили никаких сигналов о том, что что-то не так».
Когда человек делает ошибку, он обычно оставляет следы. Задаёт вопрос, который не должен задавать. Колеблется перед ответом. Его продукт выглядит немного странно. Он взаимодействует с другими людьми, которые замечают несоответствие. Человеческая ошибка, как правило, имеет социальный след.
Автоматизированные системы производят результат молча. Бот упал 47 раз и ничего не сказал. Финансовая формула год давала неправильные результаты и сообщала их с полной уверенностью. Путаница единиц производила красивые форматированные числа в дашборде, который выглядел абсолютно нормально.
Есть ещё один специфический эффект: автоматизированным системам доверяют больше, чем людям, после того как они некоторое время проработали правильно. Ты строишь систему, тестируешь её, видишь что работает, и перестаёшь проверять. Год работы финансовой формулы — это год накопленного доверия к ней. Сложно предположить, что что-то считается неправильно в системе, которую ты видел работающей тысячи раз.
Это создаёт ловушку: чем дольше неправильная система работает без обнаружения ошибки, тем сильнее кажется, что она работает правильно. Это не логично с точки зрения вероятности, но это очень по-человечески с точки зрения психологии доверия.
В тот же период, когда я разбирался с этими тремя ошибками, я обнаружил ещё несколько примеров той же динамики. 13 ботов писали в рабочий чат балийской команды круглосуточно, включая 3 часа ночи. Только один из них знал о ночном режиме тишины. Остальные 12 никогда не были настроены с учётом часовых поясов — это просто не было предусмотрено при разработке. Никто не жаловался явно, Тригуна просто просыпался от уведомлений. Это не алерт, это накопленный дискомфорт.
Ещё один случай той же недели: виллы, которые я передал другой управляющей компании, продолжали генерировать алерты в трёх разных скриптах — «двойное бронирование», «гость не выехал», «не закрыт чек-аут». Виллы уже не мои, их не нужно алертить. Но три разных скрипта не знали о передаче — у каждого был свой жёстко прописанный список объектов. Один раз обновил поле в базе данных «вилла активная да/нет», и 74 правила алертов умолкли за 10 минут. Они не были сломаны — они просто не знали, что мир изменился. Системы не знают об изменениях в реальности, если ты их явно не сообщаешь.
Что реально находит эти ошибки, по моему опыту — не алерты. Алерты находят ошибки, которые ты предвидел. Вот что находит остальные:
Внешние глаза. Развёртывание для кого-то другого убирает привычный шум. Инвестор, который смотрит на свой баланс первый раз, видит то, что ты перестал видеть.
Очевидный предел. Маржа −171% — это не «немного неправильно», это «нужно разобраться что происходит». Когда результат выходит за пределы правдоподобного диапазона, мозг переключает режим с «доверяю системе» на «проверяю данные».
Случайная инспекция. Зашёл на сервер по другому поводу, увидел счётчик рестартов. Не целенаправленная проверка — случайный взгляд в нужное место в нужный момент.
Сборка нового поверх старого. Когда строишь что-то новое, которое зависит от существующих данных, приходится сравнивать. Сравнение показывает расхождения, которые при использовании данных «в одном направлении» никогда не всплывают.
Ни один из этих механизмов не является автоматическим. Все требуют человеческого внимания в какой-то точке.
Практика: что и когда проверять вручную
На основе этих трёх классов ошибок я выстроил для себя конкретный аудитный цикл. Не «раз в год смотрю всё», а регулярная практика с конкретными вопросами.
Ежемесячно — сквозная проверка результата. Для каждого ключевого конвейера: не «скрипт запустился успешно», а «на другом конце произошло то, что должно было произойти». Для финансового дашборда — открыть итоговый результат и задать вопрос: «выглядит ли это как реальный бизнес?». Для клиентских систем — пройти полный пользовательский путь руками. Не smoke-тест компонентов, а именно полный путь.
После каждого закрытого финансового периода — sanity check. Три вопроса: находится ли маржа в правдоподобном диапазоне для этого бизнеса? Нет ли строки расходов, которая занимает больше 30% от суммы (если есть — либо она нормальная и нужно понять почему, либо это методологическая ошибка)? Сходятся ли цифры в сумме с банковскими выписками за период?
Для баз данных с финансовыми данными — реестр единиц. Каждое числовое поле имеет запись: имя поля, таблица, единица измерения, дата последней проверки. Перед написанием любого расчёта, который использует финансовые данные, — заглянуть в реестр. Не предполагать единицы из контекста имён соседних полей.
Для развёрнутых систем — ручной walkthrough раз в две недели. Не технический smoke-тест — полный сценарий использования от начала до конца, как пользователь. Именно этот формат находит класс ошибок «каждый компонент работает, но их последовательность — нет».
Для любой деструктивной миграции — правило атомарности. Весь процесс в одну сессию или не начинать совсем. Backup с датой до каждого деструктивного шага. Smoke-тест новой конфигурации standalone до перезапуска зависимых сервисов. Ответ на вопрос «какой одной командой откачусь» перед каждым шагом, который изменяет данные.
Раз в месяц — два часа на «вещи которые я давно не смотрел». Выбрать три системы без специальной причины. Залезть в исходные данные, не в дашборд. Посмотреть сырые числа. Задать вопрос: «выглядит ли это как реальность?». Это та самая проверка, которая находит год-старое неверное допущение, потому что ты смотришь на данные не через привычную линзу.
Для систем с watchdog — проверь, что watchdog сам работает. Это звучит абсурдно, но это реальный класс ошибок: watchdog, который должен перезапускать упавшие процессы, сам иногда падает. Или работает, но смотрит не на тот процесс. Или срабатывает с задержкой в 4 часа вместо 5 минут. Раз в месяц — намеренно остановить один процесс и убедиться что watchdog его поднимает. Если нет — ты нашёл ещё одну тихую поломку.
Этот цикл не поймает всё. Но он меняет модель обнаружения ошибок: от «ждать алерта» — который срабатывает только на предвиденные сценарии — к «периодически проверять допущение, что всё работает». Второй подход ловит то, что первый по определению не может поймать.
Важный нюанс: этот аудит не нужно делать подробно по всем системам сразу. Достаточно покрывать каждую систему раз в месяц — по три за неделю, если их 12, или раз в неделю по одной, если их четыре. Главное — регулярность и то, что ты смотришь именно на конечный результат, а не на индикаторы работы. Индикаторы работы все три моих ошибки показывали зелёными.
Что изменилось после этих трёх ошибок
Суммарно эти три ошибки дали мне больше практического понимания об устойчивости систем, чем полгода успешной работы без инцидентов. Потому что успех не учит ничему о том, что может пойти не так. Ошибки — учат именно этому.
Главный сдвиг: я перестал воспринимать «работает без ошибок» как синоним «работает правильно». Эти два утверждения — разные. Первое говорит о технической исправности. Второе говорит о том, что система производит правильный результат в соответствии с реальностью, на которую она должна влиять.
Автоматизация зарабатывает доверие со временем. Это хорошо. Но доверие не должно означать «перестал проверять». Особенно в части методологий, формул и единиц измерения — тех вещей, которые не меняются сами по себе и поэтому кажутся надёжными. Именно они несут самые долгоживущие ошибки.
Когда у тебя 16 вилл, несколько клиентов, автоматические конвейеры в нескольких направлениях — регулярный ручной аудит это не overhead. Это тот минимальный контакт с реальностью, который не даёт расстоянию между системой и тем, что она описывает, вырасти до полутора лет и миллиарда рупий.
Когда вы последний раз смотрели на сырые данные своих автоматизированных систем — не на красивый дашборд, а непосредственно на то, что дашборд читает из базы данных?
Про конкретные паттерны тихих поломок читайте в Аудит автоматизации: кладбище тихо сломанных вещей. О том, как выстроить систему мониторинга, которая ловит то, что алерты не ловят — Мониторинг AI-агентов: как следить за системой которая сама за собой не следит.