From a91a9b8c2e7e7d01589a024934fa298d90f6d813 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 10:54:56 +0300 Subject: [PATCH 01/25] Correct release status for BROray 2.2.6 candidate --- README.md | 165 ++++++++++++------------------------------------------ 1 file changed, 35 insertions(+), 130 deletions(-) diff --git a/README.md b/README.md index 9fd688e..8c2dc07 100644 --- a/README.md +++ b/README.md @@ -1,144 +1,60 @@ # BROray -**BROray — полноценный клиент Xray для современных маршрутизаторов Keenetic и Netcraze.** Это не только менеджер конфигураций: BROray устанавливает и обслуживает Xray, принимает подписки и отдельные подключения, выбирает активный сервер, создаёт штатный прокси-интерфейс `ProxyN`, управляет маршрутами, DNS-over-TLS, обновлениями и диагностикой через локальный авторизованный WebUI. +**BROray — полноценный клиент Xray для современных маршрутизаторов Keenetic и Netcraze.** BROray устанавливает и обслуживает Xray, принимает подписки и отдельные подключения, выбирает активный сервер, создаёт штатный `ProxyN`, управляет маршрутами, DNS-over-TLS, обновлениями и диагностикой через локальный авторизованный WebUI. -## Статус релиза +## Статус релизов -**BROray 2.2.5 / OPKG 2.2.5 опубликован 31 июля 2026 года и успешно установлен на реальный Keenetic полным пользовательским путём через WebUI.** Проверенный переход выполнен с установленной версии `2.1.1-2`: `BROray → Проверить обновление → Установить обновление`. +- **Стабильный публичный релиз:** BROray `2.2.4`, OPKG `2.2.4`, WebUI `WebUI-2.2.0-r2`. +- **BROray 2.2.5 отозван 31 июля 2026 года.** На физическом роутере обнаружены несовместимые форматы резервной копии между updater и `preinst`, а также ошибочный код возврата функции учёта служб. Пакет, установщики и запись OPKG удалены из публичного канала. +- **BROray 2.2.6 находится в статусе release candidate.** Он не считается опубликованным релизом до прохождения полного физического теста через WebUI теми же неизменяемыми байтами. -Версия 2.2.4 отозвана. В 2.2.5 исправлены обязательный порядок очистки и резервного копирования, preflight свободного места и чтение SHA-256 из OPKG `src/gz`, включая фоновый worker старого WebUI. +## Что исправляет 2.2.6 -## Текущий релиз +- `preinst` распознаёт два допустимых контракта резервной копии: полную копию `/opt` с корнем `broray/` и внутреннюю копию с корнями `bin/`, `lib/`, `web-new/`, `config/`; +- updater явно завершает учёт служб кодом `0`, поэтому остановленная `S28broray-subscriptions` не ломает создание резервной копии; +- updater передаёт `BRORAY_OPKG_CLEANUP_DONE=1`, исключая повторную очистку и вторую резервную копию в `preinst`; +- при ошибке показываются последние строки полного журнала `opkg install`/`preinst`/`postinst` до автоматического отката; +- публичные скрипты должны публиковаться читаемыми Nginx и проверяться внешней загрузкой с SHA-256; +- правила релиза обновлены до версии 1.3: сначала неизменяемый кандидат, затем физический WebUI-тест, затем продвижение ровно тех же байтов. -- Приложение: **BROray 2.2.5** -- Пакет OPKG: **2.2.5** -- Архитектура пакета: **aarch64-3.10** -- WebUI: **WebUI-2.2.0-r3** -- Xray в пакете: **26.7.11**, SHA-256 `dd3ba298aa32af9442163ee791d54f562bd89aa860fed1d0c47306fb019c1e64` +## Обязательная проверка кандидата 2.2.6 -Релиз собран из проверенной контрольной точки реального Keenetic от 30 июля 2026 года. Публикация OPKG и сайта завершилась со статусом `success`, кодом `0`; публичные `Packages`, обычная и no-cache загрузки IPK совпали. Полевое обновление до 2.2.5 через WebUI завершилось успешно 31 июля 2026 года. +1. Сборка кандидата из точных отозванных байтов 2.2.5, сохранённых в серверном карантине. +2. Публикация только в закрытый staging-канал. +3. Обновление через установленный WebUI с `2.2.0-2` и `2.2.4`. +4. Тест с остановленной `S28broray-subscriptions`. +5. Принудительная ошибка установки, автоматический откат и успешная повторная попытка. +6. Чистая установка на физическом роутере. +7. Проверка пяти служб, WebUI, Xray, ProxyN, DNS-over-TLS, маршрутов и пользовательских данных. +8. Только после отчёта `PASS` — атомарное продвижение тех же байтов из staging в публичный OPKG. + +Подробности: [`docs/RELEASE-2.2.6.md`](docs/RELEASE-2.2.6.md) и [`docs/RELEASE-REQUIREMENTS.md`](docs/RELEASE-REQUIREMENTS.md). ## Основные возможности - локальный авторизованный WebUI для компьютера, планшета и телефона; - импорт VLESS, VMess, Trojan и Hysteria2; - подписки, отдельные серверы, проверка качества и автоматическое переключение; -- полный жизненный цикл Xray: запуск, остановка, перезапуск, проверка конфигурации, диагностика, обновление и безопасная переустановка; -- создание и восстановление штатного интерфейса KeeneticOS/NDMS `ProxyN`; -- свои BAT-маршруты и девять готовых наборов маршрутов; -- единый реестр владельцев маршрутов: общие маршруты не удаляются, пока нужны другому набору; -- единое окно фактического прогресса, безопасная остановка после текущего маршрута и продолжение; -- DNS-over-TLS с TLS/SNI-проверкой, Яндекс DNS, сохранением внешних DoT/DoH и транзакционным откатом; -- безопасное обновление BROray: удаление старых автоматических копий и мусора, одна проверенная актуальная копия только в `/tmp`, точный preflight места и автоматическое восстановление; -- восстановительная переустановка, технический журнал и безопасная очистка управляемых файлов. - -## Требования к роутеру +- полный жизненный цикл Xray; +- создание и восстановление `ProxyN`; +- свои BAT-маршруты и девять готовых наборов; +- единый реестр владельцев общих маршрутов; +- DNS-over-TLS с транзакционным откатом; +- восстановительная переустановка, технический журнал и безопасная очистка. -Подробности: [`docs/REQUIREMENTS.md`](docs/REQUIREMENTS.md). +## Требования -Кратко: +См. [`docs/REQUIREMENTS.md`](docs/REQUIREMENTS.md). Основная архитектура пакета — `aarch64-3.10`; требуется Entware, записываемый `/opt` и доступ к Entware root shell. -1. Современный Keenetic или Netcraze с `aarch64/arm64` и архитектурой Entware `aarch64-3.10`. -2. Установленные компоненты **Open Package support** и **Proxy client**. -3. Установленный Entware/OPKG, доступная для записи точка `/opt` и SSH-доступ именно к Entware root shell. Системный компонент **SSH server** не обязателен, если доступ уже предоставляет Entware OpenSSH/Dropbear. -4. Для страницы DNS-over-TLS — компонент **DNS-over-TLS proxy**. -5. Для удобной загрузки файлов рекомендуется компонент **SFTP server**. -6. Минимум 41693 КБ свободно в `/opt`; практический минимум — 50 МБ, рекомендуется 80 МБ. -7. Минимум 64 МБ свободно в `/tmp`; рекомендуется 128 МБ. +## Стандартное обновление -## Стандартное обновление через WebUI - -Основной и обязательный пользовательский путь обновления: +Публичные стабильные обновления устанавливаются только через WebUI: ```text BROray → Проверить обновление → Установить обновление ``` -Версия 2.2.5 загружается по точному полю `Filename` из OPKG-индекса, с запретом HTTP-кэша, уникальным параметром запроса и обязательной проверкой SHA-256. Административные скрипты установки и safe-upgrade остаются аварийными инструментами, но не заменяют проверку пользовательского пути WebUI. - -### Совместимость старого updater - -Переход с `2.1.1-2` полевым испытанием подтверждён, но старый updater потребовал отдельного совместимого ремонта до запуска установки: чтение `SHA256sum` из локального `src/gz` и значение `BRORAY_OPKG_LISTS_DIR` должны быть доступны также скопированному фоновому worker. Этот ремонт не устанавливает релиз; после него установка по-прежнему выполняется только через WebUI. - -В пакет 2.2.5 включён `preinst`-мост для обновления с ветки 2.1.1/2.2.0. Если старый updater уже успел создать копию в `/opt/broray/backup`, пакет переносит её в `/tmp`, очищает старые копии и мусор, создаёт после очистки новую актуальную копию в `/tmp` и только затем разрешает распаковку. Для этого `Installed-Size` используется как совместимый резерв OPKG, а фактический размер и обязательные 42000 КБ хранятся в отдельных проверяемых полях пакета. - -## Чистая установка - -После публикации релиза на `api.brovibe.cloud`: - -```sh -opkg update && -opkg install ca-bundle ca-certificates curl jq lighttpd lighttpd-mod-cgi openssl-util tar && -TARGET="/tmp/broray-install-2.2.5.sh" && -/opt/bin/curl -fL --retry 3 -o "$TARGET.part" \ - "https://api.brovibe.cloud/releases/broray-install-2.2.5.sh?v=$(date +%s)" && -echo "1b5d74a31c78556abd7341b100e7e961d3884c52b7e6b275724b7ed48e3a0ea2 $TARGET.part" | sha256sum -c - && -mv "$TARGET.part" "$TARGET" && -chmod 700 "$TARGET" && -/opt/bin/ash "$TARGET" -``` - -## Аварийное административное обновление - -Обычные обновления выполняются только через WebUI. Следующий скрипт предназначен для восстановления или диагностики, когда WebUI недоступен. - -```sh -opkg update && -opkg install ca-bundle ca-certificates curl jq lighttpd lighttpd-mod-cgi openssl-util tar && -TARGET="/tmp/broray-safe-upgrade-2.2.5.sh" && -/opt/bin/curl -fL --retry 3 -o "$TARGET.part" \ - "https://api.brovibe.cloud/releases/broray-safe-upgrade-2.2.5.sh?v=$(date +%s)" && -echo "dc2f417c40c47d50aa4e9ad29eaf6ea993e5b5e125f91b12a99ac4d75379417d $TARGET.part" | sha256sum -c - && -mv "$TARGET.part" "$TARGET" && -chmod 700 "$TARGET" && -BRORAY_TMP_ROOT=/tmp /opt/bin/ash "$TARGET" -``` - -IPK: - -```text -Файл: broray_2.2.5_aarch64-3.10.ipk -Размер: 13 995 075 байт -SHA-256: -8a2255e2c181a5f88438673c186da4f89870cb54bc01e656d57671d46cae9adc -``` - -## Документация - -- [Полевое подтверждение релиза 2.2.5](docs/FIELD-TEST-2.2.5.md) -- [Обязательные требования к релизам](docs/RELEASE-REQUIREMENTS.md) -- [Требования и совместимость](docs/REQUIREMENTS.md) -- [Установка, обновление и удаление](docs/INSTALLATION.md) -- [Полный справочник WebUI](docs/WEBUI.md) -- [Архитектура и безопасность](docs/ARCHITECTURE.md) -- [Примечания к релизу](docs/RELEASE-2.2.5.md) - -## WebUI - -После установки локальный адрес обычно имеет вид: - -```text -http://192.168.1.1:8080/ -``` - -Фактический LAN-адрес определяется автоматически. WebUI также может публиковаться через штатный KeenDNS HTTP Proxy, если он настроен на роутере. - -## CLI - -```sh -broray help -broray status -broray current -broray list -broray test -broray restart -broray xray update-check -broray xray update -broray-servers summary -broray-subscriptions list -broray-routes summary -broray-routes-dot status -``` +Release candidate 2.2.6 нельзя устанавливать из публичного канала до завершения полевого теста. ## Поддержка @@ -149,15 +65,4 @@ broray-routes-dot status ## Лицензия -Исходный код BROray распространяется по GNU GPL v3. Xray-core поставляется как отдельный сторонний компонент на собственных условиях; его лицензия находится в `third_party/xray/` и в установленном каталоге лицензий. - -## Нумерация версий - -- **BROray 2.2.5** — версия приложения, которую видит пользователь и которая используется как публичная версия OPKG. -- **WebUI-2.2.0-r3** — отдельная понятная версия WebUI. -- Техническая ревизия пакета хранится в поле `X-BROray-Package-Revision` и не подменяет версию приложения в интерфейсе. -- Поле «Доступная версия» показывает только `2.2.5`; технические сведения OPKG находятся отдельно. - -## Состояние исходного дерева GitHub - -Этот документ публикует сведения о фактически опубликованном и установленном пакете 2.2.5. Перенос точного исходного overlay релиза в дерево `root/`, синхронизация `web-src`/`web-new` и создание тега выполняются отдельным кодовым изменением; до него документация не означает побайтовое совпадение текущего `main` с публичным IPK. +BROray распространяется по GNU GPL v3. Xray-core поставляется как отдельный сторонний компонент на собственных условиях. From ed045b5942a55fb0a71059abc73a9cfab0c26497 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 10:55:21 +0300 Subject: [PATCH 02/25] Record BROray 2.2.6 candidate and 2.2.5 revocation --- CHANGELOG.md | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64993d0..0d6896a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,32 +1,36 @@ # История изменений -## 2.2.5 / OPKG 2.2.5 — 2026-07-31 - -- публичный OPKG-feed и документация опубликованы атомарно; обычная и no-cache загрузки IPK совпали с `Packages`; -- переход `2.1.1-2 → 2.2.5` успешно завершён через WebUI на реальном Keenetic; -- исправлено чтение `SHA256sum` из сжатого локального `src/gz` и передача `BRORAY_OPKG_LISTS_DIR` фоновому worker старого WebUI; -- перед установкой удаляются старые автоматические копии и управляемый мусор, затем создаётся одна актуальная проверенная копия только в `/tmp`; -- BROray позиционируется как полноценный клиент Xray для современных Keenetic и Netcraze, а не только менеджер конфигураций; -- финализирован адаптивный WebUI для компьютера, планшета и телефона; -- добавлена отдельная страница DNS-over-TLS, предустановки Яндекс DNS и поддержка вложенного running-config Keenetic; -- исправлены фактическая сверка DoT/DoH, лимит восьми серверов, сообщения этапа ошибки и транзакционный откат; -- добавлена отдельная кнопка обновления Xray; обновление и переустановка разделены; -- исправлен JSON backend проверки обновления и безопасной очистки BROray; -- маршруты разделены на обзор, свои маршруты и готовые маршруты; -- добавлены подпункты раздела маршрутов в меню; -- девять готовых наборов работают через один агрегированный summary; -- пользовательские BAT анализируются как текст и никогда не выполняются; -- единое окно прогресса открывается сразу, поддерживает остановку после текущего маршрута и продолжение; -- в покое polling маршрутов сокращён, скрытые вкладки не опрашивают backend, параллельные запросы не накапливаются; -- сохранён единый реестр владельцев общих маршрутов; -- добавлены восстановительная переустановка, безопасная очистка, технические журналы и полный жизненный цикл BROray; -- релиз собран из проверенной контрольной точки реального роутера. +## 2.2.6 / OPKG 2.2.6 — release candidate + +- исправлена несовместимость контракта резервной копии между updater и пакетным `preinst`; +- `preinst` распознаёт как полную копию `/opt` с `broray/...`, так и внутреннюю rootless-копию; +- функция учёта состояния служб завершается явным `return 0`; +- остановленная `S28broray-subscriptions` больше не считается ошибкой резервного копирования; +- updater передаёт `BRORAY_OPKG_CLEANUP_DONE=1` и не допускает повторную очистку или вторую копию; +- полный вывод OPKG, `preinst` и `postinst` сохраняется и показывается перед откатом; +- правила релиза обновлены до версии 1.3: неизменяемый кандидат → физический WebUI-тест → продвижение тех же байтов; +- добавлена обязательная проверка повторного обновления после отката и внешних HTTP/SHA-прав установочных файлов; +- кандидат не публикуется в стабильный канал до подтверждённого физического теста. + +## 2.2.5 / OPKG 2.2.5 — ОТОЗВАН 2026-07-31 + +- пакет и OPKG-индекс были побайтово согласованы, но реальное обновление с `2.2.0-2` завершилось ошибкой; +- updater создавал полную копию `/opt` с корнем `broray/`, а `preinst` принимал только rootless-корни `bin/`, `lib/`, `web-new/`, `config/`; +- после отката повторная попытка могла остановиться из-за отсутствующего явного `return 0` в функции учёта служб; +- релиз был полностью удалён из публичного OPKG, установочные файлы перемещены в серверный карантин, документация возвращена к 2.2.4; +- прежнее утверждение об успешном физическом WebUI-обновлении было ошибочным и отменено. + +## 2.2.4 / OPKG 2.2.4 — текущий стабильный + +- стабильный публичный релиз после отзыва 2.2.5; +- WebUI `WebUI-2.2.0-r2`; +- сохранён как базовая версия публичного канала и пакет возврата. ## 2.2.0 / OPKG 2.2.0-2 — полевой кандидат - полевое обновление на реальном Keenetic; -- первоначальная отдельная страница DNS-over-TLS; -- подготовка новой архитектуры маршрутов и серии принятых hotfix. +- отдельная страница DNS-over-TLS; +- новая архитектура маршрутов и принятые hotfix. ## 2.1.1-2 — 2026-07-27 From b5f33586939da1f000e006f560734182f97ce2be Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 10:55:48 +0300 Subject: [PATCH 03/25] Strengthen BROray release requirements after updater failure --- docs/RELEASE-REQUIREMENTS.md | 64 ++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/docs/RELEASE-REQUIREMENTS.md b/docs/RELEASE-REQUIREMENTS.md index b4fc5b7..73ab708 100644 --- a/docs/RELEASE-REQUIREMENTS.md +++ b/docs/RELEASE-REQUIREMENTS.md @@ -1,39 +1,45 @@ # Обязательные требования к релизам BROray -Версия документа: 1.2, принята для BROray 2.2.5. +Версия документа: 1.3, принята для BROray 2.2.6. ## Неподлежащий изменению порядок обновления -1. Все публичные обновления проверяются полным пользовательским путём: `BROray → Проверить обновление → Установить обновление`. -2. До загрузки пакета обновления и до создания новой копии updater удаляет все старые автоматические резервные копии BROray из `/opt/broray/backup`, `/opt/broray/backups` и `/opt/broray/routes/backup`. -3. Затем полностью удаляются управляемые временные данные, старые релизные файлы BROray в `/opt/tmp` и OPKG-кэш. Только после завершения этой очистки разрешено создавать актуальную копию. Серверы, подписки, активная конфигурация Xray, настройки и установленные маршруты не удаляются. +1. Финальный публичный релиз запрещено собирать заново после полевого теста. Сначала создаётся неизменяемый release candidate, затем именно эти байты проходят полевой тест и только после этого побайтово продвигаются в публичный канал. +2. Все публичные обновления проверяются полным пользовательским путём: `BROray → Проверить обновление → Установить обновление`. +3. До загрузки нового IPK и до создания новой копии updater удаляет старые автоматические резервные копии BROray, управляемые временные данные и OPKG-кэш. Серверы, подписки, активная конфигурация Xray, настройки, пользовательские маршруты и установленные наборы маршрутов не удаляются. 4. После очистки повторно измеряется свободное место в `/opt` и `/tmp`. -5. Создаётся ровно одна актуальная полная резервная копия в `/tmp/broray-update-/backup.tar.gz`. Она обязательно проверяется чтением архива и наличием обязательных разделов. Только после успешной проверки этой копии разрешены загрузка точного нового IPK, подготовка пакета возврата и установка. -6. До `opkg install` свободное место в `/opt` должно быть не меньше значения `X-BROray-Required-Opt-KB` (для 2.2.5 — 42000 КБ). При недостатке места установка не запускается, а WebUI показывает доступный и требуемый объём. -7. Временная копия никогда не переносится в `/opt` перед установкой и не уменьшает место раздела OPKG. -8. При ошибке используется точный пакет предыдущей установленной версии и актуальная копия из `/tmp`. При успешном откате временный каталог удаляется; при неудачном откате он сохраняется для ручного восстановления. -9. После установки проверяются версия приложения и OPKG, пять служб, WebUI, Xray, ProxyN, DNS-over-TLS и обязательные backend-файлы маршрутов. -10. После успешной проверки временная копия и staging удаляются. -11. Чтение метаданных OPKG обязано работать как с обычным `Packages`, так и со сжатым локальным списком `src/gz`; отсутствие `SHA256sum` запрещено трактовать как несовпадение суммы. -12. Для каждой поддерживаемой старой версии проверяется реальный переход через её установленный WebUI. Если старый updater имеет известный дефект, публикуется отдельный минимальный совместимый ремонт updater, который не устанавливает релиз и после которого сама установка выполняется только через WebUI. -13. Если старый updater уже создал копию в `/opt`, `preinst` переносит её в `/tmp`, очищает старые копии и мусор, создаёт после очистки новую актуальную копию в `/tmp` и сохраняет совместимый путь отката до завершения проверки. -14. `Installed-Size` может использоваться как совместимый резерв только для входа старого OPKG в `preinst`; реальный размер и обязательное место фиксируются в `X-BROray-Actual-Installed-Size` и `X-BROray-Required-Opt-KB`. +5. Создаётся ровно одна актуальная полная резервная копия в `/tmp/broray-update-/backup.tar.gz`; она проверяется чтением архива и обязательными разделами до загрузки нового пакета. +6. Контракт резервной копии версионируется. Updater может передавать полную копию `/opt` с корнями `broray/`, `bin/` и `etc/`; пакетный `preinst` может создавать внутреннюю копию с корнями `bin/`, `lib/`, `web-new/`, `config/`. `preinst` обязан явно распознавать оба формата и запрещает смешанный или неполный формат. +7. Функции учёта состояния служб всегда завершаются явным `return 0`, если состояние успешно записано; остановленная необязательная служба не является ошибкой создания резервной копии. +8. До `opkg install` свободное место в `/opt` должно быть не меньше `X-BROray-Required-Opt-KB`. Временная копия никогда не переносится в `/opt` перед установкой. +9. При ошибке используется точный пакет предыдущей версии и актуальная копия из `/tmp`. Успешный откат восстанавливает код, OPKG-метаданные, пользовательские данные, журналы, runtime-состояние и ранее сохранённые резервные копии. +10. Полный вывод `opkg install`, `preinst` и `postinst` сохраняется в журнале и последние строки выводятся пользователю при ошибке до запуска отката. +11. После установки проверяются приложение и OPKG, пять служб, WebUI, Xray, ProxyN, DNS-over-TLS, маршруты и сохранность пользовательских данных. +12. После успешной проверки временная копия и staging удаляются. +13. Чтение метаданных OPKG работает с `Packages` и сжатым локальным `src/gz`; отсутствие прочитанного `SHA256sum` является ошибкой метаданных, а не сообщением о несовпадении суммы. +14. Для каждой поддерживаемой старой версии проверяется реальный переход через установленный WebUI. Известный дефект старого updater исправляется отдельным минимальным совместимым ремонтом, который сам релиз не устанавливает. +15. Публичные `.sh` и `.txt` устанавливаются с правами не строже `0644`; публикация обязана проверять HTTP 200 и SHA-256 каждого файла от имени внешнего клиента. -## Релизные запреты +## Обязательная матрица перед публичным выпуском -- Нельзя изменять уже опубликованный IPK под прежним именем или версией. -- Нельзя публиковать `Packages` раньше самого IPK. -- Нельзя считать релиз готовым только по статическим тестам: обязателен реальный путь WebUI на поддерживаемом Keenetic/Netcraze. -- Нельзя выполнять релизную установку на тестовом роутере ручным `opkg install`, локальным IPK или runner-скриптом вместо WebUI. -- Нельзя создавать временную резервную копию обновления в `/opt`. +- две детерминированные сборки кандидата побайтово совпадают; +- статические проверки BusyBox `ash`, JavaScript и JSON; +- динамический тест обоих форматов резервной копии; +- обновление через WebUI с 2.2.0-2 и актуальной стабильной 2.2.4; +- чистая установка на физическом роутере; +- остановленная S28 до обновления не ломает создание копии; +- принудительная ошибка `preinst` и автоматический откат; +- повторное обновление после успешного отката; +- сохранность серверов, подписок, активного сервера, маршрутов, DNS и ProxyN; +- публичные обычная и no-cache загрузки совпадают с `Packages`; +- документация переключается на новую версию только после успешного полевого отчёта; +- публикационный архив и detached-команда выдаются вместе и имеют отдельные SHA-256. -## Обязательные доказательства перед финальным статусом +## Релизные запреты -- две детерминированные сборки IPK побайтово совпадают; -- SHA-256 публичного IPK совпадает с `Packages` при обычной и no-cache загрузке; -- BusyBox `ash` принимает все shell-скрипты; -- updater удаляет старые копии до создания новой; -- актуальная копия расположена только в `/tmp`; -- тест недостатка места останавливает операцию до `opkg install`; -- тест ошибки установки подтверждает автоматический откат; -- сохранность пользовательских данных подтверждена сравнением до и после. +- Нельзя изменять опубликованный файл под прежним именем. +- Нельзя публиковать `Packages` раньше IPK и установочных файлов. +- Нельзя объявлять полевой успех по лабораторной симуляции. +- Нельзя публиковать release candidate как стабильный до физического WebUI-теста. +- Нельзя скрывать вывод OPKG общей фразой без сохранённого журнала. +- Нельзя оставлять отозванный пакет, установщик, updater или документацию в публичном канале. From 75b545475d5caf769246a9414c4ee4e77ea0a53a Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 10:56:11 +0300 Subject: [PATCH 04/25] Add BROray 2.2.6 release candidate plan --- docs/RELEASE-2.2.6.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/RELEASE-2.2.6.md diff --git a/docs/RELEASE-2.2.6.md b/docs/RELEASE-2.2.6.md new file mode 100644 index 0000000..1ba3545 --- /dev/null +++ b/docs/RELEASE-2.2.6.md @@ -0,0 +1,43 @@ +# BROray 2.2.6 — release candidate + +## Статус + +BROray 2.2.6 подготовлен как **неизменяемый release candidate**, а не как уже опубликованный стабильный релиз. Текущий публичный стабильный канал остаётся на BROray/OPKG 2.2.4. + +Публичное продвижение 2.2.6 разрешено только после физического теста тех же байтов через WebUI и итогового отчёта `PASS`. + +## Причины выпуска + +BROray 2.2.5 был отозван после реального теста на роутере с версией `2.2.0-2`: + +1. updater передавал резервную копию полного `/opt` с путями `broray/...`, а пакетный `preinst` принимал только rootless-пути `bin/`, `lib/`, `web-new/`, `config/`; +2. функция записи состояния служб не имела явного успешного возврата и могла завершиться кодом остановленной последней службы; +3. пользователю показывалась общая ошибка OPKG без полезного хвоста `preinst`/`postinst`; +4. серверная публикация первоначально выдала `.sh` с правами `0700`, из-за чего Nginx отвечал `403`. + +## Исправления + +- два явных допустимых формата backup; +- `return 0` после успешного учёта служб; +- `BRORAY_OPKG_CLEANUP_DONE=1` при передаче уже проверенной копии; +- полный журнал OPKG до отката; +- staging-публикация с внешней HTTP/SHA-проверкой; +- права публичных статических файлов `0644`; +- правила релиза 1.3 и запрет пересборки после field test. + +## Порядок выпуска + +1. На сервере собрать кандидат скриптом `scripts/build-release-candidate-2.2.6.sh` из точных файлов отозванного 2.2.5 в карантине. +2. Сверить внутренний `SHA256SUMS` и внешний SHA архива кандидата. +3. Опубликовать кандидат только в `/releases/staging/broray/2.2.6-r1/`. +4. Подготовить тестовый роутер к staging и запустить установку исключительно из WebUI. +5. Выполнить матрицу из [`FIELD-TEST-2.2.6.md`](FIELD-TEST-2.2.6.md). +6. После `PASS` продвинуть точные байты без пересборки; затем обновить документацию, GitHub tag и release notes. + +## Что не считается выпуском + +- лабораторная распаковка IPK; +- успешный `bash -n`/`ash -n`; +- локальная симуляция публикации; +- ручной `opkg install` вместо WebUI; +- установка пересобранного после field test пакета. From 9cf03aadfbfd727c588e16865a9a2a05543dc986 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 10:56:32 +0300 Subject: [PATCH 05/25] Add mandatory BROray 2.2.6 field test matrix --- docs/FIELD-TEST-2.2.6.md | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs/FIELD-TEST-2.2.6.md diff --git a/docs/FIELD-TEST-2.2.6.md b/docs/FIELD-TEST-2.2.6.md new file mode 100644 index 0000000..7c29ec2 --- /dev/null +++ b/docs/FIELD-TEST-2.2.6.md @@ -0,0 +1,53 @@ +# Полевой тест BROray 2.2.6 + +## Идентичность кандидата + +Перед тестом зафиксировать: + +- имя архива кандидата и SHA-256; +- имя IPK, размер и SHA-256; +- SHA-256 safe-upgrade, installer и compatibility repair; +- WebUI `WebUI-2.2.0-r4`; +- исходную версию роутера и модель устройства. + +## Обязательные сценарии + +### A. Обновление 2.2.0-2 через WebUI + +- проверить доступное обновление; +- нажать «Установить обновление»; +- убедиться, что используется staging `Filename` и точная SHA-256; +- проверить пять служб, WebUI, Xray, ProxyN, DNS-over-TLS и маршруты; +- сравнить пользовательские серверы, подписки, активный сервер и настройки до/после. + +### B. Остановленная S28 + +- до запуска обновления остановить `S28broray-subscriptions`; +- убедиться, что создание копии завершается успешно; +- после установки проверить ожидаемое состояние всех служб и отсутствие ложной ошибки backup. + +### C. Принудительная ошибка и откат + +- вызвать контролируемую ошибку до завершения установки; +- проверить показ хвоста полного OPKG/preinst/postinst-журнала; +- подтвердить восстановление версии, OPKG-метаданных, пяти служб, пользовательских данных, runtime и сохранённых резервных копий; +- убедиться, что при успешном откате временный workspace удалён. + +### D. Повтор после отката + +- повторить штатное обновление через WebUI; +- подтвердить успешную установку тех же байтов кандидата; +- убедиться, что остаточные marker-файлы не мешают backup. + +### E. Обновление 2.2.4 через WebUI + +- повторить сценарий A с текущей стабильной версии 2.2.4. + +### F. Чистая установка + +- выполнить чистую установку кандидата на физическом поддерживаемом устройстве; +- проверить пять служб, WebUI, Xray, ProxyN, DNS-over-TLS, маршруты и отсутствие пользовательских/runtime-данных в исходном пакете. + +## Итоговый критерий + +Статус `PASS` разрешён только когда все сценарии A–F завершены теми же SHA-256. Любое изменение байтов отменяет результаты теста и требует нового кандидата. From ff7bf20b483b1b37134c7439b3203c2f571b4558 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 11:03:32 +0300 Subject: [PATCH 06/25] Add verified entrypoint for BROray 2.2.6 candidate builder --- .../run-release-candidate-builder-2.2.6.sh | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 scripts/run-release-candidate-builder-2.2.6.sh diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh new file mode 100644 index 0000000..2d78242 --- /dev/null +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -u + +BUILDER="/root/BROray-2.2.6-release-candidate-builder.sh" +EXPECTED="23e3bda0edbfc754544f6bd89c772c5aea50afe003a767b118d7e373b0a66597" +READY=yes + +printf '%s\n' "==================================================" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder" +printf '%s\n' "==================================================" + +if [ "$(id -u)" -ne 0 ]; then + echo "ОШИБКА: требуется root" + READY=no +fi + +if [ ! -f "$BUILDER" ]; then + echo "ОШИБКА: файл не найден: $BUILDER" + READY=no +fi + +if [ "$READY" = yes ]; then + ACTUAL="$(sha256sum "$BUILDER" 2>/dev/null | awk '{print $1}')" + echo "SHA-256: $ACTUAL" + if [ "$ACTUAL" != "$EXPECTED" ]; then + echo "ОШИБКА: SHA-256 builder не совпадает" + READY=no + elif ! bash -n "$BUILDER"; then + echo "ОШИБКА: builder не прошёл bash -n" + READY=no + fi +fi + +if [ "$READY" = yes ]; then + bash "$BUILDER" + RESULT=$? +else + RESULT=1 +fi + +echo +echo "Код завершения: $RESULT" +echo "Публичный стабильный канал не должен изменяться на этапе сборки кандидата." +echo "Терминал остаётся открытым." +echo "==================================================" +exit "$RESULT" From 1036b26e6876602a16aa0afe613a83bcb598e2db Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 11:06:19 +0300 Subject: [PATCH 07/25] Update BROray 2.2.6 builder checksum after final audit --- scripts/run-release-candidate-builder-2.2.6.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index 2d78242..d75c7b9 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -2,7 +2,7 @@ set -u BUILDER="/root/BROray-2.2.6-release-candidate-builder.sh" -EXPECTED="23e3bda0edbfc754544f6bd89c772c5aea50afe003a767b118d7e373b0a66597" +EXPECTED="888502163d790b62ce9a9e76adf3212f802309492da89a32f997732a1cf22858" READY=yes printf '%s\n' "==================================================" From 7b2ffdbcd84421afe8755f5790e5e85ead59aa1d Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 13:56:46 +0300 Subject: [PATCH 08/25] Use corrected BROray 2.2.6 candidate builder r2 --- scripts/run-release-candidate-builder-2.2.6.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index d75c7b9..6945672 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder.sh" -EXPECTED="888502163d790b62ce9a9e76adf3212f802309492da89a32f997732a1cf22858" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r2.sh" +EXPECTED="759386247553adc0d1ee64e43bc53c8606c5aa88a5d0c6a72a9674e09660c0c3" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r2" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then From 0808e669d4d41a30eaff3ba168fb1bad3f77bf7e Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 13:57:31 +0300 Subject: [PATCH 09/25] Document corrected BROray 2.2.6 builder r2 --- docs/RELEASE-2.2.6.md | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/RELEASE-2.2.6.md b/docs/RELEASE-2.2.6.md index 1ba3545..4fb4459 100644 --- a/docs/RELEASE-2.2.6.md +++ b/docs/RELEASE-2.2.6.md @@ -15,7 +15,7 @@ BROray 2.2.5 был отозван после реального теста на 3. пользователю показывалась общая ошибка OPKG без полезного хвоста `preinst`/`postinst`; 4. серверная публикация первоначально выдала `.sh` с правами `0700`, из-за чего Nginx отвечал `403`. -## Исправления +## Исправления 2.2.6 - два явных допустимых формата backup; - `return 0` после успешного учёта служб; @@ -25,11 +25,34 @@ BROray 2.2.5 был отозван после реального теста на - права публичных статических файлов `0644`; - правила релиза 1.3 и запрет пересборки после field test. +## Candidate builder r2 + +Первая попытка builder r1 была безопасно остановлена независимой проверкой распаковки: каталоги `check/control` и `check/data` не создавались до извлечения внутренних архивов. Публичный канал не изменялся, а release candidate не был создан. + +Builder r2: + +- создаёт оба каталога до независимой распаковки; +- исключает бинарный Xray из чтения shebang через command substitution; +- использует отдельный candidate-id `r2`; +- прошёл `bash -n`, изолированный тест вложенной распаковки и тест отсутствия NUL-предупреждений. + +Файл серверного builder: + +```text +BROray-2.2.6-release-candidate-builder-r2.sh +``` + +SHA-256: + +```text +759386247553adc0d1ee64e43bc53c8606c5aa88a5d0c6a72a9674e09660c0c3 +``` + ## Порядок выпуска -1. На сервере собрать кандидат скриптом `scripts/build-release-candidate-2.2.6.sh` из точных файлов отозванного 2.2.5 в карантине. +1. На сервере собрать candidate r2 из точных файлов отозванного 2.2.5 в карантине. 2. Сверить внутренний `SHA256SUMS` и внешний SHA архива кандидата. -3. Опубликовать кандидат только в `/releases/staging/broray/2.2.6-r1/`. +3. Опубликовать candidate только в `/releases/staging/broray/2.2.6-r2/`. 4. Подготовить тестовый роутер к staging и запустить установку исключительно из WebUI. 5. Выполнить матрицу из [`FIELD-TEST-2.2.6.md`](FIELD-TEST-2.2.6.md). 6. После `PASS` продвинуть точные байты без пересборки; затем обновить документацию, GitHub tag и release notes. From f93cbc39ae230747c36d4e6e3dc455213f923299 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:04:18 +0300 Subject: [PATCH 10/25] Use robust r3 release candidate builder --- scripts/run-release-candidate-builder-2.2.6.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index 6945672..491cb89 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r2.sh" -EXPECTED="759386247553adc0d1ee64e43bc53c8606c5aa88a5d0c6a72a9674e09660c0c3" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r3.sh" +EXPECTED="226e5bd894c1eade64cc5507dc12b4a5c0763f4fa243a6dc205961a1cfe5ca9f" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r2" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r3" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then From 131e269208d242185d4b55820f47568b6ef5c26b Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:15:39 +0300 Subject: [PATCH 11/25] Use BROray 2.2.6 candidate builder r4 --- scripts/run-release-candidate-builder-2.2.6.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index 491cb89..fb2b65e 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r3.sh" -EXPECTED="226e5bd894c1eade64cc5507dc12b4a5c0763f4fa243a6dc205961a1cfe5ca9f" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r4.sh" +EXPECTED="6b142780a43fd7649977e729939f5650ac06b343cd1a5f3be610e87fd786b565" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r3" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r4" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then From 8b5b093090a88466894828f2a6628cae5e3ac67b Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:16:01 +0300 Subject: [PATCH 12/25] Document BROray 2.2.6 candidate r4 --- docs/RELEASE-2.2.6.md | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/docs/RELEASE-2.2.6.md b/docs/RELEASE-2.2.6.md index 4fb4459..ee4de46 100644 --- a/docs/RELEASE-2.2.6.md +++ b/docs/RELEASE-2.2.6.md @@ -6,6 +6,14 @@ BROray 2.2.6 подготовлен как **неизменяемый release ca Публичное продвижение 2.2.6 разрешено только после физического теста тех же байтов через WebUI и итогового отчёта `PASS`. +Кандидаты `r1`, `r2` и `r3` не являются допустимыми для полевого теста: + +- `r1` не завершил независимую распаковку IPK; +- `r2` не смог устойчиво преобразовать реальный блок `opkg install`; +- `r3` собрал и опубликовал staging, но внешний compatibility repair сохранил старый ожидаемый SHA пакета и поэтому отклонил бы правильный IPK 2.2.6. + +Текущий кандидат — **r4**. Он встраивает в compatibility repair точные `SHA256sum` и `Filename` собранного IPK и повторно проверяет эти значения до упаковки. + ## Причины выпуска BROray 2.2.5 был отозван после реального теста на роутере с версией `2.2.0-2`: @@ -15,7 +23,7 @@ BROray 2.2.5 был отозван после реального теста на 3. пользователю показывалась общая ошибка OPKG без полезного хвоста `preinst`/`postinst`; 4. серверная публикация первоначально выдала `.sh` с правами `0700`, из-за чего Nginx отвечал `403`. -## Исправления 2.2.6 +## Исправления - два явных допустимых формата backup; - `return 0` после успешного учёта служб; @@ -23,36 +31,14 @@ BROray 2.2.5 был отозван после реального теста на - полный журнал OPKG до отката; - staging-публикация с внешней HTTP/SHA-проверкой; - права публичных статических файлов `0644`; +- compatibility repair содержит точные SHA-256 и Filename candidate IPK; - правила релиза 1.3 и запрет пересборки после field test. -## Candidate builder r2 - -Первая попытка builder r1 была безопасно остановлена независимой проверкой распаковки: каталоги `check/control` и `check/data` не создавались до извлечения внутренних архивов. Публичный канал не изменялся, а release candidate не был создан. - -Builder r2: - -- создаёт оба каталога до независимой распаковки; -- исключает бинарный Xray из чтения shebang через command substitution; -- использует отдельный candidate-id `r2`; -- прошёл `bash -n`, изолированный тест вложенной распаковки и тест отсутствия NUL-предупреждений. - -Файл серверного builder: - -```text -BROray-2.2.6-release-candidate-builder-r2.sh -``` - -SHA-256: - -```text -759386247553adc0d1ee64e43bc53c8606c5aa88a5d0c6a72a9674e09660c0c3 -``` - ## Порядок выпуска -1. На сервере собрать candidate r2 из точных файлов отозванного 2.2.5 в карантине. +1. На сервере собрать кандидат builder r4 из точных файлов отозванного 2.2.5 в карантине. 2. Сверить внутренний `SHA256SUMS` и внешний SHA архива кандидата. -3. Опубликовать candidate только в `/releases/staging/broray/2.2.6-r2/`. +3. Опубликовать кандидат только в `/releases/staging/broray/2.2.6-r4/`. 4. Подготовить тестовый роутер к staging и запустить установку исключительно из WebUI. 5. Выполнить матрицу из [`FIELD-TEST-2.2.6.md`](FIELD-TEST-2.2.6.md). 6. После `PASS` продвинуть точные байты без пересборки; затем обновить документацию, GitHub tag и release notes. From 55730813cf8990861f080ece66b0824b9ccf8903 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 15:38:59 +0300 Subject: [PATCH 13/25] Point release runner to candidate r5 --- scripts/run-release-candidate-builder-2.2.6.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index fb2b65e..fd64981 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r4.sh" -EXPECTED="6b142780a43fd7649977e729939f5650ac06b343cd1a5f3be610e87fd786b565" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r5.sh" +EXPECTED="c10075605fd4c7c9d326c1a455b5a018bcbb3b2835ffb20afcbe04dd6bf645be" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r4" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r5" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -40,7 +40,8 @@ fi echo echo "Код завершения: $RESULT" -echo "Публичный стабильный канал не должен изменяться на этапе сборки кандидата." +echo "Публичный stable-канал не изменяется при сборке кандидата." +echo "Candidate r5 требует обновления и двух переустановок через WebUI до продвижения." echo "Терминал остаётся открытым." echo "==================================================" exit "$RESULT" From f7b95dcf87ac13ee357b016cf1bd0dbb4de2655d Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 15:45:51 +0300 Subject: [PATCH 14/25] Fix candidate r6 builder identity check --- scripts/run-release-candidate-builder-2.2.6.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index fd64981..5d2abb9 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r5.sh" -EXPECTED="c10075605fd4c7c9d326c1a455b5a018bcbb3b2835ffb20afcbe04dd6bf645be" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r6.sh" +EXPECTED="8814fff3ea3649653d6ddf9d9cca62dc8a114d97bc72d83351ed62d5eb0072e6" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r5" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r6" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -41,7 +41,7 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r5 требует обновления и двух переустановок через WebUI до продвижения." +echo "Candidate r6 требует обновления и двух переустановок через WebUI до продвижения." echo "Терминал остаётся открытым." echo "==================================================" exit "$RESULT" From 9138d35023a54aca9cf085242098113bf52b7157 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 16:23:57 +0300 Subject: [PATCH 15/25] Point 2.2.6 candidate runner to r7 --- scripts/run-release-candidate-builder-2.2.6.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index 5d2abb9..ca9abbb 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r6.sh" -EXPECTED="8814fff3ea3649653d6ddf9d9cca62dc8a114d97bc72d83351ed62d5eb0072e6" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r7.sh" +EXPECTED="df7d5f2afa2645e369b5cdd5f74cff4dd3781da2f2e6dc2faf1cc91e398c24f5" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r6" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r7" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -41,7 +41,7 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r6 требует обновления и двух переустановок через WebUI до продвижения." +echo "Candidate r7 требует обновления, проверки непрерывного прогресса и двух переустановок через WebUI до продвижения." echo "Терминал остаётся открытым." echo "==================================================" exit "$RESULT" From 96d6f77e56fe11ae19f72a2148b3e00d7cde5199 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 16:50:14 +0300 Subject: [PATCH 16/25] Point BROray 2.2.6 candidate runner to r8 --- scripts/run-release-candidate-builder-2.2.6.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index ca9abbb..ffe9737 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r7.sh" -EXPECTED="df7d5f2afa2645e369b5cdd5f74cff4dd3781da2f2e6dc2faf1cc91e398c24f5" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r8.sh" +EXPECTED="6f65c7b81a690c50bf6cd2856f52dcf05e4b0ef759e01a913452aca5e0d81a27" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r7" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r8" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -41,7 +41,7 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r7 требует обновления, проверки непрерывного прогресса и двух переустановок через WebUI до продвижения." +echo "Candidate r8 требует проверки расположения карточки, непрерывного прогресса и двух переустановок через WebUI до продвижения." echo "Терминал остаётся открытым." echo "==================================================" exit "$RESULT" From 948f3b1f1579eef9c74eb661aaa493cf279d4bba Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:26:59 +0300 Subject: [PATCH 17/25] Point 2.2.6 release runner to candidate r9 --- scripts/run-release-candidate-builder-2.2.6.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index ffe9737..b25493f 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r8.sh" -EXPECTED="6f65c7b81a690c50bf6cd2856f52dcf05e4b0ef759e01a913452aca5e0d81a27" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r9.sh" +EXPECTED="eb73a5acd050570b72f1da234eea199e9fa1501a1cc27f6789347550ef0af82e" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r8" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r9" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -41,7 +41,7 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r8 требует проверки расположения карточки, непрерывного прогресса и двух переустановок через WebUI до продвижения." +echo "Candidate r9 требует проверки singleton S28, пустого error при успехе и двух переустановок через WebUI до продвижения." echo "Терминал остаётся открытым." echo "==================================================" exit "$RESULT" From 14f19e0b5511146fcfe1994e224c4ec74fd4b665 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:12:12 +0300 Subject: [PATCH 18/25] release: point 2.2.6 candidate runner to r10 --- scripts/run-release-candidate-builder-2.2.6.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index b25493f..f3110a8 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r9.sh" -EXPECTED="eb73a5acd050570b72f1da234eea199e9fa1501a1cc27f6789347550ef0af82e" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r10.sh" +EXPECTED="30b68b51e44faf536109c4eae23fae5a730cf923ec4d4740aa5eab0b5d57d5ff" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r9" +printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r10" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -41,7 +41,7 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r9 требует проверки singleton S28, пустого error при успехе и двух переустановок через WebUI до продвижения." +echo "Candidate r10 использует потоковую low-RAM переустановку, старое дерево для отката, прямой снимок в /opt и требует двух физических переустановок через WebUI до продвижения." echo "Терминал остаётся открытым." echo "==================================================" exit "$RESULT" From 27a8c7ab54acfa36036d8bc1de4ba525c94034f9 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Fri, 31 Jul 2026 23:31:19 +0300 Subject: [PATCH 19/25] release: switch 2.2.6 candidate runner to universal r11 --- scripts/run-release-candidate-builder-2.2.6.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index f3110a8..164f87e 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r10.sh" -EXPECTED="30b68b51e44faf536109c4eae23fae5a730cf923ec4d4740aa5eab0b5d57d5ff" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r11.sh" +EXPECTED="851cf1bd62e67fb05dcbf2350302405947737d498a801b8ced7c9cf4e7dae67a" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного candidate builder r10" +printf '%s\n' "BROray 2.2.6 — запуск universal candidate builder r11" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -41,7 +41,8 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r10 использует потоковую low-RAM переустановку, старое дерево для отката, прямой снимок в /opt и требует двух физических переустановок через WebUI до продвижения." +echo "Candidate r11 определяет исходную версию динамически, не требует прежний IPK и выполняет локальный rollback дерева, OPKG metadata, внешних файлов и служб." +echo "Продвижение запрещено до физической матрицы 2.1.1-2, 2.2.0-2, 2.2.4, 2.2.5, принудительного rollback и повторного обновления." echo "Терминал остаётся открытым." echo "==================================================" exit "$RESULT" From c64e81e50f25e87c6342f9381b0999088b153cc0 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Sat, 1 Aug 2026 00:08:19 +0300 Subject: [PATCH 20/25] release: switch 2.2.6 candidate runner to data-safe r12 --- scripts/run-release-candidate-builder-2.2.6.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index 164f87e..2f9f7b0 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r11.sh" -EXPECTED="851cf1bd62e67fb05dcbf2350302405947737d498a801b8ced7c9cf4e7dae67a" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r12.sh" +EXPECTED="203b9e52b37f18f81d76514bbfafa6be8e4b8cef4e012acbad75fe6a8d7ab5bc" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск universal candidate builder r11" +printf '%s\n' "BROray 2.2.6 — запуск universal candidate builder r12" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -41,8 +41,9 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r11 определяет исходную версию динамически, не требует прежний IPK и выполняет локальный rollback дерева, OPKG metadata, внешних файлов и служб." -echo "Продвижение запрещено до физической матрицы 2.1.1-2, 2.2.0-2, 2.2.4, 2.2.5, принудительного rollback и повторного обновления." +echo "Candidate r12 определяет исходную версию динамически, не требует прежний IPK, сохраняет все непакетные пользовательские файлы и выполняет локальный rollback дерева, OPKG metadata, внешних файлов и служб." +echo "Публикатор r12 нормализует каталоги staging в 0755 и файлы в 0644." +echo "Продвижение запрещено до физической матрицы, принудительного rollback, проверки backup/logs/quality/custom и двух повторных переустановок." echo "Терминал остаётся открытым." echo "==================================================" exit "$RESULT" From e31c95ed04a6fcdfae7d2be2a622fc348da834bd Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Sat, 1 Aug 2026 02:52:56 +0300 Subject: [PATCH 21/25] release: switch 2.2.6 candidate runner to validated universal r13 --- scripts/run-release-candidate-builder-2.2.6.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index 2f9f7b0..2561c19 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r12.sh" -EXPECTED="203b9e52b37f18f81d76514bbfafa6be8e4b8cef4e012acbad75fe6a8d7ab5bc" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r13.sh" +EXPECTED="3a6925cb2451b86904b68445b5cdcdb18e1326b8db99d3437c035420ada5baab" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск universal candidate builder r12" +printf '%s\n' "BROray 2.2.6 — запуск проверенного universal candidate builder r13" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -41,9 +41,10 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r12 определяет исходную версию динамически, не требует прежний IPK, сохраняет все непакетные пользовательские файлы и выполняет локальный rollback дерева, OPKG metadata, внешних файлов и служб." -echo "Публикатор r12 нормализует каталоги staging в 0755 и файлы в 0644." -echo "Продвижение запрещено до физической матрицы, принудительного rollback, проверки backup/logs/quality/custom и двух повторных переустановок." +echo "Candidate r13 определяет исходную версию динамически, не требует прежний IPK и сохраняет все непакетные пользовательские файлы." +echo "Обязательный транзакционный rollback действует всегда; постоянная пользовательская копия выбирается отдельно: keep или skip." +echo "Keep рекомендован для USB/достаточного накопителя; skip допускается при ограниченной внутренней памяти после preflight." +echo "Продвижение запрещено до staging, физической матрицы исходных версий, forced rollback, keep/skip и двух повторных переустановок." echo "Терминал остаётся открытым." echo "==================================================" exit "$RESULT" From e9139687ce87ef7f4f6574b1276a90ed8049ac0b Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Sat, 1 Aug 2026 09:07:33 +0300 Subject: [PATCH 22/25] release: switch 2.2.6 candidate runner to validated r14 --- .../run-release-candidate-builder-2.2.6.sh | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index 2561c19..d5834f3 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r13.sh" -EXPECTED="3a6925cb2451b86904b68445b5cdcdb18e1326b8db99d3437c035420ada5baab" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r14.sh" +EXPECTED="295e074bedd22465686c2031915ee2cdf044a850bf6d931a9cf9bea708dcef19" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного universal candidate builder r13" +printf '%s\n' "BROray 2.2.6 — запуск проверенного universal candidate builder r14" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -21,10 +21,15 @@ fi if [ "$READY" = yes ]; then ACTUAL="$(sha256sum "$BUILDER" 2>/dev/null | awk '{print $1}')" + SIZE="$(stat -c '%s' "$BUILDER" 2>/dev/null)" echo "SHA-256: $ACTUAL" + echo "Размер: $SIZE" if [ "$ACTUAL" != "$EXPECTED" ]; then echo "ОШИБКА: SHA-256 builder не совпадает" READY=no + elif [ "$SIZE" != "173401" ]; then + echo "ОШИБКА: размер builder не совпадает" + READY=no elif ! bash -n "$BUILDER"; then echo "ОШИБКА: builder не прошёл bash -n" READY=no @@ -32,6 +37,14 @@ if [ "$READY" = yes ]; then fi if [ "$READY" = yes ]; then + unset BRORAY_BUILDER_TEST_MODE \ + BRORAY_BUILDER_TEST_SOURCE_IPK \ + BRORAY_BUILDER_TEST_SOURCE_SHA \ + BRORAY_BUILDER_TEST_SOURCE_SIZE \ + BRORAY_BUILDER_PUBLIC_ROOT \ + BRORAY_BUILDER_BUILD_ROOT \ + BRORAY_BUILDER_OUT \ + BRORAY_BUILDER_ARCHIVE bash "$BUILDER" RESULT=$? else @@ -41,9 +54,9 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r13 определяет исходную версию динамически, не требует прежний IPK и сохраняет все непакетные пользовательские файлы." -echo "Обязательный транзакционный rollback действует всегда; постоянная пользовательская копия выбирается отдельно: keep или skip." -echo "Keep рекомендован для USB/достаточного накопителя; skip допускается при ограниченной внутренней памяти после preflight." +echo "Candidate r14 определяет исходную версию динамически и не требует прежний IPK." +echo "Обязательный транзакционный rollback действует всегда; постоянная копия выбирается отдельно: keep или skip." +echo "Exact preinst-модель использует явно проверенный tar и не зависит от постороннего /opt/bin/tar release-сервера." echo "Продвижение запрещено до staging, физической матрицы исходных версий, forced rollback, keep/skip и двух повторных переустановок." echo "Терминал остаётся открытым." echo "==================================================" From b3db0ed06d9119fb44f399ac97c57160fc000f26 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Sat, 1 Aug 2026 10:38:40 +0300 Subject: [PATCH 23/25] release: switch 2.2.6 candidate runner to validated r15 --- scripts/run-release-candidate-builder-2.2.6.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index d5834f3..93765f9 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,12 +1,13 @@ #!/usr/bin/env bash set -u -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r14.sh" -EXPECTED="295e074bedd22465686c2031915ee2cdf044a850bf6d931a9cf9bea708dcef19" +BUILDER="/root/BROray-2.2.6-release-candidate-builder-r15.sh" +EXPECTED="851f9c1f44e97271bf626421bc93b53bb0f06008a90ac23c803f5aaf4251b045" +EXPECTED_SIZE="198955" READY=yes printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного universal candidate builder r14" +printf '%s\n' "BROray 2.2.6 — запуск проверенного universal candidate builder r15" printf '%s\n' "==================================================" if [ "$(id -u)" -ne 0 ]; then @@ -27,7 +28,7 @@ if [ "$READY" = yes ]; then if [ "$ACTUAL" != "$EXPECTED" ]; then echo "ОШИБКА: SHA-256 builder не совпадает" READY=no - elif [ "$SIZE" != "173401" ]; then + elif [ "$SIZE" != "$EXPECTED_SIZE" ]; then echo "ОШИБКА: размер builder не совпадает" READY=no elif ! bash -n "$BUILDER"; then @@ -54,9 +55,11 @@ fi echo echo "Код завершения: $RESULT" echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r14 определяет исходную версию динамически и не требует прежний IPK." -echo "Обязательный транзакционный rollback действует всегда; постоянная копия выбирается отдельно: keep или skip." -echo "Exact preinst-модель использует явно проверенный tar и не зависит от постороннего /opt/bin/tar release-сервера." +echo "Candidate r15 определяет исходную версию динамически и не требует прежний IPK." +echo "Перед измерением удаляются только временные транзакции; постоянные архивы не удаляются, access.log ограничивается 16 МиБ." +echo "Место обязательной транзакции и keep рассчитывается отдельно; skip не вызывает оценку постоянной копии." +echo "Размер определяется через wc/readlink без stat, с тремя попытками и точным путём ошибки." +echo "Любой preflight-stop автоматически снимает compatibility overlay и возвращает исходные backend, JavaScript, CGI и wrapper." echo "Продвижение запрещено до staging, физической матрицы исходных версий, forced rollback, keep/skip и двух повторных переустановок." echo "Терминал остаётся открытым." echo "==================================================" From cba47d4b40a29eb85611fb28b47a32e65f44cdbc Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Sat, 1 Aug 2026 16:58:44 +0300 Subject: [PATCH 24/25] docs: add BROray 2.2.6 release error register --- docs/RELEASE-2.2.6-ERROR-REGISTER.md | 234 +++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 docs/RELEASE-2.2.6-ERROR-REGISTER.md diff --git a/docs/RELEASE-2.2.6-ERROR-REGISTER.md b/docs/RELEASE-2.2.6-ERROR-REGISTER.md new file mode 100644 index 0000000..e0a81e2 --- /dev/null +++ b/docs/RELEASE-2.2.6-ERROR-REGISTER.md @@ -0,0 +1,234 @@ +# BROray 2.2.6 — реестр ошибок и обязательных защит + +Этот документ является блокирующим реестром релиза BROray 2.2.6. Он фиксирует обнаруженные дефекты, причины отклонения кандидатов и проверки, которые обязаны предотвращать повторение тех же ошибок. + +## Подтверждённое безопасное состояние + +- стабильный публичный канал: BROray `2.2.4`, WebUI `WebUI-2.2.0-r2`; +- SHA-256 stable `Packages`: `8e37d0f02825056fe96b267548cfc09836f911d1bf9c7d0b735ebdc6576256ea`; +- SHA-256 stable `Packages.gz`: `083521021e13975c2d63959ca6678a5d0fca6bf1eb9fe46eefda1bb3827067da`; +- тестовый роутер после очистки: BROray/OPKG `2.2.5`, Xray config OK, WebUI HTTP 200, один процесс S28; +- обязательный production source r10: `/root/BROray-2.2.6-candidate-r10/broray_2.2.6_aarch64-3.10.ipk`; +- SHA-256 production source r10: `c0bc9a8d0c17afe4987989a24ab03ed906e0c4acb5169a5216334e6548b3f9e2`; +- размер production source r10: `13997155` байт. + +Ни один кандидат не может менять stable до отдельного решения о продвижении уже проверенных неизменяемых байтов. + +## Хронология отклонённых кандидатов + +### r4 — разрушительная переустановка той же версии + +Симптом: после WebUI-переустановки OPKG оставался зарегистрирован как 2.2.6, но программный payload, Xray и службы исчезали. + +Причина: `opkg --force-reinstall` возвращал ненулевой код из-за предупреждений conffile; worker воспринимал это как провал, запускал второй reinstall как откат и не восстанавливал полный snapshot. + +Обязательная защита: + +- same-version reinstall не должен полагаться на повторный `opkg --force-reinstall`; +- старое дерево сохраняется до полной проверки нового payload; +- forced failure после переименования старого дерева обязан вернуть payload и службы. + +### r6–r8 — прогресс, DOM и неполная диагностика + +Обнаружены зависание прогресса, некорректное расположение карточки, ошибочная трактовка пути резервной копии как поля `error` и неполная проверка результата. + +Обязательная защита: + +- успешная операция завершается `state=success`, `stage=complete`, `progress=100`, `running=false`, пустым `error`; +- WebUI продолжает polling после временного исчезновения backend; +- информационные сообщения не записываются в `error`; +- DOM-якоря проверяются на фактической структуре страницы. + +### r8–r9 — несколько процессов S28 + +Симптом: init-скрипт сообщал `stopped`, хотя несколько процессов scheduler продолжали работать; ручной start создавал ещё один процесс. + +Обязательная защита: + +- S28 должен обнаруживать все процессы по точной командной строке; +- stop удаляет все старые процессы и PID-файлы; +- start/restart оставляет ровно один процесс; +- PID-файл обязан соответствовать единственному живому процессу; +- проверка выполняется сразу, через 10 и через 30 секунд. + +### r9 — полный архив в `/tmp` + +Симптом: транзакция остановилась при создании полного снимка в `/tmp`. + +Причина: `/tmp` является tmpfs/RAM; одновременно хранились пакет, распаковка и архив. + +Обязательная защита: + +- полный payload и полный резервный архив не создаются в `/tmp`; +- обязательный rollback использует атомарно переименованное старое дерево на том же filesystem; +- `/tmp` хранит только небольшие служебные файлы. + +### r10 — зависимость от IPK исходной версии + +Симптом: обновление с 2.2.5 остановилось, потому что staging не содержал точный IPK 2.2.5 для возврата. + +Причина: compatibility repair был привязан к набору прежних пакетов. + +Обязательная защита: + +- исходная версия определяется динамически через OPKG; +- allowlist исходных версий запрещён; +- previous-version IPK не требуется; +- rollback сохраняет локальное дерево, OPKG status/info, внешние пакетные файлы и состояние служб. + +### r11 — потеря unmanaged-файлов + +Симптом: success-path восстанавливал только фиксированный перечень `config`, `data`, `subscriptions`, `servers`, `routes`. + +Риск: могли исчезнуть `backup`, `logs`, `quality` и будущие пользовательские каталоги. + +Обязательная защита: + +- пользовательские данные определяются как все непакетные файлы и conffiles, а не фиксированный список каталогов; +- неизвестные будущие каталоги сохраняются; +- старые программные файлы не накладываются поверх нового payload; +- конфликт пользовательского пути с новым пакетным путём блокирует транзакцию до изменений. + +### r11 — права staging + +Симптом: локальная публикация прошла, публичный URL возвращал 404. + +Причина: каталоги staging получили mode 0700 при `umask 077`; nginx не мог пройти по дереву. + +Обязательная защита: + +- publisher принудительно устанавливает каталогам 0755, файлам 0644, владельца `root:root`; +- после локальной проверки обязательна внешняя HTTP-загрузка каждого файла и сравнение SHA-256. + +### r12 — валидатор проверял несуществующий путь + +Симптом: кандидат отклонён проверкой `preinst`, хотя валидатор искал его вне распакованного IPK. + +Обязательная защита: + +- независимый валидатор распаковывает итоговый IPK; +- проверяет реальные `control`, `preinst`, `postinst`; +- шаблоны и экспортированные standalone-файлы не заменяют проверку пакетных байтов. + +### r13 — тестовая модель не соответствовала release-среде + +Симптом: exact-preinst модель выбрала неподходящий `/opt/bin/tar` на release-сервере. + +Обязательная защита: + +- тестовый tar задаётся явно; +- runtime Keenetic выбирает проверенный `/opt/bin/tar` с безопасным fallback; +- exact-preinst исполняется на финальном пакете в изолированном PATH. + +### r14 — общий порог места для keep/skip + +Симптом: `keep` и `skip` блокировались одним порогом 42000 КБ. + +Обязательная защита: + +- место обязательной транзакции рассчитывается отдельно; +- дополнительное место постоянной копии `keep` рассчитывается отдельно; +- `skip` не запускает оценку persistent backup; +- если не помещается только `keep`, пользователь получает предложение перейти на `skip`; +- если не помещается транзакция, сообщается, что `skip` не поможет. + +### r14 — старый мусор и разросшийся access.log + +Фактический `access.log` вырос до `121594840` байт и занял существенную часть внутреннего накопителя. + +Обязательная защита: + +- до измерения места удаляются только подтверждённые завершённые временные транзакции, `.part`, `.tmp`, временные IPK и OPKG-кэш; +- активный snapshot и аварийные деревья защищены; +- постоянные пользовательские архивы автоматически не удаляются; +- технический `access.log` обнуляется только после превышения фиксированного безопасного лимита; +- после cleanup место измеряется повторно. + +### r14 — зависимость оценщика от `stat` + +Симптом: ветка `keep` не смогла оценить размер дополнительной копии; конкретный путь не сообщался. + +Обязательная защита: + +- обычные файлы измеряются через `wc -c`; +- ссылки — через `readlink` и `wc -c`; +- `stat` запрещён внутри portable size estimator; +- выполняются три попытки; +- исчезнувший или изменившийся файл возвращает точный `relative/path|reason`; +- модель исполняется в PATH без `stat`. + +### r14 — неполный возврат compatibility overlay после preflight-stop + +После безопасной остановки требовалась ручная очистка и проверка восстановленных файлов. + +Обязательная защита: + +- каждый отказ до snapshot синхронно восстанавливает backend, WebUI JS, CGI, system wrapper и исходный feed; +- marker и временный compatibility snapshot удаляются только после проверки восстановления; +- cache OPKG инвалидируется после возврата feed; +- ошибка restore не скрывается исходной ошибкой preflight. + +### r15 — mock-only PASS и неинициализированный runtime + +Симптом production-сборки: + +```text +ash: can't create .../base/run/broray/update.json: nonexistent directory +``` + +Причина: mock-IPK сохранял тестовый путь cache, а production backend после source переопределял его под `$BRORAY_BASE/run/broray/update.json`; модель не создала каталог после инициализации настоящего backend. + +Обязательная защита: + +- mock-тест не является production-доказательством; +- все runtime-пути создаются и проверяются после source настоящего production backend; +- модели исполняются на backend, извлечённом из exact production source; +- stdout/stderr неуспешной ветки сохраняются; +- первый отсутствующий путь выводится явно. + +## Дополнительные инварианты безопасности + +### Пути и архивы + +- абсолютные пути и `..` запрещены; +- управляющие символы в путях запрещены; +- имена с начальным `-` обрабатываются безопасно; +- небезопасные symlink targets блокируются до mutation; +- metadata persistent backup (`.broray-user-backup-v3`, `manifest.json`) не могут пересекаться с пользовательскими путями; +- дублированные и неканонические члены архива запрещены; +- metadata обязана быть обычными файлами, не symlink. + +### OPKG и feed + +- прямой `opkg upgrade broray` без валидного локального snapshot блокируется `preinst`; +- сохранённая sourceVersion сверяется с OPKG registration, но не сравнивается с allowlist; +- исходный feed может быть обычным файлом, отсутствовать или быть symlink; +- восстановление feed атомарное и проверяемое; +- staging содержит одну запись BROray и один IPK кандидата. + +### Резервные копии + +- обязательный транзакционный rollback всегда включён; +- persistent backup — отдельный выбор `keep`/`skip`; +- `keep` включён по умолчанию и рекомендован для USB/достаточного накопителя; +- `skip` не отключает автоматический rollback; +- пользовательские постоянные архивы не удаляются без явного выбора; +- `last-backup` сохраняется только если указывает на реально существующий валидный архив. + +## Полные release gates + +Перед передачей следующего production-кандидата обязательны: + +1. точный source r10 с утверждёнными SHA-256 и размером; +2. три чистые production-сборки A/B/C в `env -i` и независимых каталогах; +3. побайтовое совпадение деревьев, IPK, архивов, `Packages`, `Packages.gz` и всех helper-файлов; +4. независимый валидатор, не использующий логику builder как источник истины; +5. финальная холодная распаковка копии результата в другом parent-каталоге; +6. негативные mutation controls для top-level, staging, symlink, duplicate archive member и специальных mode bits; +7. `bash -n`, BusyBox `ash -n`, `node --check`, JSON, tar/gzip и реальный IPK control/preinst/postinst; +8. модели keep, skip, transaction-insufficient, keep-only-insufficient, no-stat, disappearing/changing file, internal storage, USB, forced rollback, feed restore и S28 singleton; +9. подтверждение неизменности stable и защищённого staging; +10. отдельная staging-публикация и только затем физическая матрица Keenetic; +11. stable promotion только тех же неизменяемых байтов после полного field-test PASS. + +Любой FAIL отклоняет байты. Исправление требует нового кандидата и повторения всего цикла с нуля. \ No newline at end of file From 85382c4a02989f50dbe5bf06a8506c0f7405ae64 Mon Sep 17 00:00:00 2001 From: BROadmin <307129396+BROadmin@users.noreply.github.com> Date: Sat, 1 Aug 2026 17:15:17 +0300 Subject: [PATCH 25/25] release: replace rejected r15 runner with r41 full-control gate --- .../run-release-candidate-builder-2.2.6.sh | 132 ++++++++++-------- 1 file changed, 76 insertions(+), 56 deletions(-) diff --git a/scripts/run-release-candidate-builder-2.2.6.sh b/scripts/run-release-candidate-builder-2.2.6.sh index 93765f9..14028b4 100644 --- a/scripts/run-release-candidate-builder-2.2.6.sh +++ b/scripts/run-release-candidate-builder-2.2.6.sh @@ -1,66 +1,86 @@ #!/usr/bin/env bash -set -u +set -Eeuo pipefail +umask 077 +export LC_ALL=C -BUILDER="/root/BROray-2.2.6-release-candidate-builder-r15.sh" -EXPECTED="851f9c1f44e97271bf626421bc93b53bb0f06008a90ac23c803f5aaf4251b045" -EXPECTED_SIZE="198955" -READY=yes +CONTROLLER="/root/BROray-2.2.6-full-control-production-r41.sh" +EXPECTED_CONTROLLER_SHA="1807bd06eb7e5dd329d65dab2fcba5209f08989b00289a27c0eedbf01aff6921" +EXPECTED_CONTROLLER_SIZE="424919" + +SOURCE_IPK="/root/BROray-2.2.6-candidate-r10/broray_2.2.6_aarch64-3.10.ipk" +EXPECTED_SOURCE_SHA="c0bc9a8d0c17afe4987989a24ab03ed906e0c4acb5169a5216334e6548b3f9e2" +EXPECTED_SOURCE_SIZE="13997155" + +STABLE_PACKAGES="/var/www/api.brovibe.cloud/releases/opkg/aarch64-3.10/Packages" +STABLE_PACKAGES_GZ="${STABLE_PACKAGES}.gz" +EXPECTED_STABLE_SHA="8e37d0f02825056fe96b267548cfc09836f911d1bf9c7d0b735ebdc6576256ea" +EXPECTED_STABLE_GZ_SHA="083521021e13975c2d63959ca6678a5d0fca6bf1eb9fe46eefda1bb3827067da" + +fail() { + printf '\nОШИБКА: %s\n' "$*" >&2 + printf 'Stable и staging не изменялись этой командой.\n' >&2 + exit 1 +} + +sha_of() { + sha256sum "$1" | awk '{print $1}' +} + +size_of() { + wc -c <"$1" | tr -d ' ' +} printf '%s\n' "==================================================" -printf '%s\n' "BROray 2.2.6 — запуск проверенного universal candidate builder r15" +printf '%s\n' "BROray 2.2.6 — exact production full-control r41" printf '%s\n' "==================================================" -if [ "$(id -u)" -ne 0 ]; then - echo "ОШИБКА: требуется root" - READY=no -fi +[ "$(id -u)" -eq 0 ] || fail "требуется root" -if [ ! -f "$BUILDER" ]; then - echo "ОШИБКА: файл не найден: $BUILDER" - READY=no -fi +for command_name in bash busybox node python3 tar gzip sha256sum awk find sort stat cmp jq env wc tr; do + command -v "$command_name" >/dev/null 2>&1 || fail "не найдена команда $command_name" +done -if [ "$READY" = yes ]; then - ACTUAL="$(sha256sum "$BUILDER" 2>/dev/null | awk '{print $1}')" - SIZE="$(stat -c '%s' "$BUILDER" 2>/dev/null)" - echo "SHA-256: $ACTUAL" - echo "Размер: $SIZE" - if [ "$ACTUAL" != "$EXPECTED" ]; then - echo "ОШИБКА: SHA-256 builder не совпадает" - READY=no - elif [ "$SIZE" != "$EXPECTED_SIZE" ]; then - echo "ОШИБКА: размер builder не совпадает" - READY=no - elif ! bash -n "$BUILDER"; then - echo "ОШИБКА: builder не прошёл bash -n" - READY=no - fi -fi +[ -s "$CONTROLLER" ] || fail "контроллер отсутствует: $CONTROLLER" +[ "$(sha_of "$CONTROLLER")" = "$EXPECTED_CONTROLLER_SHA" ] || fail "SHA-256 контроллера не совпадает" +[ "$(size_of "$CONTROLLER")" = "$EXPECTED_CONTROLLER_SIZE" ] || fail "размер контроллера не совпадает" +bash -n "$CONTROLLER" || fail "контроллер не прошёл bash -n" -if [ "$READY" = yes ]; then - unset BRORAY_BUILDER_TEST_MODE \ - BRORAY_BUILDER_TEST_SOURCE_IPK \ - BRORAY_BUILDER_TEST_SOURCE_SHA \ - BRORAY_BUILDER_TEST_SOURCE_SIZE \ - BRORAY_BUILDER_PUBLIC_ROOT \ - BRORAY_BUILDER_BUILD_ROOT \ - BRORAY_BUILDER_OUT \ - BRORAY_BUILDER_ARCHIVE - bash "$BUILDER" - RESULT=$? -else - RESULT=1 -fi +[ -s "$SOURCE_IPK" ] || fail "точный production source r10 отсутствует" +[ "$(sha_of "$SOURCE_IPK")" = "$EXPECTED_SOURCE_SHA" ] || fail "SHA-256 production source r10 не совпадает" +[ "$(size_of "$SOURCE_IPK")" = "$EXPECTED_SOURCE_SIZE" ] || fail "размер production source r10 не совпадает" +tar -tzf "$SOURCE_IPK" >/dev/null 2>&1 || fail "production source r10 не читается" -echo -echo "Код завершения: $RESULT" -echo "Публичный stable-канал не изменяется при сборке кандидата." -echo "Candidate r15 определяет исходную версию динамически и не требует прежний IPK." -echo "Перед измерением удаляются только временные транзакции; постоянные архивы не удаляются, access.log ограничивается 16 МиБ." -echo "Место обязательной транзакции и keep рассчитывается отдельно; skip не вызывает оценку постоянной копии." -echo "Размер определяется через wc/readlink без stat, с тремя попытками и точным путём ошибки." -echo "Любой preflight-stop автоматически снимает compatibility overlay и возвращает исходные backend, JavaScript, CGI и wrapper." -echo "Продвижение запрещено до staging, физической матрицы исходных версий, forced rollback, keep/skip и двух повторных переустановок." -echo "Терминал остаётся открытым." -echo "==================================================" -exit "$RESULT" +[ -s "$STABLE_PACKAGES" ] || fail "stable Packages отсутствует" +[ -s "$STABLE_PACKAGES_GZ" ] || fail "stable Packages.gz отсутствует" +[ "$(sha_of "$STABLE_PACKAGES")" = "$EXPECTED_STABLE_SHA" ] || fail "stable Packages изменён" +[ "$(sha_of "$STABLE_PACKAGES_GZ")" = "$EXPECTED_STABLE_GZ_SHA" ] || fail "stable Packages.gz изменён" +gzip -cd "$STABLE_PACKAGES_GZ" | cmp - "$STABLE_PACKAGES" >/dev/null || fail "stable Packages.gz не соответствует Packages" + +for forbidden in \ + BRORAY_FULL_CONTROL_TEST_MODE \ + BRORAY_FULL_CONTROL_TEST_SOURCE_IPK \ + BRORAY_FULL_CONTROL_TEST_SOURCE_SHA \ + BRORAY_FULL_CONTROL_TEST_SOURCE_SIZE \ + BRORAY_BUILDER_TEST_MODE \ + BRORAY_BUILDER_TEST_SOURCE_IPK \ + BRORAY_BUILDER_TEST_SOURCE_SHA \ + BRORAY_BUILDER_TEST_SOURCE_SIZE \ + BRORAY_TAR_BIN \ + BRORAY_OPT_ROOT \ + BRORAY_TMP_ROOT \ + BRORAY_LOCAL_ROLLBACK_TREE \ + BRORAY_LOCAL_ROLLBACK_META +do + eval "value=\${$forbidden:-}" + [ -z "$value" ] || fail "запрещена переменная окружения $forbidden" +done + +bash "$CONTROLLER" +result=$? + +printf '\nКод завершения: %s\n' "$result" +printf '%s\n' "Контроллер выполняет три чистые exact-production сборки A/B/C, независимый валидатор, финальную холодную проверку, негативные controls и контроль неизменности stable/staging." +printf '%s\n' "Контроллер не публикует staging и не изменяет stable." +printf '%s\n' "Только итог BROray 2.2.6-r41 FULL CONTROL: PASS разрешает следующий отдельный этап staging." +printf '%s\n' "==================================================" +exit "$result"