Зоны ответственности
- OpenClaw (
extensions/qa-lab/src/mantis/*): среда выполнения сценариев, CLIpnpm openclaw qa mantis <command>, схема свидетельств. - QA Lab (
extensions/qa-lab/src/live-transports/*): среда тестирования реальных транспортов, боты драйвера/SUT, средства записи отчётов и свидетельств. - Crabbox (
openclaw/crabbox): прогретые машины Linux, аренда, VNC,crabbox media preview. - GitHub Actions (
.github/workflows/mantis-*.yml): удалённые точки входа, хранение артефактов. - ClawSweeper: анализирует команды сопровождающих в PR, запускает рабочие процессы, публикует итоговый комментарий к PR.
Команды CLI
Все команды определены вpnpm openclaw qa mantis <command>,
extensions/qa-lab/src/mantis/cli.ts. Во время сборки/запуска требуется OPENCLAW_ENABLE_PRIVATE_QA_CLI=1
(встроенные рабочие процессы задают OPENCLAW_BUILD_PRIVATE_QA=1 и
OPENCLAW_ENABLE_PRIVATE_QA_CLI=1 перед сборкой).
Каждая команда принимает
--repo-root <path> и --output-dir <path>; команды Crabbox
также принимают --crabbox-bin, --provider, --machine-class/--class,
--lease-id, --idle-timeout, --ttl и --keep-lease. Локальные значения CLI по умолчанию
для провайдера/класса — hetzner/beast, если не указано иное; рабочие процессы CI
обычно переопределяют оба значения.
discord-smoke
https://discord.com/api/v10), чтобы получить данные
пользователя-бота, сервера, каналов сервера и целевого канала, проверяет,
что канал принадлежит серверу, затем (если не указан --skip-post) публикует сообщение и
добавляет реакцию 👀. Записывает mantis-discord-smoke-summary.json и
mantis-discord-smoke-report.md.
Порядок получения токена: значение --token-file, затем OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN
(переопределяется через --token-env), затем файл, указанный в OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN_FILE
(переопределяется через --token-file-env). Идентификаторы сервера/канала берутся из
OPENCLAW_QA_DISCORD_GUILD_ID / OPENCLAW_QA_DISCORD_CHANNEL_ID (переопределяются через
--guild-id / --channel-id) и должны быть 17–20-значными snowflake-идентификаторами Discord. Задайте
OPENCLAW_QA_REDACT_PUBLIC_METADATA=1, чтобы заменить идентификаторы
и имена бота/сервера/канала/сообщения на <redacted> в публикуемой сводке и отчёте.
run
--transport сейчас принимает только discord. --scenario — один из двух
встроенных идентификаторов, каждый со своей базовой ссылкой по умолчанию и ожидаемыми метками «до/после»
(extensions/qa-lab/src/mantis/run.runtime.ts):
Значение
--candidate по умолчанию — HEAD. Другие флаги: --credential-source
(по умолчанию convex), --credential-role (по умолчанию ci), --provider-mode
(по умолчанию live-frontier), --fast (по умолчанию включён), --skip-install, --skip-build.
Средство запуска создаёт отсоединённые рабочие деревья git worktree для базового
и проверяемого вариантов в <output-dir>/worktrees/, выполняет pnpm install/pnpm build в
каждом из них (если этап не пропущен), а затем запускает
pnpm openclaw qa discord --scenario <id> --model openai/gpt-5.4 --alt-model openai/gpt-5.4 --allow-failures
для каждого рабочего дерева. Каждый поток записывает discord-qa-reaction-timelines.json
и пару <scenario-id>-timeline.html/.png; средство запуска копирует эти
свидетельства обратно в baseline//candidate/, записывает comparison.json,
mantis-report.md и mantis-evidence.json в выходной каталог и
завершается с ненулевым кодом, если сравнение не пройдено (базовый вариант fail, а проверяемый —
pass).
Второй сценарий Discord (discord-thread-reply-filepath-attachment) публикует
родительское сообщение с помощью бота-драйвера, создаёт реальную ветку, вызывает действие SUT
message.thread-reply с локальным для репозитория filePath, а затем опрашивает
ветку в ожидании ответа и имени файла вложения. Ожидается вложение
с именем mantis-thread-report.md.
desktop-browser-smoke
--browser-url (по умолчанию https://openclaw.ai) или отрисованный
--html-file, ожидает, делает снимок экрана с помощью scrot, при необходимости записывает MP4 с помощью
ffmpeg и синхронизирует через rsync файлы desktop-browser-smoke.png / .mp4 / remote-metadata.json
обратно в --output-dir.
Флаги:
--lease-id <cbx_...>повторно использует прогретый рабочий стол вместо создания нового.--browser-profile-dir <remote-path>повторно использует удалённый каталог пользовательских данных Chrome, чтобы постоянный рабочий стол сохранял авторизацию между запусками (используется для долгоживущего профиля просмотра Discord Web).--browser-profile-archive-env <name>перед запуском восстанавливает из этой переменной среды закодированный в base64 архив профиля Chrome.tgz(по умолчаниюOPENCLAW_MANTIS_BROWSER_PROFILE_TGZ_B64); используется для авторизованных средств визуального подтверждения, таких как Discord Web.--video-duration <seconds>управляет длительностью записи MP4 (по умолчанию 10s).--keep-lease(илиOPENCLAW_MANTIS_KEEP_VM=1) оставляет аренду, созданную во время этого запуска, открытой для проверки через VNC; неудачные запуски, создавшие аренду, также по умолчанию оставляют её открытой.
qa discord) остаётся авторитетным источником; когда
задан OPENCLAW_QA_DISCORD_CAPTURE_UI_METADATA=1, сценарий также записывает
артефакт с URL Discord Web, а OPENCLAW_QA_DISCORD_KEEP_THREADS=1 оставляет
ветку открытой достаточно долго, чтобы браузер успел её открыть.
Рабочий процесс GitHub предпочитает постоянный профиль просмотра через
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR (полные архивы профилей могут превышать
ограничение GitHub на размер секрета); для небольших/начальных профилей вместо этого можно восстановить
закодированный в base64 .tgz из MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64. Если
не настроен ни один источник, рабочий процесс всё равно публикует детерминированные
снимки экрана базового и проверяемого вариантов и записывает в журнал, что авторизованное визуальное подтверждение
пропущено.
slack-desktop-smoke
pnpm openclaw qa slack, открывает Slack Web в браузере VNC,
записывает рабочий стол и копирует локально как артефакты QA Slack (slack-qa/), так и
снимок экрана/видео VNC. Это единственная конфигурация Mantis, в которой
Gateway SUT и браузер работают внутри одной ВМ.
При использовании --gateway-setup команда создаёт постоянный одноразовый домашний каталог OpenClaw
в $HOME/.openclaw-mantis/slack-openclaw внутри ВМ, изменяет конфигурацию Slack
Socket Mode для целевого канала, запускает
openclaw gateway run --dev --allow-unconfigured --port 38973 и оставляет
Chrome запущенным в сеансе VNC; если --gateway-setup не указан, вместо этого запускается обычный
поток QA Slack «бот-бот».
Обязательные переменные среды для --credential-source env (локальное значение по умолчанию — env; роль
по умолчанию — maintainer):
OPENCLAW_QA_SLACK_CHANNEL_IDOPENCLAW_QA_SLACK_DRIVER_BOT_TOKENOPENCLAW_QA_SLACK_SUT_BOT_TOKENOPENCLAW_QA_SLACK_SUT_APP_TOKENOPENCLAW_LIVE_OPENAI_KEYдля удалённого потока модели (если локально задан толькоOPENAI_API_KEY, Mantis копирует его вOPENCLAW_LIVE_OPENAI_KEYперед вызовом Crabbox)
--credential-source convex Mantis арендует учётные данные SUT Slack из
общего пула перед созданием ВМ и передаёт идентификатор канала, токен приложения и
токен бота в ВМ как переменные среды OPENCLAW_MANTIS_SLACK_*, поэтому рабочим процессам GitHub
нужен только секрет брокера Convex, а не необработанные токены Slack.
Другие флаги: --slack-url <url> открывает указанный URL (иначе Mantis получает
https://app.slack.com/client/<team>/<channel> из auth.test);
--slack-channel-id <id> задаёт разрешённый канал Gateway;
OPENCLAW_MANTIS_SLACK_BROWSER_PROFILE_DIR управляет постоянным профилем Chrome
внутри ВМ (по умолчанию $HOME/.config/openclaw-mantis/slack-chrome-profile);
--approval-checkpoints запускает нативные сценарии подтверждения Slack
(slack-approval-exec-native, slack-approval-plugin-native) и отрисовывает
снимки экрана контрольных точек в состояниях ожидания/завершения вместо настройки Gateway (взаимоисключающий
с --gateway-setup); --hydrate-mode source|prehydrated,
--provider-mode, --model, --alt-model и --fast передаются в
реальный поток Slack.
Снимки экрана контрольных точек подтверждения отрисовываются из сообщения Slack API, которое
наблюдал сценарий, а не из реального интерфейса Slack; slack-desktop-smoke.png служит только
подтверждением самого Slack Web, если в профиле браузера арендованной машины уже выполнен вход.
telegram-desktop-builder
openclaw gateway run --dev --allow-unconfigured --port 38974, публикует
сообщение бота-драйвера о готовности в арендованной закрытой группе, а затем записывает
снимок экрана и MP4. Токен бота только настраивает OpenClaw; он никогда не выполняет вход
в Telegram Desktop. Средство просмотра на рабочем столе использует отдельный пользовательский сеанс Telegram,
восстановленный из --telegram-profile-archive-env <name> или созданный вручную
через VNC и сохраняемый с помощью --keep-lease.
Флаги: --lease-id <cbx_...> повторно запускает сценарий в ВМ, где уже выполнен вход в
Telegram Desktop; --telegram-profile-archive-env <name> перед запуском восстанавливает закодированный в base64
архив профиля .tgz; --telegram-profile-dir <remote-path>
задаёт удалённый каталог профиля (по умолчанию $HOME/.local/share/TelegramDesktop);
--no-gateway-setup только устанавливает и открывает Telegram Desktop;
значения --credential-source/--credential-role по умолчанию — convex/maintainer.
Манифест свидетельств
Каждый сценарий, публикующий результаты в PR, записываетmantis-evidence.json рядом со
своим отчётом:
path задаётся относительно каталога манифеста; targetPath —
относительно настроенного префикса артефактов R2/S3. scripts/mantis/publish-pr-evidence.mjs
отклоняет обход каталогов и пропускает записи с "required": false, если
файл отсутствует.
Виды артефактов: timeline (детерминированный снимок экрана до/после),
desktopScreenshot (снимок экрана VNC/браузера), motionPreview (встроенный анимированный
GIF из записи), motionClip (MP4 с удалёнными фрагментами без движения), fullVideo (полная
запись), metadata (сопутствующий файл JSON/журнала), report (отчёт Markdown).
Структура артефактов запуска на диске:
OPENCLAW_QA_REDACT_PUBLIC_METADATA=1
для общедоступной загрузки артефактов; этот параметр по умолчанию
включён в рабочих процессах GitHub для Discord/Slack/Telegram.
Автоматизация GitHub
scripts/mantis/publish-pr-evidence.mjs — переиспользуемый инструмент публикации. Рабочие процессы
вызывают его с манифестом, целевым PR, корневым целевым каталогом артефактов, маркером
комментария, URL артефакта, URL запуска и источником запроса. Он загружает объявленные
артефакты в бакет Mantis R2, формирует комментарий к PR, начинающийся со сводки, со встроенными
изображениями/предпросмотрами и ссылками на видео, а затем обновляет существующий комментарий
с маркером или создаёт новый. Обязательные переменные окружения:
MANTIS_ARTIFACT_R2_ACCESS_KEY_IDMANTIS_ARTIFACT_R2_SECRET_ACCESS_KEYMANTIS_ARTIFACT_R2_BUCKET(рабочие процессы задаютopenclaw-crabbox-artifacts)MANTIS_ARTIFACT_R2_ENDPOINTMANTIS_ARTIFACT_R2_REGION(рабочие процессы задаютauto)MANTIS_ARTIFACT_R2_PUBLIC_BASE_URL(рабочие процессы задаютhttps://artifacts.openclaw.ai)
MANTIS_GITHUB_APP_ID /
MANTIS_GITHUB_APP_PRIVATE_KEY), а не через github-actions[bot]; в качестве ключа
обновления или вставки используется скрытый комментарий-маркер.
Mantis Discord Status Reactions и Mantis Telegram Live принимают
baseline_ref/candidate_ref (либо baseline=/candidate= в комментарии к PR)
и перед запуском с учётными данными, содержащими секреты, проверяют, что разрешённый SHA
является либо предком origin/main, либо тегом выпуска (v*),
либо вершиной открытого PR.
Триггеры в комментариях к PR с доступом на запись, сопровождение или администрирование:
telegram-status-command как сценарий; они принимают provider=aws|hetzner и
lease=<cbx_...>, чтобы выбрать конкретного поставщика Crabbox или предварительно
прогретый рабочий стол. Mantis Telegram Desktop Proof отвечает на комментарий к PR, только если
у PR уже есть метка mantis: telegram-visible-proof.
Триггеры чата веб-интерфейса в комментариях по умолчанию используют SHA вершины PR как
проверяемый вариант. Они запускают проверку чата Control UI с имитированным Gateway и
публикуют браузерные артефакты; для других веб-страниц и поверхностей нативного приложения
используйте обычную проверку Playwright/браузера, снимки экрана от сопровождающего, Crabbox
или локальные артефакты.
ClawSweeper также может запустить сценарий напрямую:
Машины и секреты
По умолчанию локальный CLI Crabbox использует--provider hetzner --class beast; это можно переопределить
с помощью --provider, --class/--machine-class или
OPENCLAW_MANTIS_CRABBOX_PROVIDER / OPENCLAW_MANTIS_CRABBOX_CLASS. Рабочие процессы GitHub
часто переопределяют оба параметра (например, --class standard, а также входной параметр
выбора поставщика aws/hetzner в рабочем процессе Slack). Если
поставщик работает слишком медленно или недоступен, добавьте его через тот же интерфейс
Crabbox вместо жёстко заданного резервного варианта.
Базовая конфигурация виртуальной машины: Linux с поддерживающим рабочий стол Chrome/Chromium,
доступом CDP, VNC/noVNC, Node 22.22.3+, 24.15+ или 25.9+ и pnpm, рабочей копией OpenClaw,
а также исходящим доступом к целевому транспорту, GitHub, поставщикам моделей и брокеру
учётных данных.
Имена учётных данных и переменных окружения, используемые командами и рабочими процессами Mantis:
OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKENOPENCLAW_QA_DISCORD_GUILD_IDOPENCLAW_QA_DISCORD_CHANNEL_ID- Локальному
qa mantis run --credential-source envтакже требуютсяOPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN,OPENCLAW_QA_DISCORD_SUT_BOT_TOKENиOPENCLAW_QA_DISCORD_SUT_APPLICATION_ID. Рабочие процессы GitHub обычно используют--credential-source convexи приведённые ниже учётные данные брокера вместо необработанных токенов бота Discord. OPENCLAW_QA_REDACT_PUBLIC_METADATA=1для общедоступной загрузки артефактовOPENCLAW_QA_CONVEX_SITE_URL,OPENCLAW_QA_CONVEX_SECRET_CIOPENAI_API_KEY(либо предназначенный для проверки Telegram DesktopOPENCLAW_MANTIS_AGENT_OPENAI_API_KEY)CRABBOX_COORDINATOR/CRABBOX_COORDINATOR_TOKEN(рабочие процессы также принимаютOPENCLAW_QA_MANTIS_CRABBOX_COORDINATOR/_TOKENкак резервный вариант и сопоставляют их с обычными именами перед вызовом Crabbox)CRABBOX_ACCESS_CLIENT_ID,CRABBOX_ACCESS_CLIENT_SECRETMANTIS_GITHUB_APP_ID,MANTIS_GITHUB_APP_PRIVATE_KEY
Результаты запусков
Сценарии транспорта до/после различают следующие результаты, чтобы нестабильность окружения не воспринималась как регрессия продукта:- Ошибка воспроизведена: базовый вариант завершился сбоем ожидаемым сценарием образом.
- Сбой тестовой системы: произошёл сбой настройки окружения, учётных данных, API транспорта, браузера или поставщика до того, как критерий проверки получил значимый результат.
Добавление сценария
Оперативные транспортные сценарии определяются на TypeScript отдельно для каждого транспорта (пример структуры до/после для Discord см. вMANTIS_SCENARIO_CONFIGS в extensions/qa-lab/src/mantis/run.runtime.ts),
а не в отдельном декларативном формате файлов. Для каждого сценария требуются:
идентификатор и название, транспорт, необходимые учётные данные, политика ссылки на базовый
вариант, политика ссылки на проверяемый вариант, исправление конфигурации OpenClaw, этапы
настройки и воздействия, ожидаемые критерии проверки базового и проверяемого вариантов,
цели визуального захвата, лимит времени и этапы очистки.
Для целевой проверки в браузере только проверяемого варианта можно использовать отдельный
детерминированный тест E2E и рабочий процесс. Явно ограничьте его область, проверяйте ссылку
на проверяемый вариант перед выполнением, изолируйте публикацию с секретами и создавайте
манифест доказательств по тому же контракту.
Предпочитайте небольшие типизированные критерии проверки визуальному анализу: состояние
реакций или ссылки на сообщения Discord, состояние API реакции/ts цепочки Slack,
идентификаторы и заголовки сообщений электронной почты. Используйте снимки экрана браузера,
когда интерфейс — единственный надёжно наблюдаемый источник, а визуальные проверки делайте
дополнительными к критерию на основе API платформы, если такой критерий существует.
После Discord, Slack и Telegram ту же структуру средства запуска можно распространить на
WhatsApp (вход по QR-коду, повторная идентификация, доставка, медиафайлы, реакции) и Matrix
(зашифрованные комнаты, связи цепочек/ответов, возобновление после перезапуска); ни один из
этих вариантов пока не реализован.
Открытые вопросы
- Какой бот Discord должен быть драйвером, а какой — SUT при повторном использовании существующего бота Mantis?
- Как долго GitHub должен хранить артефакты Mantis для PR?
- Когда ClawSweeper должен автоматически рекомендовать сценарий Mantis, а не ждать команды сопровождающего?
- Следует ли ретушировать или обрезать снимки экрана перед загрузкой в публичные PR?