Go-бинарь openLight появился из простой усталости: печатать ssh pi@raspberrypi.local && systemctl status ... с телефона неудобно. Первая версия в марте — один коммит, Raspberry Pi, Telegram-бот с SQLite и локальный Ollama как запасной маршрут, если роутер не понял запрос. Два месяца спустя бинарь весит те же ~25 МБ, конфиг по-прежнему один YAML, но почти всё внутри переписано хотя бы раз.

Самое значимое изменение — архитектура роутинга. Изначальная схема была плоской: slash-команда → regex → Ollama. Проблема обнаружилась быстро: половина задержки уходила на запуск модели, модель иногда выбирала «почти правильный» инструмент, а разница между «не понимаю запрос» и «уверен на 51%, выполняю» оказалась критической. Сейчас перед LLM стоит каскад детерминированных слоёв: slash-команды, aliases, нормализация, rule-based parsing, semantic mapping. Модель подключается только если все они не сработали. Русская фраза «что там с системой» нормализуется до /status без единого вызова LLM.

ВерсияРоутингМониторингНоды
v0.0.1 (март)slash → regex → OllamaТолько реактивный (запрос-ответ)Только локальная машина
v0.1.0 (май)Детерминированный каскад + LLM как fallbackWatch-цикл с алертами и кнопкамиSSH-ноды: локально и удалённо

Второе крупное изменение — мониторинг-цикл. Версия v0.0.1 была полностью реактивной: спросил — получил ответ. В v0.1.0 появились watch-правила с polling'ом, инцидентами, cooldown'ами и Telegram-алертами с кнопками Restart, Logs, Status, Ignore. Ключевое решение: кнопки вызывают тот же skill path, что и ручные команды. Нажатие Restart в алерте — это тот же service_restart, тот же allowlist, тот же audit log. Никакого отдельного «режима автоматизации» нет.

Роутер переработан: LLM подключается только если детерминированные слои (slash, alias, regex, semantic mapping) не справились.

Именно здесь автор расходится с мейнстримом AI-agent tooling. Популярная идея — дать модели shell, sandbox и автономность. Для инфраструктуры это выглядит опасно: нужен не автономный агент, а понятный проверяемый execution path. В openLight LLM — классификатор намерения, не носитель привилегий. Ранняя версия имела mutating_execute_threshold — порог уверенности для мутирующих действий. От него отказались: правильная модель проще — либо skill существует и проходит allowlist-проверки, либо нет.

Поддержка SSH-нод решила проблему разрозненной инфраструктуры. Первая версия работала только с локальной машиной. Когда появились VPS, Mac mini и несколько других коробок, потребовался единый интерфейс. Нода — именованный SSH-target в конфиге. Команда /restart matrix одинаково выглядит для пользователя независимо от того, выполняется ли она через local systemd, docker, docker-compose или их SSH-аналоги на удалённой машине.

Mac mini на M1 изменил восприятие проекта сильнее всего. Машина спокойно тянет Ollama, несколько Docker-сервисов, мониторинг и Telegram-агент при смешном энергопотреблении. Автор выделяет отдельную категорию устройств: маленькие always-on компьютеры — Mac mini, старые ThinkPad, NUC, Raspberry Pi, домашние ARM-машины. Они живут между ноутбуком и облаком, и для них плохо подходит mainstream tooling: Kubernetes избыточен, Datadog тоже, большие AI-agent frameworks — тем более. Этой категории нужен маленький, понятный, дешёвый и repairable слой управления.

Из признанных ошибок — фрейминг «мы не такие, как X» в ранних README. Определять проект через отрицание конкурента плохо по двум причинам: читатель, не знакомый с конкурентом, ничего не получает, а архитектурные решения начинают приниматься «от противного», а не из собственной логики. Ещё одна ловушка — «AI assistant creep»: каждый раз, когда добавлялись vision, browser, voice или OCR, хотелось включить их по умолчанию, потому что демо выглядело эффектно. Через пару недель начинался дебаг памяти, Playwright и лишних зависимостей. Решение — чёткое разделение на core и optional модули: без optional openLight остаётся собой, без core теряет идентичность.