regress.sh — один вход: preflight (main = origin/main, чистые, нет чужих потребителей NATS), venv, lint+unit всех репозиториев и docs make check, фронт в чистой копии (npm ci --dry-run как проверка lock, установка без lock), интеграционные с циклом миграций, реальные данные парсера, образы, e2e ядра, изолированный стенд с нуля (compose-проект arm-ka-regress на своих портах) со сценарием по API, UI-смоук Playwright, парсер по doc-bank. Не останавливается на первой ошибке; итог — summary.md с SHA и статусом шагов. Контрольные цифры — expected.json (qa-guide §7.1–7.3, прогоны 08.10/14.10, golden шахматки); снимки свода, шахматки и форм сравниваются с прошлым прогоном. Ссылки из dev/checks.md и чек-листа синхронизации контура. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Полная регрессия перед выкладкой
Один прогон проверяет main всех репозиториев workspace так, как его увидит контур: проверки качества каждого
репозитория, интеграционные и сквозные тесты, образы, стенд с нуля со сценарием по API и контрольными цифрами, UI-смоук и
прогон парсера по банку первички. В отличие от make check-full, прогон не останавливается на первой ошибке: перед
выкладкой нужна вся картина. Задача — arm-ka-docs#179.
make regress # из корня docs, workspace — родитель docs
scripts/regression/regress.sh --only stand,ui # только часть этапов (список: --list)
scripts/regression/regress.sh --skip bank --keep-stand
ARM_KA_WORKSPACE=~/projects/awp-ca scripts/regression/regress.sh # из worktree docs: проверяются основные checkout'ы
Результат — admin/regression/<дата_время>/ в workspace (--out — другой каталог; повторный запуск этапов в тот же
каталог заменяет только их строки): summary.md — итог, logs/<этап>.<шаг>.log, stand/ (отчёт сценария, снимки свода,
шахматки и форм, экспорт xlsx), ui/ (скриншоты экранов), bank/ (результаты парсера по doc-bank). Каталог содержит
производные реальных данных — в git не класть. Код возврата: 0 — всё зелёное, 1 — есть красные шаги, 2 —
preflight не пройден.
Этапы
| Этап | Что проверяет |
|---|---|
preflight |
все репозитории (docs, fixtures, arm-statements, arm-core, tabular-parser, scan-gateway) на main, равны origin/main, без правок; Docker, uv, npm, openspec; нет чужих потребителей общей NATS (контейнеры сервисов arm-ka, ядро на :8000) — иначе интеграционные тесты и e2e падают по таймауту. Не пройден — прогон останавливается (--allow-dirty — прогнать как есть, с пометкой в итоге) |
venv |
make venv во всех репозиториях (окружения по текущим зависимостям) |
static |
make check docs (контракты, OpenSpec, снимок контура, sync-statements), обзор свежести копий arm_statements, lint и test arm-statements и трёх сервисов, dbml-check ядра |
web |
фронт arm-core/web в чистой копии во временном каталоге: npm ci (как пайплайн; при расхождении lock с package.json — красный, копия доустанавливается npm install), biome, tsc, ESLint + Prettier, vitest, сборка. main не меняется |
integration |
инфраструктура общего compose-проекта arm-ka (make up), check-infra, test-integration трёх сервисов; у ядра — с циклом миграций upgrade → downgrade base → upgrade. Тесты создают свои БД, рабочую armka не трогают |
fixtures |
реальные данные парсера: test-fixtures (golden, покрытие словарей) и golden-check tabular-parser |
images |
сборка образов arm-core:dev, tabular-parser:dev, scan-gateway:dev из main (профиль services) |
e2e |
сквозной тест ядра с настоящим tabular-parser (контейнер в arm-ka, после теста возвращается в прежнее состояние); пропуск теста — красный |
stand |
изолированный стенд с нуля: compose-проект arm-ka-regress на своих портах (ядро :18000, парсер :18001, шлюз :18002, PostgreSQL :15432, NATS :14222, MinIO :19000), миграции и seed --dev, эмулятор ИС Сканирование; сценарий stand_scenario.py по expected.json |
ui |
dev-сервер фронта против стенда, Playwright (ui_smoke.py) по основным экранам: исключения страницы, ответы /api ≥ 400, пустые экраны, скриншоты |
bank |
CLI tabular-parser по всем табличным файлам doc-bank (если он есть) и сравнение с прошлым прогоном (parser_bank.py) |
Стенд снимается (down -v) после этапа ui; --keep-stand оставляет его для ручной проверки. Общий стенд arm-ka
(данные, тома, порты) этапы stand и ui не трогают; integration и e2e пользуются его инфраструктурой.
Сценарий стенда и контрольные цифры
expected.json — данные, а не код: ГК/ГСК dev-seed, пользователи, по сценарию — файлы фикстур для загрузки, summary
свода, пробелы, контрольные строки с суммами, пары шахматки, ожидаемые формы ББ/ОФР. Источники цифр — dev/qa-guide.md
§7.1–7.3 (РБ 2024 Q3, посчитаны вручную по файлам), прогоны 08.10 и 14.10.2026 (РБ 2025 Q1) и
test_intercompany_matrix_golden ядра. Новая цифра — только с причиной в описании PR.
На каждый сценарий: создание консолидации (и повтор — 409), блокировка, загрузка файлов в версию, ожидание
распознавания (PDF — через эмулятор ИС), подтверждение ОСВ-документов, summary, пробелы, контрольные строки, свод
постранично = rows_total, экспорт xlsx (строки листов «Сводная ОСВ» и «Пробелы», Content-Disposition), чек-лист,
шахматка по всем предустановленным правилам, результирующая таблица, итоги элиминации, формы ББ/ОФР; в конце — права
(эксперт читает, но не блокирует — 403) и 404.
Помимо ручных цифр, сценарий сохраняет снимки (stand/snapshots/: весь свод построчно, шахматка, формы, документы)
и сравнивает их со снимками последнего прошлого прогона в admin/regression/. Расхождения не красные — их нужно
просмотреть: изменение свода или шахматки между выкладками должно объясняться задачами выкладки.
Банк первички
parser_bank.py разбирает все файлы doc-bank/index/index.csv с маршрутом «парсер» и пишет отпечаток каждого документа
(тип, статус, счёт, период, число строк, сумма денежных колонок, коды предупреждений). База сравнения — последний
прошлый прогон (--bank-baseline DIR — явно), на первом прогоне — колонка parse_status индекса (прогон 20.10.2026).
Итог — переходы «хуже» (кандидаты в регрессию, таблица в summary.md), «лучше» и «тот же статус, другой разбор»
(bank/transitions.json). Этап не красный по переходам: регрессия это или исправление — решает человек.
Если шаг красный
Сначала лог шага (logs/<этап>.<шаг>.log, путь — в summary.md). Частые причины не в коде: занятая NATS (preflight
shared-consumers), не поднятая инфраструктура, сеть для npm ci / uv. Шаг можно перезапустить отдельно:
--only <этап> --out <тот же каталог>.