Задача · CI-9 · СРЕЗ 1 · P0 · Done

Nomad-диспатч verify-джобы

Проверка кода перестаёт быть заглушкой: VerificationWorkflow вместо «просто залогировал команду» диспатчит verify-джобу в Nomad, а та исполняет стадии из .meeseeks/project.yml по порядку — lint, затем verify.

Статус: Done (все срезы) · зависит от CI-4,CI-5,NM-1,NM-5 · все задачи · на главную

РЕШЕНО (B213) — проверяет Temporal.

VerificationWorkflow — единственный CI. bash-контур воркера (Claude Code worker, внешний репозиторий, задачи CW-23/24/25) свои гейты как авторитет не исполняет; его push в Forgejo покрывается вебхуком (CI-6, webhook_receiver) → Temporal. Реализация — CI-9-S2 (заглушка → диспатч) + маршрут worker-а через вебхук.

Записано в «Решения» (2026-09-14).

НЕСТЫКОВКА (B219) — открыта: публикация dev-env не сделана.

Решение «публиковать можно» зафиксировано (2026-09-14): добавить цель push-dev-env (два тега — стабильный v0.1.0 + commit-SHA, без :latest) и конвенцию координаты ${REGISTRY_ADDR}/dev-env-<repo>:v0.1.0. Сама публикация и межрепозиторный контракт координаты ещё не реализованы ни в одном репо.

Что это за задача

Сегодня проверка кода — заглушка: VerificationWorkflow читает verify.command из .meeseeks/project.yml и просто логирует его, ничего не исполняя. CI-9 переводит исполнение в Nomad-джобу — как агентов — и учит её гонять стадии из project.yml.

Зависит от: CI-4 (каркас VerificationWorkflow), CI-5 (триггер на верном SHA), NM-1/NM-5 (доставка кода: repo-fetch, read-бот → MinIO).

Зачем Nomad, а не воркер: изоляция. Проверка исполняется в отдельном контейнере, где можно гонять тесты и поднимать докер-контейнеры (dind), не трогая хост и воркер.

Как устроена verify-джоба

Группа verify (nomad/verify.nomad.hcl) — четыре таска в одной bridge-сети:

ТаскРольЧто делает
repo-fetchprestartскачивает снапшот репозитория и распаковывает в alloc dir до старта проверки.
dindprestart-сайдкарпривилегированный docker-демон (docker:27-dind) — чтобы стадии могли собирать контейнеры.
wait-for-dockerdprestartждёт готовности docker-демона; таймаут — отдельный код выхода (112).
verifymainисполняет стадии; образ — dev-env целевого репозитория.
Образ main-таски — dev-env целевого репозитория, а не отдельный «проверяльщик» (A-46): тождественность среды агента и верификатора недостижима, если это разные образы.

Два входа

Вход А · после агента (CI-5)

DevPipeline после успешного шага берёт commit_sha из task_result.json и запускает VerificationWorkflow на проверенном SHA — не на «последнем на ветке».

Вход Б · человек запушил (CI-6)

Приёмник вебхука Forgejo (webhook_receiver.py) стартует VerificationWorkflow на коммите события без участия агента.

Срезы CI-9

Задача разбита на три среза. Все три закрыты — CI-9 Done.

Срез 1 · среда · Done

verify-джоба поднимается в Nomad: repo-fetch распаковывает чекаут, dind-сайдкар отдаёт демон, wait-loop ждёт готовности и отличает недоступность демона от красной стадии кодом выхода. Стадии ещё не исполняются — срез даёт наблюдаемую среду прогона.

Подзадачи CI-9.1, CI-9.2

Срез 2 · перестать быть заглушкой · Done

VerificationWorkflow вместо in-process stub диспатчит verify.nomad.hcl на (repo, ref), идемпотентно по step_id, и ждёт результат по контракту task_result.json/exit_code. Verify-таск исполняет стадии из project.yml по порядку — lint.steps, затем verify.command — и на первой ошибке останавливается, называя упавшую стадию по имени.

Подзадачи CI-9.3, CI-9.4, CI-9.5

Срез 3 · регрессия · Done

Различимость причины красноты доказана прогоном: нарушение lint и провал verify дают разные результаты, чистый репозиторий проходит все стадии. Реестр тесткейсов CI-9 прогоняется целиком.

Подзадача CI-9.6

Подзадачи CI-9

