Files
HY2XS_flamy/versions.env
T
founder b99be7d514 fix(v1): разблокировать сборку, починить жизненный цикл cron и закрыть каналы утечки
Сборка не собиралась: два контракта приёмки роняли её на корректном коде.

verify_api_namespace_contract искал возвращение legacy-пространства имён
через grep по '/hui' и находил router_test.go, который ПЕРЕЧИСЛЯЕТ этот
префикс, чтобы доказать отсутствие маршрута, и сам versions.sh, где строка
стоит в тексте проверки. Падение приходило шестым шагом из четырнадцати, до
резолва Hysteria. За ним прятался второй такой же: проверка транзакционности
импорта пиров брала файл от начала applyPeerImportEntry и до конца, захватывая
объявленные ниже ExistPeerName и UpdatePeerLastConnectionAt.

Обе проверки теперь смотрят на код, а не на упоминания: добавлены помощники
code_without_comments и code_mentions_in, а отсутствие legacy-маршрута
доказывает тест на таблице маршрутов собранного роутера.

Планировщик стал собственностью процесса. InitCron вызывался из runServer и
на каждом вызове создавал новый cron.New(), не сохраняя ссылку; cron.Stop()
не вызывался нигде. Смена RESET_TRAFFIC_CRON выполняла StopServer(), точка
входа крутила for { runServer() } — и каждая правка добавляла целый
дублирующий набор джоб, а старое расписание сброса продолжало работать.
Фиксированные джобы регистрируются один раз, расписание переносится на месте
по EntryID, HTTP-сервер не трогается. Добавлено штатное завершение по SIGTERM.

Выражение проверяется до записи в базу тем же парсером (cron.ParseStandard),
которым его разбирает планировщик: раньше невалидная строка сохранялась, API
отвечал успехом, а сброс трафика молча исчезал.

updateConfigs стал атомарным: полная проверка партии, одна транзакция,
применение к рантайму. Прежний тест ставил запрещённый ключ первым и не
смотрел в базу — поймать частичное применение он был неспособен.

Удалены четыре ключа таблицы config без единого потребителя: HYSTERIA2_ENABLE,
HYSTERIA2_CONFIG (второй источник истины, читался первым), HYSTERIA2_TRAFFIC_TIME
и HYSTERIA2_CONFIG_REMARK. Имя профиля в share URI выводится из имени пира.

Безопасность:
- bootstrap-пароль администратора больше не генерируется и не пишется в журнал,
  который отдаётся кнопкой выгрузки; отсутствие env — отказ старта;
- собственный журнал админки санитизируется наравне с чужим;
- golang-jwt/jwt v3 -> v5: GO-2025-3553 не имеет исправленной версии в v3 и
  достижима с неаутентифицированного запроса; набор алгоритмов подписи
  зафиксирован через WithValidMethods;
- удалён вход по несолёному SHA-224 из предыдущего поколения;
- убран modulo bias в util.RandomString — единственном генераторе секретов;
- пир установщика защищён во всех путях записи, а не только в импорте;
- удалена латентная паника в service.GetToken и недостижимая ветка GetAdminInfo,
  проверявшая меньше, чем middleware.

Toolchain: Go 1.21.13 -> 1.26.7, Node 20.19.0 (EOL) -> 24.20.0. На прежнем
графе govulncheck находил 21 вызываемую уязвимость, 17 из них в stdlib,
попадающей в production-бинарь. Сейчас — ноль. Добавлен обязательный шаг
проверки зависимостей (govulncheck + pnpm audit) с записью результата в
metadata пакета.
2026-08-29 21:37:50 +05:00

