Правила работы — `AGENTS.md` в корне репозитория, копия в
`C:\Users\Ochenstarik\kagent-tasks\AGENTS.md`.

Репозиторий: `https://github.com/ochenstarik-ui/kagent`, база — `main` на `00c56fa`
Ветка: создать новую от свежего `main`, `wt/b4-drift-check-quality`
Файл: `scripts/drift_check.py`. Выполняется **до** задачи `b3-measurability-wire-ci.md`.

Работа этапа 0.9.1 уже влита в `main`: скрипты, реестр возможностей, каркас eval и
модульные тесты на месте. Старые worktree отпочкованы от прежнего `main` и непригодны —
начни с `git fetch origin` и новой ветки от `origin/main`.

## Зачем

`b3` подключает `drift_check.py` к непрерывной интеграции как блокирующую проверку. В
текущем виде подключать нельзя: точность проверки такова, что она заблокирует любой пуш по
ложным поводам и при этом пропустит настоящие дефекты.

Фактический прогон на текущем дереве даёт 21 находку недостижимых модулей. Разбор:

**Настоящая находка одна** — `packages/contracts/src/reasoning.ts`: файл не экспортируется
из `index.ts` и не импортируется ниоткуда.

**Ложные срабатывания:**

- `.venv/Lib/site-packages/_virtualenv.py`, `.venv/Scripts/activate_this.py` — проверка
  сканирует виртуальное окружение;
- `packages/contracts/src/index.ts` — это точка входа пакета, она достижима по определению;
- `artifact.ts`, `event.ts`, `ids.ts`, `task.ts` — экспортируются через `index.ts`;
- `artifact.test.ts`, `task.test.ts`, `tests/unit/test_*.py` — тестовые файлы являются
  точками входа для запускающего их инструмента;
- `services/reasoning-engine/src/server.py` — точка входа uvicorn, объявлена в Dockerfile
  как `src.server:app`;
- `services/reasoning-engine/src/engine.py` — импортируется из `server.py`;
- `services/control-plane/src/domain.ts` — импортируется из `store.ts` и `routes.ts`.

**Пропущенные настоящие дефекты.** Проверка не находит ни один из трёх модулей, которые
действительно не подключены ни к одной точке входа:

```
services/nats/src/events.py
services/auth/src/totp.py
services/control-plane/src/db.ts
```

Первые два перестали считаться недостижимыми после того, как в этой же ветке для них
появились модульные тесты. Это лазейка: модуль, который используют только его собственные
тесты, продуктом не используется. Достижимость из теста не является достижимостью.

**Самоблокировка.** Скрипт записывает `eval/reports/latest.json` и тут же сообщает: «product
task must not modify eval or measurability artifacts: M eval/reports/latest.json». Второй
запуск подряд падает из-за первого.

**Необъявленный вид доказательства.** `[web.dashboard] unknown evidence: build` — реестр
возможностей ссылается на вид доказательства, которого проверка не знает.

## Что сделать

1. **Исключить из обхода** каталоги окружений и сборки: `.venv`, `node_modules`, `target`,
   `dist`, `.next`, `__pycache__`, `.worktrees`, `.git`.
2. **Объявить точки входа явно**, а не выводить их эвристикой. Список в конфигурации:
   бинарные цели Rust, `main.ts` и `main.py` сервисов, `app`-объекты, объявленные в
   Dockerfile, экспорты пакетов из `package.json`, страницы Next.js. Файл, достижимый
   транзитивно от точки входа, недостижимым не считается.
3. **Тесты исключить из графа достижимости продукта.** Тестовый файл сам по себе точкой
   входа продукта не является, и покрытие модуля тестом не делает модуль подключённым.
   Проверка обязана находить `services/nats/src/events.py`, `services/auth/src/totp.py` и
   `services/control-plane/src/db.ts` при наличии тестов на них.
4. **Разделить обнаружение и отчёт.** Запись отчёта не должна влиять на результат проверки:
   писать во временный каталог либо добавить путь отчёта в исключения правила о
   неприкосновенности артефактов измеримости.
5. **Согласовать словарь доказательств** между `docs/capabilities.json` и проверкой:
   допустимые виды перечислены в одном месте, неизвестный вид — ошибка реестра с указанием,
   какие виды допустимы.

## Критерий приёмки

Прогон `python scripts/drift_check.py` на текущем дереве:

- находит `packages/contracts/src/reasoning.ts`, `services/nats/src/events.py`,
  `services/auth/src/totp.py`, `services/control-plane/src/db.ts` — все четыре;
- не находит ничего из перечисленного выше списка ложных срабатываний;
- два запуска подряд дают одинаковый результат;
- сообщений `unknown evidence` нет.

Добавить модульные тесты самой проверки: файл, достижимый от точки входа, не помечается;
файл, достижимый только из теста, помечается; файлы в исключённых каталогах не
рассматриваются.

Полный вывод обоих прогонов приложить к отчёту.

## Границы

`scripts/drift_check.py`, его конфигурация, `docs/capabilities.json` в части словаря
доказательств, тесты проверки. Найденные недостижимые модули **не чинить** — по каждому
заводится отдельное решение: подключить или удалить.
