ADR-001: Desired state вместо команд
Status: Accepted · Date: 2026-07-03
Контекст
Section titled “Контекст”Backend должен управлять конфигурацией Xray на множестве нод: инбаунды, клиенты, аутбаунды, маршрутизация, сертификаты. Ноды бывают офлайн, команды теряются, применения падают на середине.
Решение
Section titled “Решение”Backend рендерит полное желаемое состояние ноды (NodeConfig, монотонная ревизия) из нормализованных данных; агент приводит Xray к нему (reconciliation) и подтверждает applied_revision. Снапшот не хранится — только счётчик ревизии. См. Архитектуру.
Отклонённые альтернативы
Section titled “Отклонённые альтернативы”Императивные RPC (AddInbound/AddUser/… с per-строчными статусами pending/applied/error) — предыдущий дизайн. Требует от backend отслеживать результат каждой команды на каждой ноде: дрейф при потере команды, ручные откаты при частичном отказе, зависимость от порядка (цепочки разворачивались «с хвоста» с откатом), отдельные процедуры ресинхронизации и восстановления, таблицы синхронизации per-пользователь. Каждая из проблем в декларативной модели отсутствует по построению.
Последствия
Section titled “Последствия”- (+) Один механизм вместо шести процедур: применение, ретрай, ресинк, восстановление, откат, bootstrap — всё это reconciliation.
- (+) Идемпотентность бесплатно: повторный снапшот → пустой diff.
- (−) Агент обязан уметь считать diff со своим Xray — сосредоточенная сложность в одном компоненте.
- (−) Рендер выполняется на каждое изменение; при целевом масштабе (сотни нод) это дёшево.