Назад в блог

Если запускается без тебя — это продакшн

Первое, что я написал в новой системе автоматизации — не задачу. Я написал файл STOP и папку Inbox/.

Не потому что привык всё делать красиво. А потому что месяцем раньше у меня был «персональный скрипт», который ломался в 3 ночи, и я узнавал об этом только утром — из молчания там, где должна была быть активность. Ни логов, ни алерта, ни понимания, что именно пошло не так. Три часа отладки вместо завтрака.

Разница между «скриптом для себя» и «продакшн-системой» — не в аудитории и не в деньгах. Она в одном вопросе: ты будешь рядом, когда это сломается?

Два режима автоматизации

Есть автоматизации, которые ты запускаешь руками. Нажал, получил результат, закрыл. Это инструмент с обслуживанием.

И есть то, что запускает launchd, systemd или Task Scheduler. Без тебя. По расписанию. В 6 утра, пока ты спишь.

Вот это — продакшн. Независимо от того, платит за него кто-то или нет.

Я долго проводил эту границу иначе: «клиентские системы строим как надо, личные — лишь бы работало». Логика была понятная: клиент платит → несёшь ответственность → делаешь правильно. Для себя — не платит → сойдёт.

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

Что случилось

В моей системе автоматизации сейчас 13 cron-задач. Когда я строил её, уже имел опыт: Claude Code + Obsidian тоже работают по launchd, тоже без моего участия. Там первые месяца три я жил по принципу «посмотрю утром, если что». Несколько раз «что» накапливалось до состояния, когда разбираться было уже неприятно.

Самый показательный случай — задача для тихих обновлений в vault. Вместо этого она несколько дней генерировала одно и то же, перезаписывая результат. Почему? Один параметр в конфиге оказался пустым, и скрипт молча принял дефолт вместо остановки с ошибкой.

Лог: не было. Алерт: не было. Стоп-кнопка: не было. Итог: несколько дней впустую и три часа отладки.

После этого я применил к своим инструментам тот же стандарт, что применяю к клиентским системам.

Три механизма, которые я добавляю теперь

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

Первый — файловый lock. В SSI-системе автоматизации каждая задача сначала делает mkdir cron/.lock. mkdir атомарен: если папка уже есть, команда падает с ошибкой, задача не запускается. Никакого PID-файла, никакого race condition. Если предыдущий запуск завис и не почистил за собой — lock виден сразу.

Второй — файл STOP. Один файл в корне системы. Если он существует, ни одна задача не запускается. Не «надо отключить launchd, найти все конфиги, закомментировать» — просто touch cron/STOP. Через минуту всё стоит. В клиентских проектах это называется maintenance mode. Для личных инструментов почему-то считается лишним.

Третий — JSONL-лог. Каждая задача пишет строку: timestamp, task, status (ok / degraded / error), длительность, что сделано. Я не читаю их каждое утро. Но когда что-то молчит — открываю и вижу картину за последние N запусков. 20 строк кода. При каждом инциденте экономит по 2–3 часа.

Сверху — Telegram-алерт при статусе error. Не «слать всё подряд» — только аномалии. Остальное логируется молча.

Workflow technical debt

У личных инструментов есть один неочевидный риск: они накапливают долг быстрее клиентских систем. Нет code review, нет задачи в трекере, нет разговора с клиентом, который заставляет притормозить перед тем, как сделать.

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

У меня теперь одно правило: если это работает без меня — я пишу это как production-код. Комментарий там, где логика не очевидна. Явный exit с кодом 1 при ошибке вместо молчаливого дефолта. Не потому что кто-то проверит. А потому что через полгода буду разбираться в этом как будто первый раз.

Где намеренно оставляю approval gate

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

Публикация статьи на сайт — именно такая. Система готовит черновик, проходит все шаги обработки, пишет результат в папку Queue/ — и ждёт. Я смотрю, ставлю подпись, нажимаю run. Автоматизирована скучная часть. Контроль над важной — у меня.

Подробнее об этом — в отдельной статье о том, где и почему я держу approval gates.

Что не работает

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

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

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

Итог

Стандарт у меня теперь один. «Клиентский» или «личный» — больше не разделяю. Работает без тебя? Делай как надо.

На старте это занимает немного больше времени. При каждом сбое — сильно меньше.

Свои системы мне не менее важны, чем клиентские. Может, даже важнее: если они падают, падает моя работа — не чья-то чужая.