Перейти к содержимому

Как работают неизменяемые версии пайплайнов

Проблема: LLM-контент-пайплайн меняется постоянно — промпты, гейты, порядок шагов. Если код, произведший вчерашнюю тысячу статей, можно править на месте, ты теряешь ответ на единственный важный при регрессии качества вопрос: что именно произвело эту статью?

Наивный ответ — «посмотри git-историю» — не работает операционно: флот исполняет не git-историю, а то, что лежит на диске, и «маленький фикс», задеплоенный в полдень, молча меняет то, что сделает ночной прогон.

Каждая версия пайплайна — полная неизменяемая директория кода: pipelines/{id}/{variant}/{version}/ со своим manifest.yaml. После регистрации директория не редактируется никогда. Правка — сколь угодно малая — становится карвом: байт-копия родительской версии, патч, регистрация новой версии в каталоге.

carve: copy + patchcarverollback targetv3.1.16frozenv3.1.17frozenv3.1.18latestcatalog.yamllatest pointer

Манифест — это контракт: диспетчер читает его — шаги, требуемое окружение, entrypoint’ы — и никогда не заглядывает в код. Старые версии остаются в списке и остаются запускаемыми.

Какая версия исполнится, решается в момент диспатча: явный запрос → пин контракта → latest каталога. Ночной прод-прогон дополнительно пинит свои версии Collect/Generate явно, что превращает промоушен в осознанные два шага: приземлить версию, затем передвинуть пин. Регрессия, найденная между шагами, не касается флота.

  • Форензика. Каждый прогон записывает свою версию; версия не может измениться под ним. «Какой код написал это предложение» имеет точный ответ и месяцы спустя.
  • Мгновенный откат. Передвинь указатель обратно. Без revert-коммитов, без редеплоя, без «почти того же».
  • Безопасная параллельность. Несколько агентов карвят будущие версии, пока прод стоит на пине; ничто из их работы не дестабилизирует работающий код.
  • Честный A/B. Две сосуществующие версии каталога можно гнать по живым контрактам и сравнивать по выходу — ни одна не движущаяся мишень.

Неизменяемость копит директории. Политика ретеншна держит дерево компактным: выживают версии на живых пинах, latest с предшественником и именованные цели отката; остальное удаляется из дерева явной, одобренной владельцем очисткой (история остаётся в git, и каждая удалённая версия оставляет тег для восстановления). Нумерация несёт смысл: новый мажор отмечает архитектурное поколение (для Collect v3.x — векторное ранжирование; v2.x — по ключевым словам — остаётся аварийным фолбэком).

Возьми поверхность каталога и текущие пины через API — или просто прочти машинный манифест этой сборки документации: та же философия применена к этим страницам — versions.json + manifest.json с content-хэшами в корне портала.

Спеки: SPEC-054 (каталог + manifest=contract), SPEC-063 (нативное исполнение), SPEC-120 (ретеншн карвов).