98 lines
6.1 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HY2XS: единственный источник истины для контракта
# «продукт / платформа / toolchain».
#
# Что здесь ЕСТЬ:
# версия продукта, линия релиза, схема конфигурации, целевая платформа,
# версии и контрольные суммы build-toolchain, политика выбора Hysteria.
#
# Чего здесь НЕТ и быть не должно:
# 1. Прикладные зависимости (Vue, Gin, GORM, npm/Go модули). У них уже есть
# канонические lock-механизмы: apps/frontend/pnpm-lock.yaml,
# orchestrator/bun.lock, apps/go.sum. Второй слой неизбежно разъедется
# с настоящим графом зависимостей.
# 2. Конкретная версия Hysteria. Здесь живёт только ПОЛИТИКА выбора
# (HYSTERIA_CHANNEL). Результат резолва конкретной сборки замораживается
# в tools/build/hysteria-lock.env. Пин версии здесь вернул бы ручное
# обновление, от которого мы ушли.
#
# Файл читается сборкой (tools/build/lib/versions.sh) и проверяется шагом
# verify_versions_contract: рассинхрон с package.json / profile.ts /
# hy2xs.env / go.mod роняет сборку до создания tarball.
#
# Синтаксис — POSIX shell: файл должен безопасно подключаться через `.`
# без jq, Node и Python.
# ------------------------------------------------------------- продукт ---
HY2XS_VERSION=1.0.0
HY2XS_RELEASE_LINE=1
HY2XS_CONFIG_SCHEMA_VERSION=2
# ------------------------------------------------------------ платформа ---
HY2XS_BUILD_OS=debian
HY2XS_BUILD_OS_VERSION=13
HY2XS_BUILD_ARCH=amd64
HY2XS_TARGET_OS=debian
HY2XS_TARGET_OS_VERSION=13
HY2XS_TARGET_ARCH=amd64
# ------------------------------------------------------------ toolchain ---
# Go входит в production-артефакт, а не только в сборку: им компилируется
# hy2xs-admin, и его stdlib целиком попадает в бинарь. Поэтому версия здесь
# выбирается по политике поддержки Go (major поддерживается, пока не вышли две
# более новые), а не по удобству.
#
# Было 1.21.13 — линия вне поддержки. На ней `govulncheck ./...` находил 21
# ВЫЗЫВАЕМУЮ уязвимость, из них 17 в stdlib. На 1.26.7 — ноль.
GO_VERSION=1.26.7
GO_LINUX_AMD64_SHA256=ffb5f8de10c62550dfddab66b36b57030721e0a44a3218e9e1181d7b59f121ca
# Bun выбирает артефакт по наличию AVX2, поэтому одной контрольной суммы
# архитектурно недостаточно: обе должны быть зафиксированы заранее.
#
# 1.3.13 оставлена сознательно, хотя 1.4 уже вышел. Оркестратор собирается
# через `bun build --compile`, то есть Bun runtime физически входит в
# исполняемый файл, а 1.4 — крупное внутреннее обновление рантайма. Такой
# переход стоит отдельного контролируемого прохода по всей матрице
# `bun test → tsc → compile → Debian acceptance`, а не строки в общем патче.
BUN_VERSION=1.3.13
BUN_LINUX_X64_SHA256=79c0771fa8b92c33aae41e15a0e0d307ea99d0e2f00317c71c6c53237a78e25a
BUN_LINUX_X64_BASELINE_SHA256=9d8a24292a7068090205daac0a5a223f5f69736f5287e37bf88d3b4031edc750
# Node живёт только на build-хосте (сборка frontend-ассетов) и в runtime-артефакт
# не попадает. Но 20.x достигла EOL, то есть перестала получать в том числе
# security-обновления, а собирает она код, который уезжает в production.
# 24.20.0 — текущая LTS-линия.
NODE_VERSION=24.20.0
NODE_LINUX_X64_SHA256=2f2c0da162318f0de47665410c7c8c2ed3d36c8f3105de4bbc61176c70a7cbf2
# pnpm ставится через corepack, отдельного архива с контрольной суммой нет.
#
# Линия 9 оставлена вместе с apps/frontend/pnpm-lock.yaml: переход на 10 меняет
# формат lock-файла, то есть затрагивает воспроизводимость сборки frontend, и
# относится к обновлению его зависимостей, а не toolchain.
PNPM_VERSION=9.15.9
# ------------------------------------------------ проверка зависимостей ---
# Версия govulncheck пиньтся здесь, а не берётся @latest: инструмент, которым
# проверяется релиз, сам обязан быть частью контракта сборки. Иначе один и тот
# же коммит проверяется разными анализаторами в разные дни.
#
# База уязвимостей при этом ЖИВАЯ и подтягивается на каждом запуске — это и
# нужно: пин версии инструмента не должен превращаться в пин знаний о мире.
GOVULNCHECK_VERSION=v1.7.0
# Порог pnpm audit для production-зависимостей frontend.
# Значения: low | moderate | high | critical.
PNPM_AUDIT_LEVEL=high
# ------------------------------------------------ политика выбора Hysteria ---
# stable — резолвить последний стабильный upstream-релиз на build-машине;
# pinned — использовать закоммиченный tools/build/hysteria-lock.env офлайн.
HYSTERIA_CHANNEL=stable