Metadata-Version: 2.4
Name: veha
Version: 0.1.0
Summary: Веха — сервер карты тестирования: сведение артефактов partest-atlas в граф и вебморда
Author: dec01
License-Expression: MIT
Project-URL: Homepage, https://partest.ru/veha/
Project-URL: Source, https://github.com/Dec01/veha
Project-URL: Documentation, https://partest.ru/wiki/veha/
Project-URL: Changelog, https://github.com/Dec01/veha/blob/master/CHANGELOG.md
Project-URL: Issues, https://github.com/Dec01/veha/issues
Keywords: testing,coverage,observability,pytest,visualization
Classifier: Development Status :: 3 - Alpha
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.14
Classifier: Framework :: FastAPI
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: partest-atlas<0.3,>=0.1.0
Requires-Dist: partest<3,>=2.6.0
Requires-Dist: fastapi<1,>=0.132.0
Requires-Dist: uvicorn<1,>=0.27
Requires-Dist: pydantic<3,>=2.7
Requires-Dist: PyYAML<7,>=6.0.2
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-xdist>=3; extra == "dev"
Requires-Dist: pytest-rerunfailures>=14; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Dynamic: license-file

# Веха — карта тестирования

Сервер, который сводит наблюдения о системе и о прогонах тестов в один граф и показывает
его в браузере: экраны, эндпоинты, шина, таблицы — и какие тесты что из этого задели.
Сборка графа, эвристики соединения, сцена, показ расхождений. Управление ими (эталон,
принятие, исключение из оценки) — следующий этап, `docs/architecture.md` §10.

**Статус: alpha (0.1.0)**, что стабильно — в разделе «Статус» ниже. Лицензия — MIT.

## Быстрый старт

```text
pipx install veha        # или pip install veha в отдельном окружении — см. «Установка»
veha demo
```

Откроется `http://127.0.0.1:8770` — карта вымышленной системы: интернет-магазин, склад,
биллинг и CRM, 177 эндпоинтов, 605 тестов последнего прогона. Набор приезжает внутри
пакета; сервер над ним только показывает — прогоны не запускаются, на диск ничего не
пишется. Сеть не нужна. Ключи `demo`: `--port` (по умолчанию 8770), `--no-browser`.

