Правила работы — `AGENTS.md` в корне репозитория. Репозиторий: `https://github.com/ochenstarik-ui/kagent`, база — свежий `main` Ветка: новая от `origin/main`, `wt/c3-reasoning-contract` Файлы: `packages/contracts/src/index.ts`, новый тест, `docs/known-drift.json` **Зависимостей нет.** Задача не пересекается с c1, c4 и c5 и может выполняться параллельно. ## Проблема `packages/contracts/src/reasoning.ts` — типы контракта Reasoning Engine: capability, класс приватности, режим исполнения, категория задачи, запрос и решение о маршрутизации. Файл не экспортируется из `index.ts` и не импортируется ниоткуда, поэтому попал в `docs/known-drift.json` как недостижимый. При этом Python-сервис `services/reasoning-engine` объявляет те же понятия заново в `src/engine.py` и `src/server.py`. Два независимых определения одного контракта — то, что ADR-0002 прямо запрещает. ## Что сделать ### 1. Экспортировать контракт Добавить `export * from "./reasoning.js";` в `packages/contracts/src/index.ts`. Это аддитивное расширение публичной поверхности пакета: существующие импорты не ломаются. По правилам репозитория такое изменение допускается без поднятия мажорной версии, но должно быть явно описано — добавь строку в `CHANGELOG.md` и отметь в `AGENT_CHANGELOG.md`, что контракт Reasoning Engine стал частью публичной поверхности `@kagent/contracts`. ### 2. Тест соответствия контракта и сервиса Просто экспортировать файл недостаточно: он станет достижимым, но по-прежнему ничем не связан с реальным сервисом. Добавь проверку, что TypeScript-контракт и Python-реализация не разошлись. Минимальный вариант: тест, который читает список полей `DecideRequest` и допустимых значений `Capability`, `PrivacyClass`, `ExecutionMode`, `TaskCategory` из `services/reasoning-engine/src/server.py` и `src/engine.py`, и сверяет с типами из `reasoning.ts`. Расхождение — падение теста с указанием, какое значение есть только на одной стороне. Разбор Python допустимо делать по объявлениям enum: они записаны как простые классы со строковыми константами. Хрупкий разбор с регулярными выражениями по всему файлу не нужен — достаточно секции enum. Если окажется, что стороны уже разошлись, **не подгоняй ни одну из них молча**: зафиксируй расхождение в отчёте, приведи в соответствие ту сторону, которая противоречит ТЗ, и объясни выбор. ### 3. Снять запись из known-drift После того как `python scripts/drift_check.py` перестанет находить `reasoning.ts`, удалить соответствующую запись из `docs/known-drift.json`. Список должен только сокращаться. ## Критерий приёмки ```bash pnpm --filter @kagent/contracts typecheck pnpm --filter @kagent/contracts test pnpm typecheck pnpm build python scripts/drift_check.py ``` - `drift_check.py` больше не сообщает про `packages/contracts/src/reasoning.ts`; - в `docs/known-drift.json` осталось три записи; - тест соответствия проходит и падает, если в один из enum добавить лишнее значение — проверь это вручную и приведи вывод в отчёте; - ссылка на зелёный прогон приложена. ## Границы `packages/contracts`, новый тест, `docs/known-drift.json`, `CHANGELOG.md`, `AGENT_CHANGELOG.md`. Python-сервис не переписывать, кроме случая доказанного расхождения с ТЗ.