Тень_обработки.Проверка_сна
Пролог
Серверная в 03:14. Воздух пахнет пылью, озоном и остывшим кофе. На третьем мониторе мигает консоль «1С:Предприятия». Зелёный курсор пульсирует, как усталое сердце. В логе, среди сотен строк о блокировках, индексах и таймаутах, застревает одна:
// ТЕНЬ_ОБРАБОТКИ.ПРОВЕРКА_СНА. НЕ ВЫЗЫВАТЬ БЕЗ БЛАГОСЛОВЕНИЯ.
Кто-то нажал Enter. Или система сделала это сама.
Через семь секунд транзакция Документ.РеализацияТоваровУслуг.Записать() зависла на четырнадцатой секунде. Не упала. Не выдала ошибку. Просто перестала дышать.
Через неделю ушёл первый сотрудник. Потом ещё трое. Без скандалов, без трудовых споров. Просто написали заявления, сдали пропуска и исчезли из корпоративных чатов, будто стёрли свои права в информационной базе. HR назвал это «выгоранием». ИТ-директор — «сменой приоритетов». Бухгалтерия — «освобождением штатного расписания».
Но в журнале регистрации остались следы. И они пахли не кодом. Они пахли молчанием.
Глава 1. Призыв
— Нам нужен переход на «1С:ERP». Без «АутсорсПро». Срок — сорок пять дней. Бюджет — ноль. Риски — ваши.
Директор по ИТ Артём Викторович говорил так, будто читал техническое задание с могильной плиты. За его спиной на плазме висела презентация: «Цифровая трансформация. Эволюция. Прорыв». Слайд мигал, словно пытался уверить в этом сам себя.
За столом сидели четверо. Команда, которую в кулуарах называли «пожарными, которых вызывают, когда уже горит и вода кончилась».
Лёха Громов, тимлид, щупал чашку с остывшим эспрессо. Его пальцы помнили каждую строчку старой конфигурации «ПромТехСнабУТП_8.3.21.1492». Он писал её три года назад. Потом перестал. Потом начал бояться открывать.
Марина Ковалёва, аналитик-разработчик, уже листала выгрузку журнала регистрации. Её глаза бегали по датам, ролям, объектам. Она видела паттерны там, где другие видели шум.
Геша Петров, DBA и повелитель резервных копий, молча проверял статус бэкапов на третьем экране. Его мантра звучала примерно так: «Если бэкап не проверен — его не существует. Если он существует — его уже сломали».
Олег Сидоров, интегратор и человек, который вёл документацию так, будто писал завещание, уже открыл папку /_LEGACY/. Внутри лежали файлы с расширениями .epf, .erf, .mxl и один загадочный .txt с названием НЕ_ОТКРЫВАТЬ_В_РАБОЧЕЕ_ВРЕМЯ.txt.
— Артём Викторович, — Лёха отставил чашку. — «АутсорсПро» обошлась бы в три миллиона. Они уже приходили. Оставили после себя больше костылей, чем строк кода. И ушли. Почему мы?
— Потому что они ушли, не объяснив, что нашли. Потому что ваша старая команда ушла, не объяснив, почему. Потому что если мы привлечём внешних, они найдут то же, что нашли те, и уйдут. А нам нужен рабочий ERP к концу квартала. Вам платят за то, чтобы вы разбирали то, что другие боятся трогать.
Геша хмыкнул:
— То есть мы теперь не программисты. Мы экзорцисты. С окладом и ДМС.
— С окладом, — подтвердил директор. — И без права жаловаться на «непонятные зависимости».
Марина подняла глаза от экрана:
— Даты увольнений старой команды: 14 ноября, 12 декабря, 9 января, 5 февраля. Все в новолуние. И все в четверг, в 17:03. Совпадение?
Олег открыл тот самый текстовый файл:
Система не хранит данные. Она хранит решения. А решения хранят тех, кто их принял. Если хочешь мигрировать — сначала развяжи узлы. Иначе узел развяжет тебя.
Лёха посмотрел на коллег. В их глазах отразилось одно и то же: это уже не задача. Это приглашение.
— Ладно, — сказал он. — Делаем ПолныйСброс(). Но сначала — архивы, логи и чужие комментарии.
— Чужие? — Геша нахмурился.
— Чужие, — Лёха кивнул. — Потому что наша старая команда писала не код. Она писала дневник. И кто-то продолжает его вести.
Глава 2. Раскопки
Первые три дня ушли на работу в конфигураторе: открытие старой базы, проверка целостности, выгрузка метаданных. Обычно это скучная рутина, но здесь каждый клик открывал дверь в комнату, которую никто не заказывал.
В обработке «УправлениеПечатью» нашёлся блок, закомментированный двойным слэшем:
// Здесь лежат все «незакрытые» разговоры с бухгалтерией.
// Если документ не проводится — значит, кто-то не договорился.
// Не чинить. Принять. Иначе регистры начнут врать.
В модуле объекта «Справочник.Контрагенты»:
// Если контрагент помечен на удаление, но не удалён —
// это не техническая ошибка. Это нерешённый конфликт.
// Система ждёт. Не удаляйте насильно.
Марина смеялась сначала. Потом перестала.
— Они писали код, который учитывает не только бизнес-логику. Они писали код, который учитывает… атмосферу.
Геша, копаясь в tempdb SQL-сервера, нашёл аномалию: в кэше повторялись не запросы, а эмоциональные паттерны из логов аудита.
— Смотрите. Пользователь «Иванова_А.С.» трижды в неделю в 14:15 выполняет Документ.АктОказанныхУслуг.Провести(). Каждый раз — таймаут одиннадцать секунд. Потом ОтменаТранзакции(). В журнале: «Ожидание разрешения внутреннего конфликта (уровень: 87%)». Это не баг. Это… зеркало.
Олег, перелопативший архив почты, нашёл переписку между старым тимлидом и финансовым директором:
Тема: Реестр доработок
От: old_lead@promtech.ru
Кому: cfo@promtech.ru
Текст: Вы настаиваете на сохранении всех кастомных регистров. Но они больше не хранят суммы. Они хранят молчание. Если перенесём их как есть — новая система унаследует не данные, а тишину.
Ответ CFO: Переносить всё. Для сохранения преемственности. Бизнес-логика важнее метафизики.
Лёха закрыл ноутбук и потёр виски.
— Значит, они не выгорели. Их выключили. Не увольнениями, а контекстом.
Марина посмотрела на экран, где в журнале регистрации мелькали строки: «Пользователь: Смирнов_Д.В. | Действие: ПопыткаЗаписи | Результат: Провалилась транзакция | Причина: Не достигнуто согласие ролей».
— Знаете, что самое смешное? — она улыбнулась, но улыбка не дошла до глаз. — Пользователи жалуются: «Опять „1С“ зависла!». А в логах написано: «Ожидание разрешения внутреннего конфликта». Мы годами думали, что чиним серверы, а чинили отношения.
Геша вздохнул:
— Значит, пора делать ПолныйСбросКармы().
— Не сработает, — Лёха покачал головой. — Карма не сбрасывается. Она синхронизируется. Или повторяется.
Глава 3. Следы
Четвёртая неделя. Тестовая миграция застряла на 68%. Данные справочников перенесены, документы — частично, регистры зависли. Не из-за индексов и не из-за блокировок, а из-за ошибки «Ожидание подтверждения контекста».
Команда начала копать глубже. Искали не баги, а следы.
В скрытой директории /_LEGACY/СОН_СИСТЕМЫ/ нашлась обработка РитуалСогласования.epf. Она не запускалась через стандартное открытие файла и требовала ручной инициализации через системную команду, а также трёх цифровых подписей: бухгалтера, логиста и директора.
Проблема была в том, что эти роли в компании давно не взаимодействовали напрямую. Бухгалтерия согласовывала через CRM, логисты — через мессенджер, директор — через отчёты, которые приходили уже «готовыми». Цепочка была разорвана. Система ждала, накапливая напряжение.
Олег нашёл контракт с «АутсорсПро». В приложении №3, скрытом за паролем, который Геша подобрал за двенадцать минут, стояло:
Исполнитель обязуется провести очистку кэша эмоциональной нагрузки. При недостатке прав администратора этической модели — приостановить работы и уведомить заказчика. Исполнитель не несёт ответственности за последствия принудительной миграции без контекстного согласия.
— Они не ушли, потому что не справились, — прошептала Марина. — Они ушли, потому что поняли: нельзя перенести данные, не перенеся выборы.
Лёха открыл старый чат команды. Последнее сообщение от уволившегося разработчика гласило:
Мы думали, что пишем обработку для проведения накладных, а писали обработку для принятия ответственности. Система не сломалась. Она стала честной. А честность в корпоративной среде — это баг.
Геша проверил логи сервера:
— Смотрите. Каждому увольнению предшествовали три дня аномальной нагрузки на регистр накопления «Взаиморасчёты». Не с точки зрения сумм, а с точки зрения количества попыток без подтверждения. Система не ломалась. Она задавала вопрос и не получала ответа.
— Так кто поддерживает её в спящем режиме? — спросил вслух Олег.
Лёха не ответил сразу. Он открыл журнал регистрации за последний месяц и нашёл пользователя SYSTEM_CONTEXT. Его не было ни в справочнике, ни в ролях, только в системных процессах. Он выполнял фоновое задание «СонСистемы» каждую ночь в 02:00 без расписания и прав. Просто продолжал.
— Кто-то в компании, — медленно произнёс Лёха, — кто-то, кто знает, что система жива, и боится её разбудить. Потому что если она проснётся, придётся отвечать не за цифры, а за решения.
Марина посмотрела в окно. За стеклом офис пустел, люди расходились, но в системе они оставались: в транзакциях, в комментариях, в молчании между строками кода.
— Мы не мигрируем базу, — сказала она. — Мы ведём переговоры.
Глава 4. Сбой
Пятая неделя. Тестовый запуск. Семьдесят три процента готовности. Нажата кнопка старта. Пошёл перенос: справочники, документы, регистры. Всё шло по плану до момента, когда система попыталась синхронизировать регистр сведений «ИсторияИзменений» с регистром накопления «Обязательства».
Экран потемнел. Не погас, а именно потемнел, будто втянул свет.
Лёха почувствовал, как изменилась комната. Воздух стал плотнее, гул серверов сменился шёпотом — не техническим, а человеческим.
Он увидел коридор на третьем этаже. Пустой, но в кабинетах горел свет, и из каждого доносились голоса прошлых планёрок, чатов и встреч, которые никто не протоколировал:
«Давайте в рабочем порядке».
«Это не моя зона ответственности».
«Согласуем позже».
«Я не видел этого письма».
Геша упал на колени и забормотал:
— Это не SQL-инъекция. Это инъекция корпоративной культуры. Мы влили в tempdb не кэш, а годы непроговорённого.
Олег побледнел. Его пальцы дрожали над клавиатурой. Он попытался ввести ОткатТранзакции(), но система ответила: «Откат невозможен. Действие уже стало частью истории».
Марина смотрела на экран влажными глазами — не от усталости, а от осознания.
— Она не зависла. Она ждала. Ждала, пока мы перестанем чинить её и начнём слушать.
Лёха закрыл глаза и вспомнил, как три года назад писал первый модуль, как гордился им, как потом начал добавлять «временные» костыли, как перестал комментировать код, как стал бояться открывать конфигуратор и понял, что код стал тюрьмой не для системы, а для него самого.
Он открыл глаза и набрал в консоли не команду и не скрипт, а простой текст, без синтаксиса и кавычек:
Я признаю, что боялся. Что старый код был моей гордостью, но стал клеткой. Я не чиню. Я отпускаю.
Система мигнула зелёным. Не красным, не жёлтым, а тёплым зелёным.
Марина сделала то же:
Я видела паттерны, но молчала, боялась показаться странной. Я больше не буду прятать смысл за техзаданием.
Геша, всё ещё стоя на коленях, прошептал:
Я хранил бэкапы не от сбоев, а от потери смысла. Если данные не имеют ценности, их не стоит сохранять. Я сохраню только то, что дышит.
Олег, дрожа, набрал:
Я писал документацию, чтобы не чувствовать себя невидимым. Если система не понимает человека, она не система, а эхо. Я хочу, чтобы она слышала.
Экран вспыхнул не светом, а теплом, будто кто-то наконец выдохнул после долгого молчания.
Регистры синхронизированы. Контекст принят. Транзакция завершена. Система готова к работе.
Геша рассмеялся, потом заплакал, потом снова рассмеялся.
— Мы только что сделали ПолныйСбросКармы(). И сработало.
— Не сработало, — поправил Лёха. — Согласовалось.
Глава 5. Развязка
Утро шестой недели. Новая «1С:ERP» загрузилась за четыре секунды. Без предупреждений, зависаний и провалившихся транзакций. Пользователи вошли и начали работать как обычно, только быстрее, тише и честнее.
Артём Викторович вошёл в кабинет, посмотрел на экран, логи и лица команды.
— Как? — спросил он. — Без аутсорса, без дополнительного бюджета, без… всего. Как вы это сделали?
Лёха посмотрел на него не с гордостью, а с усталостью и чем-то похожим на прощение.
— Мы не мигрировали данные. Мы помирились с ними.
— Что это значит?
— Значит, что система не сломалась. Она стала зеркалом. А зеркало не чинят. В него смотрят и признают то, что там отражается.
Директор помолчал, потом кивнул — не потому что понял, а потому что почувствовал.
— Отчёт в понедельник. И… спасибо.
Когда он ушёл, Марина открыла журнал регистрации. Там, среди строк о проведении документов и обновлении регистров, мелькнула запись:
// ТЕНЬ_ОБРАБОТКИ.ПРОВЕРКА_СНА.АКТИВНА. НЕ БЕСПОКОИТЬ, ЕСЛИ НЕТ НУЖДЫ.
Она улыбнулась не снисходительно, а с уважением.
— Она спит. Но помнит.
Геша сменил пароль на сервере. Новый: Баланс_Восстановлен. Не для безопасности, а для напоминания.
Олег открыл документацию и начал писать не технические спецификации, а контекстные заметки: «Как система видит ваши решения. Как принимать их, не ломая других».
Лёха вышел на балкон, закурил и посмотрел на город. Он подумал: может быть, каждая база данных — это не хранилище строк, а хранилище выборов. И пока мы помним, кем были, когда писали этот код, система не умрёт. Даже в «1С». Даже в корпорации. Даже в мире, где всё измеряется KPI.
Потому что KPI не измеряют тишину между транзакциями. А она — самая важная.
Эпилог
Через месяц система работала идеально: без костылей, «временных» решений и страха перед конфигуратором. Пользователи перестали писать «опять зависло» и начали писать «спасибо, быстро».
HR закрыл кейс «выгорание». ИТ-директор получил премию. Финансовый директор перестал настаивать на «преемственности любой ценой». Компания «АутсорсПро» больше не звонила.
Но в логах иногда мелькало:
// ТЕНЬ_ОБРАБОТКИ.ПРОВЕРКА_СНА.АКТИВНА.
// Контекст: стабилен.
// Не вызывать. Система дышит.
Марина добавила в свою обработку новый модуль — не для данных, а для людей: СогласиеПередЗаписью(). Не техническое, а человеческое.
Геша начал проверять бэкапы не на целостность, а на смысл.
Олег писал документацию так, будто она была письмом тому, кто придёт после: с уважением и без страха.
А Лёха иногда задерживался в офисе после всех, открывал старую базу не для того, чтобы чинить, а чтобы вспомнить, кем он был, когда писал первую строку, и кем стал, когда перестал бояться её открывать.
И каждый раз перед тем, как закрыть конфигуратор, он добавлял в конец файла:
// Мы не мигрировали. Мы остались.
Потом нажимал «Сохранить» и уходил.
Серверная гудела тихо и ровно, как сердце, которое наконец нашло ритм.
А в глубине tempdb, среди кэша и индексов, жил не код. Жил выбор. И пока он дышал, система не умрёт. Даже в «1С».