Что смотреть и в каком порядке — [обход демонстрации на 7 шагов](https://github.com/Dec01/veha/blob/v0.1.0/demo/README.md).
Та же карта без сервера — [демо на сайте](https://partest.ru/veha/demo/).

Свой проект: `veha serve --root <каталог>`, где лежат `atlas.yaml`, артефакты
`partest-atlas` в `atlas/`, `coverage.json` и `allure-results/` (ниже — «Запуск»).

## Имена

Решение принято 2026-09-06 и действует везде:

| | Имя | Где встречается |
|---|---|---|
| **Проект** | **Веха** | сайт, интерфейс, документация |
| Имя пакета сервера | `veha` | код этого репозитория |
| Команда сервера | `veha` | `veha serve`, `veha demo`, `veha export-static`; в плане — `veha update`, `veha baseline diff` |
| Агент сбора | `partest-atlas` | PyPI, отдельный открытый пакет |
| Команда агента | `partest-atlas` | `partest-atlas wrap -- …` |
| Технические имена данных | `atlas.yaml`, каталог `atlas/` | конфигурация и артефакты в проекте с тестами |

Технические имена намеренно **не** переименовываются в `veha`: `atlas.yaml` и каталог
`atlas/` — часть контракта с агентом и с уже существующими установками. Имя проекта и
имя формата — разные вещи, и смешивать их дороже, чем объяснить один раз.

Короткое `atlas` как имя команды не используется: оно занято в экосистеме (MongoDB Atlas
CLI), а конфликт имён на чужой машине ловится дорого.

## Семейство

Веха — потребитель открытых пакетов семейства partest; они про неё не знают.

| Часть | Где | Что делает |
|---|---|---|
| [`partest`](https://github.com/Dec01/partest) | [PyPI](https://pypi.org/project/partest/) | харнесс покрытия API и методика; Веха берёт у него маскирование секретов и читает его отчёт `coverage.json` |
| [`partest-atlas`](https://github.com/Dec01/partest-atlas) | [PyPI](https://pypi.org/project/partest-atlas/) | агент сбора: сборщики, адаптеры, обёртка, зонд; владелец формата артефактов |
| [`partest-load`](https://github.com/Dec01/partest-load) | [PyPI](https://pypi.org/project/partest-load/) | нагрузочные профили и метрики деградации |
| **Веха** | этот репозиторий | сведение источников, карта, вебморда, показ расхождений |

Агент записывает наблюдение, сервер делает вывод. Агент ходит в базу, шину и логи
тестируемой системы, поэтому он маленький и читается целиком. Ценность не в сборе, а в
сведении — она здесь.

**Вебморда живёт здесь**, в сервере, и другого места у неё быть не может: она показывает
сведённый граф, находки и эталон — то, чего агент не знает. FastAPI отдаёт и `/api/*`, и
статику; отрисовка — Canvas 2D в браузере; ни npm, ни WebGL, ни единого внешнего запроса.
Подробности и недостающая аутентификация — [`docs/architecture.md`](https://github.com/Dec01/veha/blob/v0.1.0/docs/architecture.md) §4.6.

## Документация

| Документ | О чём |
|---|---|
| [docs/architecture.md](https://github.com/Dec01/veha/blob/v0.1.0/docs/architecture.md) | проектный документ: модель данных, несколько систем и контуров, управление расхождениями, подключение к тестам, вебморда |
| [docs/wiki/index.md](https://github.com/Dec01/veha/blob/v0.1.0/docs/wiki/index.md) | каталог вики: состояние, решения, спорное |
| [docs/wiki/status.md](https://github.com/Dec01/veha/blob/v0.1.0/docs/wiki/status.md) | что сделано, чего нет, известные ограничения |
| [demo/README.md](https://github.com/Dec01/veha/blob/v0.1.0/demo/README.md) | демонстрация на вымышленных данных |

## Красные линии

Нарушение любой — дефект, а не компромисс.

1. **Нулевой исходящий трафик.** Ни телеметрии, ни отчётов о падениях, ни CDN, ни внешних
   шрифтов, ни загрузки библиотек из сети. Вебморда открывается на машине без интернета.
2. **Базы только на чтение.** Ни DDL, ни DML. Запрос, не являющийся одиночным `SELECT`,
   отклоняется (`partest.sideeffects.assert_read_only_sql`).
3. **В consumer group не входим.** Смещения читаются, чужие консьюмеры не задеты.
4. **Пишем только в свой каталог.** Артефакты — в `artifacts_dir`, ничего другого в
   тестируемой системе не создаётся и не меняется (о файле отметок МР —
   [docs/wiki/proposals.md](https://github.com/Dec01/veha/blob/v0.1.0/docs/wiki/proposals.md)).
5. **Секреты не показываем.** Всё, что уходит в интерфейс, проходит через `redact`.
6. **Аудит-лог обращений** к базе, шине и логам — в открытом виде, доступен тому, чью
   систему читают.
7. **Догадка подписана как догадка.** Вывод не выдаётся за факт. Сейчас: у требования
   видно, чем установлена связь с тестом — прямой ссылкой из теста или выведена (по
   эндпоинту, по таблице, по названию фичи); связь «эндпоинт — таблица» подписана окном
   теста, в котором снята, а «топик — таблица» — выводом из тишины записей. Единое поле
   `evidence` (`measured`, `inferred`, `declared`) на каждой связи — план, а не то, что
   уже есть ([docs/wiki/proposals.md](https://github.com/Dec01/veha/blob/v0.1.0/docs/wiki/proposals.md)).
8. **В ядре нет домена конкретного проекта.** Всё проектное — в `atlas.yaml`.

## Установка

Нужен Python ≥ 3.10. Ставьте Веху в **отдельное окружение**, а не в окружение проекта с
тестами: у сервера свои зависимости (FastAPI, uvicorn, pydantic), и резолвер pip будет
мирить их с пакетами проекта — проигрывает в этом обычно проект. Данные проекта сервер
читает из каталога (`--root`), ставить его рядом с тестами незачем.

```text
pipx install veha                    # команда veha в своём окружении
# или своё окружение:
python -m venv ~/.veha && ~/.veha/bin/pip install veha    # Windows: ~/.veha/Scripts/pip
```

Вместе с пакетом ставится `partest-atlas` (`>=0.1.0,<0.3`) — владелец формата артефактов;
сервер читает и проверяет артефакты его кодом. Без доступа в интернет пакеты ставятся
из локального индекса или wheelhouse, сеть для работы не нужна.

Из исходников — для разработки и для пересборки демонстрации. Из корня репозитория:

```text
python -m venv .venv
.venv/Scripts/python -m pip install -e ".[dev]"     # Linux/macOS: .venv/bin/python
```

Демонстрационный набор лежит в пакете, в `veha/demo_data/`; пишет его
`demo/generate.py`, и править набор руками бесполезно — следующий запуск генератора
перетрёт правку. Попробовать на нём `--allow-run` — только на копии во временном
каталоге: с этим ключом сервер пишет в каталог данных (история прогонов, отметки МР),
а `veha/demo_data/` — это дерево пакета.

```text
python -c "import shutil, tempfile, veha.demo as d; print(shutil.copytree(d.data_root(), tempfile.mkdtemp() + '/demo'))"
veha serve --root <напечатанный каталог> --allow-run
```

Колесо для выпуска собирается **только из чистого клона** (`git clone`, затем
`python -m build`), не из рабочей копии: в рабочей копии `veha/demo_data/` мог
измениться — от `--allow-run`, от незакоммиченной генерации, — и в колесо уехало бы
не то, что в репозитории.

## Запуск

```text
veha demo                            # демонстрация на вымышленных данных из пакета
veha serve --root <каталог>          # atlas.yaml, atlas/, coverage.json, allure-results/
veha export-static --root <каталог> --out <каталог>   # статический снимок для сайта
```

`export-static` пишет снимок вебморды, которому сервер не нужен: страницу, статику и
ответы API JSON-файлами. Он открывается из любого подкаталога статического сайта под
CSP без `'unsafe-inline'`; действия, которым нужен сервер (перезапуск, раннер, опрос
«Live», отметки МР), в нём выключены с подписью «в демо недоступно». **Снимок публикует
всё, что видно в вебморде** — контейнеры, логи, merge request'ы, шаги и вложения тестов;
снимок настоящих данных наружу не выкладывают, для витрины есть вымышленный набор
`veha demo` (из исходников — `--root veha/demo_data`).

Ключи `serve`: `--port` (по умолчанию 8770), `--no-browser`, `--system`/`--env` — какую область
показывать (иначе `ATLAS_SYSTEM`/`ATLAS_ENV`, как у агента; имя — один сегмент
`[A-Za-z0-9._-]+`), `--allow-run` — разрешить из вебморды запуск наборов pytest из
`runner.suites`, остановку, очистку, перезапуск кейса и отметки МР (по умолчанию только
просмотр, ничего не пишется).

Аутентификации пока нет, поэтому сервер слушает только `127.0.0.1`, отвечает только на
`Host` `127.0.0.1:<порт>` и `localhost:<порт>`, изменяющие запросы принимает только со
своей страницы и отдаёт CSP без внешних источников. Секреты (авторизация, пароли, токены,
куки) маскируются во всём, что уходит в интерфейс: вложения, логи, разбор падений.

Что сервер прочитал, а что нет и почему, печатается при старте и видно в шапке сцены; для
диагностики то же отдаёт `GET /api/artifacts` — это внутренний HTTP-интерфейс вебморды,
его форма может меняться в любой версии. Проверки — `python -m pytest` (без сети и без стенда).

## Статус

Alpha: сервер — устанавливаемый пакет и потребитель `partest-atlas`; подключение своего
проекта пока требует ручной настройки `atlas.yaml`.

**Что стабильно.** Версии — [Semantic Versioning](https://semver.org/) с поправкой на
линию `0.x`: пока она не кончилась, ломающее изменение поднимает **минорную** цифру и
записывается в журнале изменений разделом «Сломано». Таблица — в начале
[CHANGELOG.md](https://github.com/Dec01/veha/blob/v0.1.0/CHANGELOG.md).

- **Публичное** — то, на что можно опираться: команды `veha serve`, `veha demo`,
  `veha export-static` и их ключи; порт по умолчанию 8770; переменные `ATLAS_SYSTEM` и
  `ATLAS_ENV`; раскладка каталога данных (`atlas.yaml`, `atlas/<система>/<контур>/`,
  `coverage.json`, `allure-results/`) и разделы `atlas.yaml`, которые читает сервер;
  то, что сервер пишет у пользователя, — история прогонов `runner.history` и отметки
  `live/mr_checks.json`.
- **Внутреннее** — меняется в любой версии без записи в «Сломано»: импорт `veha.*`
  (кроме `veha.__version__`), HTTP-интерфейс `/api/*`, раскладка статического снимка. Подробно, с
тем, чего нет, и с ближайшими шагами, — [docs/wiki/status.md](https://github.com/Dec01/veha/blob/v0.1.0/docs/wiki/status.md).
Проектное направление дальше — этапы в [`docs/architecture.md`](https://github.com/Dec01/veha/blob/v0.1.0/docs/architecture.md) §10.

## Лицензия

MIT — см. [LICENSE](https://github.com/Dec01/veha/blob/v0.1.0/LICENSE).
