14 KiB
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:
- блокеры A1–A4, 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(fallbackgitea_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 пуст (или каждая запись обоснована комментарием), тест зелёный.
- блокеры A1–A4, A7 реестра закрыты:
- 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отработала, артефакты01–04созданы; расширенный режим — до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согласован (если затронут).
- webhook-секреты (
- FAIL: секрет генерируется детерминированно/слабо; ИЛИ запуск механизма затирает существующий
.env; ИЛИ в.env.exampleотсутствует обязательный ключ; ИЛИ в гит закоммичено реальное секретное значение; ИЛИ процедура предписывает копирование боевого секрета.
AC-6 — Инфра-файлы параметризованы
Условие: docker-compose.yml, Dockerfile, scripts/orchestrator-deploy-hook.sh не требуют
правки под новый хост — только переменные.
- PASS:
- реестр §3.1 B/C/D закрыт: пути
/home/slin/..., gid999, uid1000:1000, node/claude-code-пути, ssh-user, staging-порт вcommand:,REPO=в deploy-hook — параметризованы (${VAR:-default}/ARG/"${REPO:-…}") с дефолтами = текущим значениям; - связка «uid/gid/HOME/маунты
.claude+.ssh/useradd» меняется согласованной группой переменных (инвариант ORCH-040 сохранён,group_adddocker-gid не удалён); - структурный тест параметризации (TC-06/TC-12 из
04-test-plan.yaml) зелёный.
- реестр §3.1 B/C/D закрыт: пути
- 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 |