ЗаметкиКейсыНа главную

Кейс

Как я чуть не построил идеальную систему вместо работающего продукта

Кейс о том, как разумные меры безопасности превратили автоматизацию публикации в бесконечный подготовительный цикл — и как изоляция реального сценария вернула фокус на продукт.

Ситуация

Всё начиналось почти наивно. Я хотел, чтобы система сама находила достойную историю в моей работе, помогала превратить её в хороший текст, показывала мне в Telegram и после короткого «Публикуй» размещала на сайте ровно ту версию, которую я видел.

Звучит как понятный продуктовый сценарий. Есть материал, есть решение владельца, есть публикация. Но чем серьёзнее я относился к слову «ровно», тем быстрее простая цепочка обрастала защитой. Нужно было доказать, что команда пришла от меня. Что она относится к конкретному сообщению. Что одобрен именно этот текст, а не соседняя редакция. Что публикация не затронет production раньше времени. Что при ошибке всё можно вернуть назад.

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

Где я зациклился

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

Потом появился безопасный release-контракт сайта. Он отделил подготовку релиза от переключения активной версии, ввёл проверяемые инварианты и нормальный rollback. Это тоже было нужно.

Дальше я захотел, чтобы обязательные проверки нельзя было обойти. Появились точные approval, digest, evidence, одноразовые пакеты, проверки конфликтов и закрытия зависимостей. Затем — приватный реестр материалов, версии, receipts, tombstone и восстановление. Потом — точное Telegram-одобрение. Потом — publisher, который принимает только неизменяемый receipt и не может незаметно подменить материал.

На бумаге система становилась всё надёжнее. В жизни пользователь всё ещё не мог открыть настоящую страницу и сказать: «Да, вот это я готов публиковать».

Почему каждая следующая защита выглядела разумной

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

Если автоматизация умеет публиковать, ей нельзя доверять расплывчатую команду. Значит, нужен exact approval. Если approval точный, его нужно связать с конкретной версией материала. Если версия связана хэшами, нужны правила single-use и срок действия. Если publisher меняет состояние, нужны атомарность и rollback. Если вокруг есть другие изменения, нужен контроль конфликтов. Если проверка существует только в инструкции, её нужно сделать исполняемой.

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

Это был не провал инженерии. Наоборот, это была инженерия без достаточно жёсткого продуктового ограничителя.

Признак, что система перестала служить продукту

Для меня таким признаком стал простой вопрос: что нового я могу сделать как пользователь после очередной завершённой задачи?

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

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

Ещё один сигнал — язык. В обсуждении стало больше внутренних названий, статусов и пакетов, чем слов «материал», «прочитать», «исправить», «одобрить» и «опубликовать». Когда продукт приходится объяснять через устройство его предохранителей, баланс уже нарушен.

Что сделали

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

Approval и publisher были вынесены в отдельные изолированные песочницы. Там не было живого Telegram, production, сайта, scheduler и внешней сети. Только синтетические данные, строгие контракты и тесты. Это позволило проверить ключевое без риска: неверный пользователь блокируется, чужое сообщение блокируется, подмена одного поля блокируется, истёкший receipt блокируется, повторное использование блокируется, а корректное подтверждение проходит.

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

Главное — эти песочницы не притворялись production. Они честно отвечали только на один вопрос: работает ли логика одобрения и исполнения в контролируемых условиях?

Что изменилось

После этого стало возможным сделать следующий маленький, но настоящий шаг: соединить проверенную логику с реальным Astro-сайтом и разместить один материал только в закрытом preview.

Здесь уже нет второго генератора страниц и демонстрационного HTML. Используется существующая контентная модель сайта, его настоящий layout, реальные маршруты и настоящая build-команда. Материал получает неизменяемую ревизию, content и metadata bindings, а preview approval прямо запрещает production.

Релиз собирается как content-addressed набор файлов. Перед переключением фиксируется предыдущая preview-версия и неизменность production. Затем меняется только preview pointer, выполняются HTTP-проверки, контролируемый rollback и повторная активация. Если любой инвариант расходится, работа останавливается.

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

Ограничения

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

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

Итог

Безопасность и продукт не противостоят друг другу. Ошибка возникает, когда безопасность проектируется без ограниченного сценария, который она должна разблокировать.

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

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

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