- docs/07: полный порядок staged apply, инвариант снятия guard, объяснение
почему окно 45 секунд не обязано покрывать smoke и почему guard не трогает
nftables.service, семантическая проверка эффективного firewall;
- docs/11: разделы A5e/A5f для новых unit-тестов и серверные сценарии D1e
(guard доходит до дедлайна), D1f (конкурентные операции), D1g (успешная
операция не оставляет следов транзакции); матрица и acceptance criteria
дополнены;
- docs/12: разбор отказов "уже выполняется другая операция" и
firewall_guard_fired;
- docs/13: строки журнала guard в таблице recovery, новый раздел 8a про замок
операций;
- docs/14 и purge-v0.sh: очистка /run/hy2xs, замка операций и candidate-файлов
firewall — /run это tmpfs, но очистка не имеет права требовать перезагрузки;
- README: защита от потери доступа при смене firewall и раздел "Одна операция
за раз";
- CHANGELOG: шестой проход.
verify_versions_contract получил сверку API namespace. Путь machine-auth
записывается в /etc/hysteria/config.yaml и в post-install.env, то есть по нему
Hysteria обращается к админке. Пока строка была продублирована в шаблонах,
smoke, тестах, приёмке и e2e, расхождение обнаруживалось только на живом
сервере. Теперь Go-константы, API_BASE фронтенда и оба шаблона сверяются
против значений, скомпилированных в оркестратор.
Приёмка проверяет, что:
- fatal_pre_apply недостижим после записи install-state;
- каждый ownership-флаг взводится раньше своего шага;
- у read-only фазы нет универсального раннера, через который можно
проскользнуть;
- инвариант публичного endpoint живёт в preflight и не обращается к внешним
сервисам определения IP;
- purge-v0.sh и clean-host описывают одну границу;
- секреты не попадают в персистентный файл экспорта;
- импорт пиров валидируется так же строго, как их создание;
- удалённые exportConfig/importConfig не вернулись.
Захардкоженная схема =2 в приёмке заменена на значение из versions.env: при
переходе на schema 3 пришлось бы помнить ещё и про эту строку.
Документация: контракт раннеров и ownership в 08, инвариант публичного
endpoint в 08/09/12/13 и README, сетевая идентичность панели и удалённые
export/import в 04, сценарии D1 (отказ сразу после PHASE 0) и D2 (устаревший
DNS после смены IPv4) в 11, версии package.json как не-версия продукта в 02.
Новый docs/14-legacy-cleanup.md: как выглядит отказ установщика, полный
список маркеров чужой установки, что сохранить перед очисткой, работа
purge-v0.sh, ручная процедура и отдельно - случай незавершённой
установки текущего поколения, где нужен repair, а не очистка.
Обновлено под фактическое поведение:
- README и package/docs: установка описана как две фазы, PHASE 0 ничего
не меняет; добавлен troubleshooting по отказу clean-host; версии
toolchain больше не передаются через окружение;
- 02-build-layer: раздел про versions.env (что в нём есть и чего нет и
почему), verify_versions_contract, проверка происхождения артефакта
по upstream hashes.txt;
- 08-orchestrator-spec: двухфазный контракт, read-only guard,
идентификация поколения в install-state, ownership-aware rollback,
расширенная семантическая проверка конфига, структурная редакция;
- 04-admin-panel: таблица удалённых маршрутов и почему они удалены, а
не оставлены заглушками; сужена формулировка гарантии санитайза;
- 11-testing: новые unit-наборы, полный список инвариантов конфига,
раздел про одну реализацию URI вместо двух, сценарий проверки
границы установки на живом сервере;
- 12-operations и 13-runbook: диагностика отказов по поколению,
поведение diagnostics-бандла;
- tools/build/README: контракт версий, обе суммы Bun, hashes.txt.
CHANGELOG: раздел Unreleased с разбором каждого исправленного дефекта.