work_item: ORCH-101 stage: analysis author_agent: analyst status: ready-for-review created_at: 2026-06-10 model_used: claude-opus-4-8 title: "ORCH-10-common: расхардкод + секреты + smoke — план тестов" framework: pytest scope: > Покрывается: расхардкод src/**+watchdog/** (чтение хост-значений из Settings), параметризация docker-compose.yml/Dockerfile/deploy-hook (структурные проверки), полнота .env.example, поведение генератора секретов, запускаемость smoke-обвязки, анти-регресс grep-тест и его негативная самопроверка, zero-regression (полный регресс tests/). Вне покрытия: реальный e2e-тираж на новом железе (заменён воспроизводимым прогоном smoke-процедуры на staging-песочнице 8501 — AC-3), задачи Lite/Bundled эпика ORCH-10, перенос данных (stateless по решению 10.06). notes: > Имена новых тест-модулей — предложение analyst; developer может переименовать, сохранив покрытие TC. Дефолты всех новых параметров обязаны равняться текущим боевым значениям (AC-2) — тесты фиксируют это явно. Анти-регресс тест судит исполняемый код (комментарии/докстринги исключены) — образец структурных тестов: tests/test_agent_prompts_canon.py. Полный регресс tests/ должен оставаться зелёным; STAGE_TRANSITIONS/QG_CHECKS/check_*/machine-verdict не меняются — новые тесты входят в существующие гейты (check_ci_green) автоматически. tests: - id: TC-01 type: unit description: > Анти-регресс скан: в исполняемом коде src/** и watchdog/** нет запрещённых литералов (82.22.50.71, /home/slin, mva154, duckdns); комментарии/докстринги исключаются; список литералов централизован; allowlist пуст либо каждая запись обоснована (AC-1, AC-7 / FR-6). module: tests/test_no_host_hardcodes.py expected: PASS - id: TC-02 type: unit description: > Негативная самопроверка сканера: подсаженный во временный/фиктивный модуль запрещённый литерал детектируется (сканер реально ловит, не вечно-зелёный) (AC-7 / FR-6, NFR-5). module: tests/test_no_host_hardcodes.py expected: PASS - id: TC-03 type: unit description: > plane_sync.notify_stage_change строит ссылки Branch/PR из settings.gitea_public_url (fallback gitea_url) + settings.gitea_owner; литерал git.mva154.duckdns.org и owner admin из кода удалены; при переопределённых настройках ссылка меняется соответственно (monkeypatch, без сети) (AC-1 / FR-1 A1, FR-2). module: tests/test_host_config_keys.py expected: PASS - id: TC-04 type: unit description: > Env агент-процесса в agents/launcher (оба места запуска): HOME и GIT_AUTHOR/COMMITTER_NAME/EMAIL берутся из settings; дефолты равны прежним значениям (/home/slin, claude-bot@mva154.local); переопределение env-ключей меняет словарь окружения (AC-1, AC-2 / FR-1 A2, FR-2). module: tests/test_host_config_keys.py expected: PASS - id: TC-05 type: unit description: > Env self_deploy (deploy-finalizer) и post_deploy (monitor): HOME и git-идентичность из settings, дефолты = прежним значениям; литералы /home/slin и *@mva154.local из кода удалены (AC-1, AC-2 / FR-1 A3–A4, FR-2). module: tests/test_host_config_keys.py expected: PASS - id: TC-06 type: unit description: > Структурная проверка docker-compose.yml: хост-значения реестра ТЗ §3.1 B (пути /home/slin/*, node/claude-code-пути, gid 999, uid 1000:1000, ssh-user, staging-порт в command) выражены интерполяцией ${VAR:-default}, и дефолты равны текущим значениям; group_add docker-gid присутствует во всех трёх сервисах (инвариант ORCH-040 «МИНА 1») (AC-2, AC-6 / FR-3). module: tests/test_infra_parametrization.py expected: PASS - id: TC-07 type: unit description: > Структурная проверка Dockerfile: uid/gid/username/home параметризованы через ARG с дефолтами 1000/1000/slin//home/slin; решение по CMD-порту соответствует ADR задачи (ARG либо обоснованный дефолт 8500) (AC-2, AC-6 / FR-3, §3.4 А-3). module: tests/test_infra_parametrization.py expected: PASS - id: TC-08 type: unit description: > Полнота .env.example: каждый обязательный для старта ключ присутствует, включая ВСЕ новые ключи FR-2/FR-3 (сверка с Settings.model_fields по выбранному архитектором контракту); секретные ключи содержат только плейсхолдеры, не реальные значения; deploy-hook принимает REPO через env-override (AC-5, AC-6 / FR-1 D1, FR-4.4). module: tests/test_infra_parametrization.py expected: PASS - id: TC-09 type: unit description: > Генератор секретов: два запуска дают различные значения; длина/энтропия webhook-секретов >= 32 байт; существующий .env никогда не перезаписывается молча (запуск при существующем файле -> отказ/явное подтверждение); вывод согласован с ключами .env.example (AC-5 / FR-4, NFR-3). module: tests/test_secrets_gen.py expected: PASS - id: TC-10 type: integration description: > Smoke-обвязка и процедура: deployment-док с пошаговой smoke-процедурой существует и содержит явные PASS/FAIL-критерии каждого шага; если введён скрипт — он запускается без ошибок в безопасном режиме (--help/dry-run, без сети/LLM-расходов); карта env в INFRA.md дополнена; CHANGELOG.md содержит запись ORCH-101 (AC-3, AC-4 / FR-5, FR-7). module: tests/test_replication_smoke.py expected: PASS - id: TC-11 type: unit description: > Инвариант ORCH-058 при исходе А-1: если staging-порт стал конфигуром — дефолт 8501, guard «staging-порт != прод-порт» отвергает совпадение (freshness-путь невозможно нацелить на прод); если остался константой — тест фиксирует константу 8501 и наличие обоснования в ADR задачи (AC-8 / FR-1 A5, NFR-4). module: tests/test_host_config_keys.py expected: PASS - id: TC-12 type: integration description: > Полный регресс: pytest tests/ -q зелёный на дефолтной конфигурации (пустой env) — поведение платформы на текущем хосте 1:1; существующие тесты не правились под задачу (кроме согласованных структурных) (AC-2 / BR-5, NFR-6). module: tests/ expected: PASS