Files
orchestrator/docs/work-items/ORCH-101/03-acceptance-criteria.md
claude-bot 69aa6eacde
All checks were successful
CI / test (push) Successful in 1m9s
analyst(ET): auto-commit from analyst run_id=602
2026-06-10 20:02:14 +03:00

14 KiB
Raw Blame History

work_item, stage, author_agent, status, created_at, model_used
work_item stage author_agent status created_at model_used
ORCH-101 analysis analyst ready-for-review 2026-06-10 claude-opus-4-8

03 — Критерии приёмки (Acceptance Criteria): ORCH-101 — ORCH-10-common: расхардкод + секреты + smoke

Work Item: ORCH-101 · Repo: orchestrator · Стадия: analysis

Формат: каждый критерий имеет PASS (что должно быть истинно для приёмки) и FAIL (что считается провалом). Любой машинный/ручной reviewer проверяет их буквально по файлам репозитория. AC-1…AC-4 — дословно из бизнес-запроса (уточнены до проверяемости); AC-5…AC-8 — детализация скоупа (секреты/инфра/анти-регресс/инварианты).


AC-1 — Ноль хардкодов хоста/путей/портов в src/**

Условие: в коде src/** и watchdog/** (вне комментариев/докстрингов) нет хост-специфичных литералов, обходящих конфиг; всё читается из env/конфига с дефолтами. Проверка — grep-тестом (tests/test_no_host_hardcodes.py) и ревью по реестру 02-trz.md §3.1.

  • PASS:
    • блокеры A1A4, A7 реестра закрыты: grep -rn "git.mva154.duckdns.org\|/home/slin\|mva154.local" src/ watchdog/ не находит ни одного вхождения в исполняемом коде (докстринги/комментарии — допустимы);
    • src/plane_sync.py::notify_stage_change строит ссылки Branch/PR из settings.gitea_public_url (fallback gitea_url) и settings.gitea_owner;
    • env-словари акторов (launcher ×2, self_deploy, post_deploy) берут HOME и git-идентичность из settings;
    • A5 (_STAGING_PORT) и A6 (SELF_HOSTING_REPO) либо конфигуризованы, либо явно обоснованы в ADR задачи как платформенные константы (решение архитектора зафиксировано);
    • структурный тест tests/test_no_host_hardcodes.py существует, его allowlist пуст (или каждая запись обоснована комментарием), тест зелёный.
  • FAIL: хотя бы один литерал 82.22.50.71 / /home/slin / mva154 / duckdns в исполняемом коде src/**/watchdog/**; ИЛИ ссылка в Plane-комментарии всё ещё строится от захардкоженного http://git.mva154.duckdns.org; ИЛИ A5/A6 не конфигуризованы и не обоснованы в ADR; ИЛИ анти-регресс тест отсутствует/красный.

AC-2 — Без регресса: на текущем хосте поведение 1:1

Условие: дефолты всех новых параметров равны текущим боевым значениям; pytest зелёный.

  • PASS:
    • каждый новый Settings-ключ / compose-переменная / ARG / shell-default имеет дефолт, равный значению, зашитому до задачи (/home/slin, claude-bot@mva154.local-адреса, gid 999, uid 1000, порты 8500/8501, пути node/claude-code и т.д.);
    • docker compose config без заданных переменных окружения резолвится в эквивалент текущей конфигурации (volumes/user/group_add/environment/command совпадают по значениям);
    • значения существующих дефолтов src/config.py (реестр §3.1 E) не изменены;
    • полный pytest tests/ -q зелёный;
    • STAGE_TRANSITIONS / QG_CHECKS / check_* / machine-verdict ключи / схема БД — без изменений (диф не затрагивает их семантику).
  • FAIL: хотя бы один дефолт отличается от текущего боевого значения; ИЛИ docker compose config при пустом окружении даёт иную эффективную конфигурацию; ИЛИ любой существующий тест красный; ИЛИ диф меняет машину стадий/реестр QG/схему БД.

AC-3 — Smoke-процедура задокументирована и воспроизводима

Условие: существует документированная процедура «развёрнутый инстанс → тестовый проект + задача → конвейер доехал» с явными PASS/FAIL-критериями; воспроизводимость подтверждена.

  • PASS:
    • в docs/operations/ есть раздел/документ (предложение ТЗ: REPLICATION.md) с пошаговой smoke-процедурой: health-check инстанса → тестовый проект → тестовая задача → подтверждение продвижения конвейера (минимум: analysis отработала, артефакты 0104 созданы; расширенный режим — до done);
    • каждый шаг имеет явный ожидаемый результат (PASS/FAIL), итог — однозначный вердикт;
    • процедура не требует переноса данных/секретов с боевого хоста (stateless);
    • воспроизводимость подтверждена хотя бы одним прогоном на текущей инфре (staging-песочница 8501 / sandbox-проект) — результат зафиксирован в артефактах задачи (например, 13-test-report.md / 15-staging-log.md);
    • если введена скрипт-обвязка (scripts/…) — она запускается (--help/dry-run без ошибок) и покрыта тестом из 04-test-plan.yaml.
  • FAIL: процедуры нет; ИЛИ шаги без явных критериев («посмотреть, что всё ок»); ИЛИ процедура требует копирования боевых данных/секретов; ИЛИ заявленный прогон не зафиксирован; ИЛИ скрипт-обвязка падает на запуске.

AC-4 — Доки (deployment-раздел) + CHANGELOG

Условие: документация обновлена в том же PR (правило агентов №2; reviewer проверяет — №6).

  • PASS:
    • deployment-раздел (см. AC-3) дополнительно содержит: карту всех новых env-переменных (имя, назначение, дефолт), процедуру/чек-лист секретов (см. AC-5), границы «10-common vs Lite vs Bundled»;
    • карта переменных окружения в docs/operations/INFRA.md дополнена новыми ключами;
    • CHANGELOG.md содержит запись ORCH-101;
    • CLAUDE.md/README.md обновлены, если фактический объём изменений того требует (новые операторские способности/ограничения).
  • FAIL: новый env-ключ отсутствует в карте env; ИЛИ нет записи в CHANGELOG.md; ИЛИ deployment-раздел не покрывает секреты/smoke; ИЛИ README выдаёт решённое за открытое (правило №6).

AC-5 — Секреты: генерация новых, не копирование боевых

Условие: механизм выпуска нового комплекта секретов на новом хосте существует и безопасен.

  • PASS:
    • webhook-секреты (ORCH_PLANE_WEBHOOK_SECRET, ORCH_GITEA_WEBHOOK_SECRET) генерируются криптослучайно (≥ 32 байт энтропии; повторный запуск даёт другие значения);
    • механизм никогда не перезаписывает существующий .env молча;
    • чек-лист перечисляет все внешние токены (ORCH_PLANE_API_TOKEN, ORCH_PLANE_BOT_*, ORCH_GITEA_TOKEN, ORCH_TELEGRAM_BOT_TOKEN) с указанием, где их выпустить и куда вписать; явно сказано «боевые секреты не копируются»;
    • .env.example покрывает 100% ключей, обязательных для старта (включая новые из AC-1/AC-2), секретные значения — только плейсхолдеры; реальные секреты в гит не попадают (.gitleaks/security-гейт зелёный);
    • .env.staging.example согласован (если затронут).
  • FAIL: секрет генерируется детерминированно/слабо; ИЛИ запуск механизма затирает существующий .env; ИЛИ в .env.example отсутствует обязательный ключ; ИЛИ в гит закоммичено реальное секретное значение; ИЛИ процедура предписывает копирование боевого секрета.

AC-6 — Инфра-файлы параметризованы

Условие: docker-compose.yml, Dockerfile, scripts/orchestrator-deploy-hook.sh не требуют правки под новый хост — только переменные.

  • PASS:
    • реестр §3.1 B/C/D закрыт: пути /home/slin/..., gid 999, uid 1000:1000, node/claude-code-пути, ssh-user, staging-порт в command:, REPO= в deploy-hook — параметризованы (${VAR:-default} / ARG / "${REPO:-…}") с дефолтами = текущим значениям;
    • связка «uid/gid/HOME/маунты .claude+.ssh/useradd» меняется согласованной группой переменных (инвариант ORCH-040 сохранён, group_add docker-gid не удалён);
    • структурный тест параметризации (TC-06/TC-12 из 04-test-plan.yaml) зелёный.
  • FAIL: хотя бы одно значение реестра B/C/D осталось непараметризованным; ИЛИ группа ORCH-040 рассогласована (HOME ≠ маунт-таргеты при дефолтах); ИЛИ group_add удалён; ИЛИ структурный тест красный.

AC-7 — Анти-регресс защита от возврата хардкодов

Условие: возврат хост-хардкода в src/** ломает CI.

  • PASS: tests/test_no_host_hardcodes.py существует; сканирует src/**+watchdog/** на централизованный список запрещённых литералов (минимум: 82.22.50.71, /home/slin, mva154, duckdns); исключает комментарии/докстринги/tests/**/docs/**; детерминирован (повторные прогоны стабильны); демонстрационно ловит подсадку литерала (негативная самопроверка в самом тесте или в тестах теста).
  • FAIL: тест отсутствует; ИЛИ не ловит подсаженный в код литерал из списка; ИЛИ флапает; ИЛИ список литералов размазан по нескольким местам без единой точки правки.

AC-8 — Self-hosting безопасность и инварианты соседних задач

Условие: задача не дестабилизирует общий прод и не ослабляет зафиксированные инварианты.

  • PASS:
    • в рамках задачи прод-контейнер orchestrator не перезапускается; прод-деплой — только штатно (staging 8501 → ручной Confirm Deploy);
    • инвариант ORCH-058 сохранён: freshness/staging-путь не может быть переконфигурирован в прод-таргет (guard «staging-порт ≠ прод-порт» при конфигуризации A5 — либо A5 остался константой по ADR);
    • INV-4 сохранён (никаких push/force-push в main мимо PR-merge API);
    • маркеры ORCH-NNN в правленых блоках сохранены/обновлены корректно (правило №9).
  • FAIL: диф содержит рестарт/останов прод-контейнера вне штатного деплой-пути; ИЛИ конфигурацией можно нацелить staging-rebuild на прод-порт; ИЛИ нарушен INV-4; ИЛИ правка помеченного блока стёрла инвариант соседнего ADR.

Сводная матрица AC ↔ BR/FR

AC Покрывает
AC-1 BR-1 / FR-1, FR-2, FR-6
AC-2 BR-5 / FR-1 (реестр E), FR-2, FR-3, NFR-6
AC-3 BR-4 / FR-5
AC-4 BR-7 / FR-7
AC-5 BR-3 / FR-4, NFR-3
AC-6 BR-2 / FR-3, NFR-4
AC-7 BR-6 / FR-6, NFR-5
AC-8 NFR-1, NFR-2, NFR-4 / FR-3