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
