Files
HY2XS_flamy/versions.env
T
founder 8dcb50a07c fix(admin): дать отзыву доступа вторую попытку, а лимиту устройств — порядок снимков
Предыдущий проход сделал правильным порядок «сначала долговременная запись,
потом разрыв сессии» и правильно запретил откат при неудаче разрыва. Способа
прийти к согласованному состоянию ПОТОМ он не дал: у двух операций повтор не
работал вовсе.

Импорт, заменивший auth_id: после неудавшегося /kick старое значение не
хранится нигде, повтор того же файла читает из базы уже новое и рвёт его, а
cron пропускал незнакомый authID молча — dao.ListPeer просто не возвращала
строку. Живая сессия оставалась навсегда.

Снижение maxDevices: повтор формы даёт 1 < 1 -> false, разрыва больше нет.
Лимит устройств в политику доступа не входит и входить не должен — это
свойство сессий, — поэтому механизма схождения у него не было.

enforcePeerAccess стал сверкой живых сессий: обход идёт по каждому authID из
/online. Нет строки в базе -> kick; peerAccessDenied -> kick; непригодный
maxDevices -> kick; устройств больше разрешённого -> kick. Отказ базы при этом
не рвёт ничего. Ни таблицы отложенных операций, ни очереди retry: список живых
сессий уже есть, и это /online.

Отдельно закрыт второй TOCTOU лимита устройств. Учёт выданных разрешений
закрыл сравнение двух одинаковых снимков, но сетевой запрос выполнялся вне
блокировки, поэтому снимки приходили в резервацию в произвольном порядке и
устаревший откатывал lastOnline назад, возвращая уже занятое место. Это не
data race — память защищена мьютексом, и -race здесь молчит принципиально.
Последовательность «прочитать /online -> занять место» выполняется под замком
по authId; глобальный замок не годится, внутри идёт сетевой запрос.

Учёт разрешений больше не растёт бесконечно: запись снималась только на ветке
отказа, поэтому в карте копились удалённые пиры и переписанные импортом
идентификаторы. Уборка идёт по фактической картине подключений.

Гейты приёмки доращены под все три инварианта и проверены в обе стороны.
Go 1.26.7 -> 1.26.8. Документация приведена в соответствие в двух местах,
где описывала снятую архитектуру.

Разбор: docs/acceptance/2026-09-02-v1.0.0-rc3-preflight-findings.md
2026-09-02 07:15:43 +05:00

108 lines
7.1 KiB
Bash
Raw Permalink 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.x — ноль.
#
# Patch-релиз держится актуальным по той же причине: stdlib целиком попадает в
# бинарь, поэтому «на один патч позади» — это свойство выпускаемого артефакта,
# а не среды сборки. 1.26.8 вышел 2026-09-01 (fixes в cgo, компиляторе,
# runtime, `debug/elf` и `os`); major при этом не меняется — линия 1.26
# поддерживается, и переход на 1.27 ради номера не нужен.
GO_VERSION=1.26.8
GO_LINUX_AMD64_SHA256=d0f743b33e8d8945e6b1f432edd15785c70507121d6e2a723b21285eddf8b57b
# 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 по ВСЕМУ lock-графу frontend, а не только по production-
# зависимостям. `--prod` здесь стоял с обоснованием «devDependencies в артефакт
# не попадают», и для frontend build tooling это обоснование неверно: vite и
# rollup формируют production-бандл, который уезжает в артефакт, поэтому
# уязвимость в них — уязвимость в том, что мы выпускаем.
# Значения: low | moderate | high | critical.
PNPM_AUDIT_LEVEL=high
# ------------------------------------------------ политика выбора Hysteria ---
# stable — резолвить последний стабильный upstream-релиз на build-машине;
# pinned — использовать закоммиченный tools/build/hysteria-lock.env офлайн.
HYSTERIA_CHANNEL=stable