## Why Прод и тест будут работать с разными наборами subject'ов NATS и разными JWT. Платформа РАИСА передаёт в под только переменные `OPENBAO__*`, поэтому окружение должно настраиваться только секретами OpenBao, без пересборки и релиза сервисов. Сейчас JWT и seed уже приходят как `OPENBAO__NATS__NATS_JWT` / `NATS_SEED`, а subject'ы зашиты константами `api/src/contract/subjects.py` трёх сервисов (решение R-4 в #74) и уже раз менялись (`recognition.*` → `files.*`, 08.10.2026). Решение владельца 12.10.2026: subject'ы и JWT задаются по окружению секретами группы `OPENBAO__NATS__` — так устроен `RSHB/armka_file_worker`, проверенный в контуре (`NATS_COMMAND_SUBJECT`, `NATS_EVENT_SUBJECT` рядом с `NATS_JWT`). Срез: вне плана срезов `09-delivery-plan.md` — подготовка к контуру (инфраструктура NATS платформы). Issue RSHB/arm-ka-docs#80. ## What Changes - Три настройки окружения, одинаковые ключи во всех трёх сервисах, умолчания — текущие имена: `OPENBAO__NATS__NATS_TABULAR_REQUEST_SUBJECT` (`files.tabular_uploaded`), `OPENBAO__NATS__NATS_IMAGE_REQUEST_SUBJECT` (`files.img_uploaded`), `OPENBAO__NATS__NATS_RESULT_SUBJECT` (`files.tabular_parsed`). - Контракт: subject'ы — конфигурация окружения; у ядра и сервисов одного окружения значения MUST совпадать; имена проверяются при старте (непустые, без пробелов и шаблонов `*`/`>`, три разных). - `NATS_JWT` / `NATS_SEED` — секреты: значения не попадают в `repr`, логи и тексты ошибок валидации конфигурации. - Каждый сервис пишет свои subject'ы в лог при старте и отдаёт их в `/healthcheck` (объект `subjects`). - Интеграционные тесты `tabular-parser` и `scan-gateway` берут собственные subject'ы через настройки и не делят их с контейнерами стенда (OQ-83 в части этих тестов; e2e ядра — без изменений, design R-7). - Документы: `context/03-architecture.md` (NATS платформы, перечень секретов), `context/07-open-questions.md` (OQ-83), `dev/README.md`, `dev/contour-transfer-guide.md`, `dev/qa-guide.md`, `dev/frontend-api-guide.md` (ответ `/healthcheck`, если описан), `dev/.env.example`. Читают и пишут контракт: `arm-core` (публикует запросы в оба subject'а запроса, подписан на subject ответа), `tabular-parser` (подписан на subject запроса `tabular`, публикует в subject ответа), `scan-gateway` (подписан на subject запроса `image`, публикует в subject ответа). Дочерние change'и `nats-env-config`: RSHB/arm-core#106, RSHB/arm-tabular-parser#31, RSHB/arm-scan-gateway#32. ## Non-goals - `schema_version` контракта не меняется: тела сообщений, `Nats-Msg-Id`, файл результата — те же. - Queue group'ы (`arm-core`, `tabular-parser`, `scan-gateway`) остаются константами. - Механизм аутентификации NATS не меняется (nkeys seed + JWT, оба пусты — без учётных данных). - Пароли MinIO и SMB в `SecretStr` не переводятся. - Subject'ы не настраиваются через `OPENBAO__APP__*`: это группа `NATS`, а не настройки верхнего уровня. - DBML не поднимается; заметки v5.17 про subject'ы — follow-up RSHB/arm-ka-docs#79 (R-3). - Отдельный NATS для тестов не поднимается. ## Capabilities ### New Capabilities ### Modified Capabilities - `recognition-contract`: subject'ы запроса и ответа — настройки окружения с умолчаниями `files.*`. ## Impact - Сервисы: `arm-core`, `tabular-parser`, `scan-gateway` — `core/config.py` (`NATSSettings`), `contract/subjects.py`, `core/nats.py`, публикация и подписки, `/healthcheck`, тесты, `.env.example`, спеки, README. - Выкат обратно совместим: без новых ключей всё работает на `files.*`. Для теста платформа кладёт свои `NATS_JWT`, `NATS_SEED` и три subject'а одинаково всем трём сервисам; JWT окружения должен давать права publish/subscribe на эти subject'ы. - Ядро вычисляет subject при каждой публикации по `pipeline`, поэтому после смены настроек повторная публикация заданий в работе уходит в новый subject; `recognition_job.request_subject` записывает фактический subject.