IDСлойЧто делаетЗависит от
CI-9.1Infraverify.nomad.hcl: группа verify (repo-fetch + dind + verify), bridge-сеть.—
CI-9.2InfraWait-loop готовности dockerd в entrypoint; таймаут — отдельный exit code.CI-9.1
CI-9.3Доменparse_project_config расширен: упорядоченный список стадий (lint.steps + verify.command) с именем и командой; test.steps не читается.—
CI-9.4OrchestrationVerificationWorkflow.run() вместо stub диспатчит verify.nomad.hcl (идемпотентно по step_id), ждёт результат по task_result.json/exit_code.CI-9.1, CI-9.3
CI-9.5ДоменПоследовательное исполнение стадий внутри verify-таска; первая ошибка стопит прогон, результат называет упавшую стадию.CI-9.3, CI-9.4
CI-9.6ТестРегрессионный прогон: нарушение lint / провал verify / чистый репозиторий.CI-9.2, CI-9.4, CI-9.5

Тесткейсы

Кейсы, привязанные к CI-9 в листе «Тесткейсы» (колонка «Единица бэклога»):

TC-IDДаноКогдаТогда
TC-CI-9.1-averify.nomad.hcl с группой verify (repo-fetch + dind + wait-for-dockerd + verify)`nomad job run`repo-fetch распаковал тарбол; dind в running; wait-for-dockerd вышел 0; verify стартует
TC-CI-9.2-adind ещё не готовwait-for-dockerd в wait-loop на `docker info`при готовности — код 0, verify стартует; при таймауте — код 112, отличимый от 1 и 0
TC-CI-9.3-aproject.yml с lint.steps и verify.commandparse_project_configупорядоченный список стадий: lint по именам, затем verify, у каждой имя и команда
TC-CI-9.3-bproject.yml без verify.commandparse_project_configMissingVerifyCommandError — поведение не сломано
TC-CI-9.4-aVerificationWorkflow.run() на (repo, ref)шаг исполняетсяverify.nomad.hcl задиспатчена через dispatch_job_with_meta с (repo, ref) в meta; in-process не исполняется
TC-CI-9.4-bта же пара (repo, ref) уже продиспатченаповторный run()диспатч идемпотентен по step_id — второй джобы нет
TC-CI-9.5-aвнесено нарушение lint-стадии (import-linter)verify-таск исполняет стадии по порядкупрогон остановлен на lint, verify.command не запускается; результат называет упавшую стадию
TC-CI-9.6-aрепозиторий с нарушением lint и отдельно с провалом verify, рядом чистыйрегрессионный прогон на трёхоба нарушения красные с различимой причиной; чистый — зелёный

Рамки и решения

Правила, внутри которых делается CI-9 (лист «Архитектура», «Решения»):

Решения CI-9-S2

Три развилки, державшие срез в NeedSpec, закрыты (решения 2026-09-15).

РазвилкаРешение
Runner стадийdocker/verify/run_stages.py запечён в dev-env образ, verify-таск зовёт его как command (nomad/ исключён .dockerignore).
Получение результатаопрос read_alloc_status (обобщён: main_task_name/fetch_task_name/result_file) до терминала; имя упавшей стадии — из result.json.
Источник координатыverify_image в meta — имя без registry, registry подставляет HCL (${REGISTRY_ADDR}/${NOMAD_META_verify_image}); публикация dev-env — push-dev-env (B219 частично: остальные репо — отдельный долг).

Что готово

Готово

  • nomad/verify.nomad.hcl — группа verify (repo-fetch + dind + wait-for-dockerd + verify).
  • Runner docker/verify/run_stages.py — стадии lint.steps → verify по порядку, стоп на первой ошибке.
  • VerificationWorkflow — dispatch_verification (идемпотентно по step_id) + poll до терминала.
  • parse_project_config — упорядоченные стадии (CI-9.3).
  • push-dev-env + DEV_ENV_IMAGE v0.1.0 (B219).
  • Реестр тесткейсов CI-9 (1-a..9.6-a) зелёный: verify-ci9-s3.

Осталось (долг)

  • Публикация dev-env в остальных продуктовых репо (B219 — только mr_meeseeks закрыт).
  • Вход А передаёт плейсхолдер _DEFAULT_VERIFICATION_REPO — источник repo из входа пайплайна.

Связи

Блокирует

CI-7 (commit-status — публиковать нечего, пока нет вердикта), RA-2/RA-3 (ревьюер и гейт «CI зелёный»), CM-3 (стадии import-linter/tach), PL-1 (пилот).

Перед

CI-9-S1 (среда), CI-4/CI-5 (каркас + триггер), NM-1/NM-5 (доставка кода).