extensions/qa-channel: синтетический канал сообщений с поверхностями личных сообщений, каналов, тредов, реакций, редактирования и удаления.extensions/qa-lab: отладочный UI и шина QA для наблюдения за транскриптом, внедрения входящих сообщений и экспорта Markdown-отчета.extensions/qa-matrix, будущие Plugin раннеров: адаптеры живых транспортов, которые управляют реальным каналом внутри дочернего QA gateway.qa/: seed-ресурсы из репозитория для стартовой задачи и базовых QA-сценариев.- Mantis: проверка до и после вживую для ошибок, которым нужны реальные транспорты, скриншоты браузера, состояние VM и доказательства для PR.
Поверхность команд
Каждый QA-поток выполняется черезpnpm openclaw qa <subcommand>. У многих есть
алиасы скриптов pnpm qa:*; поддерживаются обе формы.
qa run на основе профиля читает состав из taxonomy.yaml, затем отправляет
разрешенные сценарии через qa suite. --surface и
--category фильтруют выбранный профиль, а не определяют отдельные линии.
Итоговый qa-evidence.json включает сводку scorecard профиля с
количеством выбранных категорий и отсутствующими ID покрытия; отдельные записи
доказательств остаются источником истины для тестов, ролей покрытия и результатов.
ID покрытия возможностей таксономии являются точными целями доказательства, а не алиасами. Основное
покрытие сценариев выполняет совпадающие ID; вторичное покрытие остается рекомендационным.
ID покрытия используют dotted-форму namespace.behavior со строчными
буквенно-цифровыми сегментами или сегментами с дефисами; ID профиля, поверхности и категории могут по-прежнему использовать
существующие dashed или dotted ID таксономии.
Slim-доказательства опускают execution для каждой записи и задают evidenceMode: "slim";
smoke-ci по умолчанию использует slim, а --evidence-mode full восстанавливает полные записи:
smoke-ci для детерминированного доказательства профиля с mock model providers и
локальными серверами provider Crabline. Используйте release для доказательства Stable/LTS против живых
каналов. Используйте all только для явных запусков доказательств по всей таксономии; он выбирает
каждую активную категорию зрелости и может быть отправлен через workflow QA Profile Evidence с qa_profile=all. Когда команде также нужен корневой профиль OpenClaw,
поместите корневой профиль перед командой QA:
Поток оператора
Текущий операторский поток QA — это двухпанельный сайт QA:- Слева: Gateway dashboard (Control UI) с агентом.
- Справа: QA Lab, показывающая похожий на Slack транскрипт и план сценария.
qa:lab:up:fast оставляет Docker-сервисы на предварительно собранном образе и монтирует через bind
extensions/qa-lab/web/dist в контейнер qa-lab. qa:lab:watch
пересобирает этот bundle при изменениях, а браузер автоматически перезагружается, когда меняется
asset hash QA Lab.
Для локального smoke сигнала OpenTelemetry выполните:
otel-trace-smoke
с включенным Plugin diagnostics-otel, затем проверяет, что traces,
metrics и logs экспортированы. Он декодирует экспортированные protobuf trace spans
и проверяет критичную для релиза форму:
openclaw.run, openclaw.harness.run, span вызова модели по последней semantic convention GenAI,
openclaw.context.assembled и openclaw.message.delivery
должны присутствовать. Smoke принудительно задает
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental, поэтому span вызова модели
должен использовать имя {gen_ai.operation.name} {gen_ai.request.model};
вызовы модели не должны экспортировать StreamAbandoned при успешных turns; raw diagnostic IDs и
атрибуты openclaw.content.* не должны попадать в trace. Raw OTLP
payloads не должны содержать prompt sentinel, response sentinel или ключ QA-сессии.
Он записывает otel-smoke-summary.json рядом с артефактами QA suite.
Для smoke OpenTelemetry на базе collector выполните:
docker-prometheus-smoke с включенным
diagnostics-prometheus, проверяет, что неаутентифицированные scrape-запросы отклоняются,
а затем проверяет, что аутентифицированный scrape включает критичные для релиза семейства метрик
без содержимого prompt, содержимого ответа, сырых диагностических идентификаторов, токенов
аутентификации или локальных путей.
Чтобы запустить обе дымовые проверки наблюдаемости подряд, используйте:
qa. Используйте
pnpm qa:otel:smoke, pnpm qa:prometheus:smoke или
pnpm qa:observability:smoke из собранного исходного checkout при изменении
диагностической инструментации.
Для транспортно-реальной дымовой линии Matrix, которой не требуются учетные данные
провайдера модели, запустите быстрый профиль с детерминированным mock-провайдером OpenAI:
qa-channel), затем записывает Markdown-отчет, JSON-сводку, артефакт наблюдаемых событий и объединенный журнал вывода в .artifacts/qa-e2e/matrix-<timestamp>/.
Сценарии покрывают поведение транспорта, которое модульные тесты не могут доказать от начала до конца: фильтрация по упоминаниям, политики allow-bot, списки разрешенных, ответы верхнего уровня и ответы в тредах, маршрутизацию DM, обработку реакций, подавление входящих правок, дедупликацию replay после перезапуска, восстановление после прерывания homeserver, доставку метаданных approval, обработку медиа и потоки bootstrap/recovery/verification для Matrix E2EE. Профиль CLI для E2EE также прогоняет команды openclaw matrix encryption setup и команды верификации через тот же одноразовый homeserver перед проверкой ответов Gateway.
У Discord также есть opt-in-сценарии только для Mantis для воспроизведения багов. Используйте
--scenario discord-status-reactions-tool-only для явной временной шкалы статусных реакций
или --scenario discord-thread-reply-filepath-attachment, чтобы создать реальный тред Discord
и проверить, что message.thread-reply сохраняет вложение filePath. Эти сценарии не входят
в стандартную живую линию Discord, потому что это probes для воспроизведения до/после, а не
широкое дымовое покрытие. Mantis workflow для вложений в тредах также может добавить видео
свидетеля из Discord Web с выполненным входом, когда MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR или
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64 настроены в QA-окружении. Этот профиль viewer
используется только для визуального захвата; решение pass/fail по-прежнему приходит от
Discord REST-оракула.
CI использует ту же командную поверхность в .github/workflows/qa-live-transports-convex.yml.
Запуски по расписанию и стандартные ручные запуски выполняют быстрый профиль Matrix с
предоставленными QA учетными данными live-frontier, --fast и
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000. Ручной matrix_profile=all разворачивается
в пять profile shards.
Для транспортно-реальных дымовых линий Telegram, Discord, Slack и WhatsApp:
slack-qa/, slack-desktop-smoke.png и slack-desktop-smoke.mp4, когда видеозахват
доступен, обратно в каталог артефактов Mantis. Аренды Crabbox desktop/browser заранее
предоставляют инструменты захвата и вспомогательные пакеты browser/native-build, поэтому
сценарий должен устанавливать fallback-пакеты только на старых арендах. Mantis сообщает
общее время и время по фазам в mantis-slack-desktop-smoke-report.md, чтобы медленные
запуски показывали, куда ушло время: на прогрев аренды, получение учетных данных,
удаленную настройку или копирование артефактов. Повторно используйте --lease-id <cbx_...>
после ручного входа в Slack Web через VNC; повторно используемые аренды также сохраняют
теплым pnpm store cache Crabbox. Стандартный --hydrate-mode source проверяет из исходного
checkout и запускает install/build внутри VM. Используйте --hydrate-mode prehydrated только
когда повторно используемое удаленное рабочее пространство уже содержит node_modules и
собранный dist/; этот режим пропускает дорогой шаг install/build и fail-closed, если
рабочее пространство не готово. С --gateway-setup Mantis оставляет постоянный OpenClaw
Slack Gateway, работающий внутри VM на порту 38973; без него команда запускает обычную
bot-to-bot линию Slack QA и выходит после захвата артефактов.
Чтобы доказать нативный UI approval в Slack с desktop-доказательствами, запустите checkpoint-режим approval в Mantis:
--gateway-setup. Он запускает сценарии approval в Slack,
отклоняет id сценариев не для approval, ожидает каждого pending и resolved состояния approval,
рендерит наблюдаемое сообщение Slack API в
approval-checkpoints/<scenario>-pending.png и
approval-checkpoints/<scenario>-resolved.png, затем падает, если любой checkpoint,
доказательство сообщения, acknowledgement или отрендеренный screenshot отсутствует или пуст.
Холодные CI-аренды все еще могут показывать вход в Slack в slack-desktop-smoke.png;
изображения approval checkpoint являются визуальным доказательством для этой линии.
Операторский checklist, команда GitHub workflow dispatch, контракт evidence-comment,
таблица принятия решений по hydrate-mode, интерпретация timing и шаги обработки ошибок
находятся в runbook Mantis Slack Desktop.
Для desktop-задачи в стиле agent/CV выполните:
visual-task арендует или повторно использует desktop/browser машину Crabbox, запускает
crabbox record --while, управляет видимым браузером через вложенный
visual-driver, захватывает visual-task.png, запускает openclaw infer image describe
для screenshot, когда выбран --vision-mode image-describe, и записывает
visual-task.mp4, mantis-visual-task-summary.json,
mantis-visual-task-driver-result.json и mantis-visual-task-report.md.
Когда задан --expect-text, vision prompt запрашивает структурированный JSON-вердикт
и проходит только когда модель сообщает положительное видимое доказательство; отрицательный
ответ, который лишь цитирует целевой текст, проваливает assertion.
Используйте --vision-mode metadata для дымовой проверки без модели, которая доказывает
связку desktop, browser, screenshot и video без вызова провайдера понимания изображений.
Recording является обязательным артефактом для visual-task; если Crabbox не записывает
непустой visual-task.mp4, задача падает, даже когда visual driver прошел. При ошибке
Mantis сохраняет аренду для VNC, если только задача уже не прошла и --keep-lease не был задан.
Перед использованием pooled live credentials выполните:
Покрытие живых транспортов
Линии живых транспортов используют один общий контракт, вместо того чтобы каждая изобретала собственную форму списка сценариев.qa-channel — это широкий синтетический набор продуктового поведения и не является частью матрицы покрытия живых транспортов.
Runners живого транспорта должны импортировать общие ids сценариев, helpers
baseline-покрытия и helper выбора сценариев из
openclaw/plugin-sdk/qa-live-transport-scenarios.
Это сохраняет
qa-channel как широкий набор продуктового поведения, пока Matrix,
Telegram и другие живые транспорты совместно используют один явный checklist транспортного контракта.
Для одноразовой линии Linux VM без добавления Docker в QA-путь выполните:
qa suite, затем копирует обычный QA-отчет и
сводку обратно в .artifacts/qa-e2e/... на host.
Она повторно использует то же поведение выбора сценариев, что и qa suite на host.
Запуски suite на host и Multipass по умолчанию выполняют несколько выбранных сценариев
параллельно с изолированными workers Gateway. qa-channel по умолчанию использует concurrency
4, ограниченную количеством выбранных сценариев. Используйте --concurrency <count> для настройки
количества workers или --concurrency 1 для последовательного выполнения.
Используйте --pack personal-agent, чтобы запустить benchmark pack персонального ассистента. Селектор
pack является аддитивным с повторяющимися флагами --scenario: явные сценарии
запускаются первыми, затем сценарии pack запускаются в порядке pack с удалением дубликатов.
Используйте --pack observability, когда пользовательский QA runner уже предоставляет настройку
OpenTelemetry collector и хочет выбрать вместе дымовые диагностические сценарии OpenTelemetry и Prometheus.
Команда завершается с ненулевым кодом, когда любой сценарий падает. Используйте --allow-failures, когда
нужны артефакты без ошибочного exit code.
Живые запуски передают поддерживаемые входные данные QA auth, практичные для
guest: provider keys на основе env, путь к live provider config QA и
CODEX_HOME, когда он присутствует. Держите --output-dir внутри корня репозитория, чтобы guest
мог записывать обратно через смонтированное рабочее пространство.
Справочник QA для Telegram, Discord, Slack и WhatsApp
У Matrix есть отдельная страница из-за количества сценариев и подготовки homeserver на базе Docker. Telegram, Discord, Slack и WhatsApp запускаются на уже существующих реальных транспортах, поэтому их справочник находится здесь.Общие флаги CLI
Эти lanes регистрируются черезextensions/qa-lab/src/live-transports/shared/live-transport-cli.ts и принимают одинаковые флаги:
Каждый lane завершается с ненулевым кодом при любом неуспешном сценарии.
--allow-failures записывает артефакты, не выставляя код выхода с ошибкой.
QA Telegram
@BotFather.
Обязательные env при --credential-source env:
OPENCLAW_QA_TELEGRAM_GROUP_ID- числовой id чата (строка).OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKENOPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN
extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts):
telegram-canarytelegram-mention-gatingtelegram-mentioned-message-replytelegram-help-commandtelegram-commands-commandtelegram-tools-compact-commandtelegram-whoami-commandtelegram-status-commandtelegram-repeated-command-authorizationtelegram-other-bot-command-gatingtelegram-context-commandtelegram-current-session-status-tooltelegram-reply-chain-exact-markertelegram-stream-final-single-messagetelegram-long-final-reuses-previewtelegram-long-final-three-chunks
mock-openai также включают детерминированные проверки цепочки ответов и streaming финального сообщения. telegram-current-session-status-tool остается opt-in, потому что он стабилен только при непосредственном запуске после canary, а не после произвольных ответов нативных команд. Используйте pnpm openclaw qa telegram --list-scenarios --provider-mode mock-openai, чтобы вывести текущий разрез default/optional с regression refs.
Выходные артефакты:
telegram-qa-report.mdqa-evidence.json- записи evidence для проверок live-транспорта, включая поля profile, coverage, provider, channel, artifacts, result и RTT.
qa-evidence.json в result.timing для выбранной проверки RTT.
OPENCLAW_QA_CREDENTIAL_SOURCE=convex, пакетная live-обертка
арендует учетные данные kind: "telegram", экспортирует env арендованной группы/driver/SUT-бота
в запуск установленного пакета, отправляет Heartbeat аренды и освобождает ее при
завершении. Пакетная обертка по умолчанию выполняет 20 проверок RTT для
telegram-mentioned-message-reply, использует таймаут RTT 30 с и роль Convex
maintainer вне CI, когда выбран Convex. Переопределите
OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES, OPENCLAW_NPM_TELEGRAM_RTT_TIMEOUT_MS
или OPENCLAW_NPM_TELEGRAM_RTT_MAX_FAILURES, чтобы настроить измерение RTT без
создания отдельной команды RTT или формата сводки, специфичного для Telegram.
QA Discord
/help в Discord, а также opt-in Mantis evidence-сценарии.
Обязательные env при --credential-source env:
OPENCLAW_QA_DISCORD_GUILD_IDOPENCLAW_QA_DISCORD_CHANNEL_IDOPENCLAW_QA_DISCORD_DRIVER_BOT_TOKENOPENCLAW_QA_DISCORD_SUT_BOT_TOKENOPENCLAW_QA_DISCORD_SUT_APPLICATION_ID- должен совпадать с id пользователя SUT-бота, возвращенным Discord (иначе lane быстро завершится ошибкой).
OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1сохраняет тела сообщений в артефактах observed-message.OPENCLAW_QA_DISCORD_VOICE_CHANNEL_IDвыбирает голосовой/stage-канал дляdiscord-voice-autojoin; без него сценарий выбирает первый видимый для SUT-бота голосовой/stage-канал.
extensions/qa-lab/src/live-transports/discord/discord-live.runtime.ts:36):
discord-canarydiscord-mention-gatingdiscord-native-help-command-registrationdiscord-voice-autojoin- opt-in голосовой сценарий. Запускается отдельно, включаетchannels.discord.voice.autoJoinи проверяет, что текущее голосовое состояние SUT-бота в Discord соответствует целевому голосовому/stage-каналу. Учетные данные Convex Discord могут включать необязательныйvoiceChannelId; иначе runner обнаруживает первый видимый голосовой/stage-канал в guild.discord-status-reactions-tool-only- opt-in Mantis-сценарий. Запускается отдельно, потому что переводит SUT в always-on режим ответов guild только через tools сmessages.statusReactions.enabled=true, затем захватывает REST timeline реакций и визуальные артефакты HTML/PNG. Отчеты Mantis before/after также сохраняют предоставленные сценарием MP4-артефакты какbaseline.mp4иcandidate.mp4.
discord-qa-report.mdqa-evidence.json- записи evidence для проверок live-транспорта.discord-qa-observed-messages.json- тела редактируются, если не заданOPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1.discord-qa-reaction-timelines.jsonиdiscord-status-reactions-tool-only-timeline.png, когда запускается сценарий status-reaction.
QA Slack
--credential-source env:
OPENCLAW_QA_SLACK_CHANNEL_IDOPENCLAW_QA_SLACK_DRIVER_BOT_TOKENOPENCLAW_QA_SLACK_SUT_BOT_TOKENOPENCLAW_QA_SLACK_SUT_APP_TOKEN
OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1сохраняет тела сообщений в артефактах observed-message.OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIRвключает визуальные approval checkpoints для Mantis. Runner записывает<scenario>.pending.jsonи<scenario>.resolved.json, затем ждет соответствующие файлы.ack.json.OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_TIMEOUT_MSпереопределяет таймаут подтверждения checkpoint. Значение по умолчанию:120000.
extensions/qa-lab/src/live-transports/slack/slack-live.runtime.ts):
slack-canaryslack-mention-gatingslack-allowlist-blockslack-top-level-reply-shapeslack-restart-resumeslack-thread-follow-upslack-thread-isolationslack-approval-exec-native- opt-in сценарий нативного Slack approval для exec. Запрашивает exec approval через Gateway, проверяет, что сообщение Slack содержит нативные кнопки approval, разрешает его и проверяет обновление Slack после разрешения.slack-approval-plugin-native- opt-in сценарий нативного Slack Plugin approval. Включает пересылку exec и Plugin approval вместе, чтобы Plugin events не подавлялись маршрутизацией exec approval, затем проверяет тот же pending/resolved путь нативного Slack UI.
slack-qa-report.mdqa-evidence.json- записи evidence для проверок live-транспорта.slack-qa-observed-messages.json- тела редактируются, если не заданOPENCLAW_QA_SLACK_CAPTURE_CONTENT=1.approval-checkpoints/- только когда Mantis задаетOPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIR; содержит checkpoint JSON, acknowledgement JSON и screenshots pending/resolved.
Настройка рабочего пространства Slack
Для lane нужны два разных приложения Slack в одном рабочем пространстве, а также канал, участниками которого являются оба бота:channelId- idCxxxxxxxxxxканала, куда приглашены оба бота. Используйте выделенный канал; lane публикует сообщения при каждом запуске.driverBotToken- токен бота (xoxb-...) приложения Driver.sutBotToken- токен бота (xoxb-...) приложения SUT, которое должно быть отдельным приложением Slack, отличным от driver, чтобы id его bot user был уникальным.sutAppToken- app-level token (xapp-...) приложения SUT сconnections:write, используемый Socket Mode, чтобы приложение SUT могло получать события.
extensions/slack/src/setup-shared.ts:10) до разрешений и событий, покрываемых live Slack QA suite. Для настройки production-канала так, как ее видят пользователи, см. быструю настройку канала Slack; пара QA Driver/SUT намеренно отделена, потому что lane нужны два разных bot user id в одном рабочем пространстве.
1. Создайте приложение Driver
Перейдите на api.slack.com/apps → Создать новое приложение → Из манифеста → выберите рабочее пространство QA, вставьте следующий манифест, затем Установить в рабочее пространство:
xoxb-...) - он станет driverBotToken. Драйверу нужно только отправлять сообщения и идентифицировать себя; события и Socket Mode не нужны.
2. Создайте приложение SUT
Повторите Создать новое приложение → Из манифеста в том же рабочем пространстве. Это QA-приложение намеренно использует более узкую версию production-манифеста встроенного Slack plugin (extensions/slack/src/setup-shared.ts:10): scopes и события реакций опущены, потому что live-набор QA для Slack пока не покрывает обработку реакций.
- Установить в рабочее пространство → скопируйте Bot User OAuth Token → он станет
sutBotToken. - Основная информация → Токены уровня приложения → Сгенерировать токен и scopes → добавьте scope
connections:write→ сохраните → скопируйте значениеxapp-...→ оно станетsutAppToken.
auth.test для каждого токена. Runtime различает драйвер и SUT по идентификатору пользователя; повторное использование одного приложения для обоих сразу сломает фильтрацию упоминаний.
3. Создайте канал
В рабочем пространстве QA создайте канал (например, #openclaw-qa) и пригласите обоих ботов изнутри канала:
Cxxxxxxxxxx из информация о канале → О канале → ID канала - он станет channelId. Подойдет публичный канал; если вы используете приватный канал, у обоих приложений уже есть groups:history, поэтому чтение истории тестовой обвязкой все равно будет успешным.
4. Зарегистрируйте учетные данные
Есть два варианта. Используйте переменные окружения для отладки на одной машине (задайте четыре переменные OPENCLAW_QA_SLACK_* и передайте --credential-source env) или заполните общий пул Convex, чтобы CI и другие maintainers могли арендовать их.
Для пула Convex запишите четыре поля в JSON-файл:
OPENCLAW_QA_CONVEX_SITE_URL и OPENCLAW_QA_CONVEX_SECRET_MAINTAINER в вашей оболочке, зарегистрируйте и проверьте:
count: 1, status: "active", без поля lease.
5. Проверьте end-to-end
Запустите линию локально, чтобы подтвердить, что оба бота могут общаться друг с другом через брокер:
slack-qa-report.md показывает статусы pass для slack-canary и slack-mention-gating. Если линия зависает примерно на 90 секунд и завершается с Convex credential pool exhausted for kind "slack", значит пул пуст или все строки арендованы - qa credentials list --kind slack --status all --json покажет, что именно.
WhatsApp QA
--credential-source env:
OPENCLAW_QA_WHATSAPP_DRIVER_PHONE_E164OPENCLAW_QA_WHATSAPP_SUT_PHONE_E164OPENCLAW_QA_WHATSAPP_DRIVER_AUTH_ARCHIVE_BASE64OPENCLAW_QA_WHATSAPP_SUT_AUTH_ARCHIVE_BASE64
OPENCLAW_QA_WHATSAPP_GROUP_JIDвключает групповые сценарии, такие какwhatsapp-mention-gating,whatsapp-group-pending-history-context,whatsapp-broadcast-group-fanout,whatsapp-group-activation-always,whatsapp-group-reply-to-bot-triggers, сценарии групповых действий, медиа и опросов, а такжеwhatsapp-group-allowlist-block.OPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1сохраняет тела сообщений в артефактах observed-message.
extensions/qa-lab/src/live-transports/whatsapp/whatsapp-live.runtime.ts):
- Базовая проверка и фильтрация групп:
whatsapp-canary,whatsapp-pairing-block,whatsapp-mention-gating,whatsapp-group-pending-history-context,whatsapp-group-activation-always,whatsapp-group-reply-to-bot-triggers,whatsapp-top-level-reply-shape,whatsapp-restart-resume,whatsapp-group-allowlist-block. - Нативные команды:
whatsapp-help-command,whatsapp-status-command,whatsapp-commands-command,whatsapp-tools-compact-command,whatsapp-whoami-command,whatsapp-context-command,whatsapp-native-new-command. - Поведение ответов и финального вывода:
whatsapp-tool-only-usage-footer,whatsapp-reply-to-message,whatsapp-group-reply-to-message,whatsapp-reply-to-mode-batched,whatsapp-reply-context-isolation,whatsapp-reply-delivery-shape,whatsapp-stream-final-message-accounting. - Действия с сообщениями на пользовательском пути:
whatsapp-agent-message-action-reactначинается с реального DM от драйвера, позволяет модели вызвать инструментmessageи наблюдает нативную реакцию WhatsApp.whatsapp-agent-message-action-upload-fileиспользует тот же подход дляmessage(action=upload-file)и наблюдает нативные медиа WhatsApp.whatsapp-group-agent-message-action-reactиwhatsapp-group-agent-message-action-upload-fileдоказывают те же видимые пользователю действия в реальной группе WhatsApp. - Групповая рассылка:
whatsapp-broadcast-group-fanoutначинается с одного сообщения WhatsApp в группе с упоминанием и проверяет разные видимые ответы отmainиqa-second. - Активация в группе:
whatsapp-group-activation-alwaysменяет реальную групповую сессию на/activation always, доказывает, что групповое сообщение без упоминания будит агента, затем восстанавливает/activation mention.whatsapp-group-reply-to-bot-triggersсоздает ответ бота, отправляет на него нативный цитированный ответ без явного упоминания и проверяет, что агент просыпается из этого контекста ответа. - Входящие медиа и структурированные сообщения:
whatsapp-inbound-image-caption,whatsapp-audio-preflight,whatsapp-inbound-structured-messages,whatsapp-group-audio-gating,whatsapp-inbound-reaction-no-trigger. Они отправляют через драйвер реальные события WhatsApp для изображений, аудио, документов, геолокаций, контактов, стикеров и реакций. - Прямые проверки контракта Gateway:
whatsapp-outbound-media-matrix,whatsapp-outbound-document-preserves-filename,whatsapp-outbound-poll,whatsapp-group-outbound-media,whatsapp-group-outbound-poll,whatsapp-message-actions,whatsapp-reply-context-isolation,whatsapp-reply-delivery-shape. Они намеренно обходят prompting модели и доказывают детерминированные контракты Gateway/каналаsend,pollиmessage.action. - Покрытие контроля доступа:
whatsapp-access-control-dm-open,whatsapp-access-control-dm-disabled,whatsapp-access-control-group-open,whatsapp-access-control-group-disabled,whatsapp-group-allowlist-block. - Нативные подтверждения:
whatsapp-approval-exec-deny-native,whatsapp-approval-exec-native,whatsapp-approval-exec-reaction-native,whatsapp-approval-exec-group-reaction-native,whatsapp-approval-plugin-native. - Реакции статуса:
whatsapp-status-reactions,whatsapp-status-reaction-lifecycle.
live-frontier
оставлена небольшой: 10 сценариев для быстрого smoke-покрытия. Стандартная линия mock-openai
запускает 44 детерминированных сценария через настоящий транспорт WhatsApp, при этом мокается только вывод модели. Сценарии подтверждений и несколько более тяжелых или блокирующих проверок остаются явными по идентификатору сценария.
Драйвер WhatsApp QA наблюдает структурированные live-события (text, media,
location, reaction и poll) и может активно отправлять медиа, опросы, контакты, геолокации и стикеры. QA Lab импортирует этот драйвер через пакетную поверхность
@openclaw/whatsapp/api.js, а не обращается к приватным runtime-файлам WhatsApp. Для групповых наблюдений fromJid — это JID группы, а
participantJid и fromPhoneE164 идентифицируют участника-отправителя. Содержимое сообщений по умолчанию редактируется. Прямые проверки Gateway для
опросов, upload-file, медиа, групповых опросов, групповых медиа и формы ответа являются проверками контракта транспорта/API; они не считаются доказательством того, что пользовательский prompt заставил агента выбрать то же действие. Доказательство действия на пользовательском пути берется из сценариев вроде
whatsapp-agent-message-action-react и
whatsapp-group-agent-message-action-react, где драйвер отправляет обычное сообщение WhatsApp, а QA Lab наблюдает получившийся нативный артефакт WhatsApp.
Отчеты WhatsApp включают posture каждого сценария (user-path, direct-gateway
или native-approval), чтобы доказательство нельзя было принять за более сильный контракт, чем оно действительно подтверждает.
Выходные артефакты:
whatsapp-qa-report.mdqa-evidence.json- записи доказательств для live-проверок транспорта.whatsapp-qa-observed-messages.json- тела редактируются, если не заданоOPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1.
Пул учетных данных Convex
Линии Telegram, Discord, Slack и WhatsApp могут арендовать учетные данные из общего пула Convex вместо чтения указанных выше переменных окружения. Передайте--credential-source convex (или задайте OPENCLAW_QA_CREDENTIAL_SOURCE=convex); QA Lab получает эксклюзивную аренду, отправляет для нее Heartbeat на протяжении запуска и освобождает ее при завершении. Типы пула: "telegram", "discord", "slack" и "whatsapp".
Форматы payload, которые брокер проверяет на admin/add:
- Telegram (
kind: "telegram"):{ groupId: string, driverToken: string, sutToken: string }-groupIdдолжен быть числовой строкой chat-id. - Реальный пользователь Telegram (
kind: "telegram-user"):{ groupId: string, sutToken: string, testerUserId: string, testerUsername: string, telegramApiId: string, telegramApiHash: string, tdlibDatabaseEncryptionKey: string, tdlibArchiveBase64: string, tdlibArchiveSha256: string, desktopTdataArchiveBase64: string, desktopTdataArchiveSha256: string }- только подтверждение Mantis Telegram Desktop. Общие контуры QA Lab не должны получать этот тип. - Discord (
kind: "discord"):{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }. - WhatsApp (
kind: "whatsapp"):{ driverPhoneE164: string, sutPhoneE164: string, driverAuthArchiveBase64: string, sutAuthArchiveBase64: string, groupJid?: string }- номера телефонов должны быть разными строками E.164.
telegram-user одновременно для драйвера TDLib CLI и свидетеля Telegram Desktop,
а затем освобождает ее после публикации подтверждения.
Когда PR требует детерминированного визуального различия, Mantis может использовать один и тот же ответ mock-модели
на main и на голове PR, пока меняется форматтер Telegram или слой доставки.
Параметры захвата по умолчанию настроены для комментариев PR: стандартный класс Crabbox,
запись рабочего стола 24 кадра/с, GIF движения 24 кадра/с и ширина превью 1920px.
Комментарии «до/после» должны публиковать чистый пакет, содержащий только
предусмотренные GIF.
Контуры Slack также могут использовать пул. Проверки формы полезной нагрузки Slack сейчас находятся в раннере Slack QA, а не в брокере; используйте { channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string } с идентификатором канала Slack вроде Cxxxxxxxxxx. См. Настройка рабочей области Slack для подготовки приложения и областей доступа.
Операционные переменные окружения и контракт конечной точки брокера Convex описаны в Тестирование → Общие учетные данные Telegram через Convex (название раздела появилось до многоканального пула; семантика аренды общая для всех типов).
Сиды на основе репозитория
Ресурсы сидов находятся вqa/:
qa/scenarios/index.yamlqa/scenarios/<theme>/*.yaml
qa-lab должен оставаться универсальным раннером YAML-сценариев. Каждый YAML-файл сценария
является источником истины для одного тестового запуска и должен определять:
- верхнеуровневый
title - метаданные
scenario - необязательные метаданные категории, возможности, контура и риска в
scenario - ссылки на документацию и код в
scenario - необязательные требования к plugin в
scenario - необязательный патч конфигурации Gateway в
scenario - исполняемый верхнеуровневый
flowдля flow-сценариев илиscenario.execution.kind/scenario.execution.pathдля сценариев Vitest и Playwright
flow, может оставаться универсальной
и сквозной. Например, YAML-сценарии могут сочетать помощники на стороне транспорта
с помощниками на стороне браузера, которые управляют встроенным Control UI через
шов Gateway browser.request без добавления специального раннера.
Файлы сценариев следует группировать по продуктовой возможности, а не по папке
исходного дерева. Сохраняйте стабильность идентификаторов сценариев при перемещении файлов; используйте docsRefs и codeRefs
для трассируемости реализации.
Базовый список должен оставаться достаточно широким, чтобы покрывать:
- личные сообщения и чат канала
- поведение тредов
- жизненный цикл действий с сообщениями
- обратные вызовы cron
- воспоминание памяти
- переключение моделей
- передачу подагенту
- чтение репозитория и чтение документации
- одну небольшую задачу сборки, например Lobster Invaders
Контуры mock-поставщиков
Уqa suite есть два локальных контура mock-поставщиков:
mock-openai— сценарно-осведомленный mock OpenClaw. Он остается контуром детерминированного mock по умолчанию для QA на основе репозитория и проверок паритета.aimockзапускает сервер поставщика на базе AIMock для экспериментального протокола, фикстур, записи/воспроизведения и покрытия хаоса. Он является добавочным и не заменяет сценарный диспетчерmock-openai.
extensions/qa-lab/src/providers/.
Каждый поставщик владеет своими значениями по умолчанию, запуском локального сервера, конфигурацией модели Gateway,
потребностями подготовки auth-профиля и флагами возможностей live/mock. Общий код suite и
Gateway должен маршрутизироваться через реестр поставщиков, а не ветвиться по
именам поставщиков.
Транспортные адаптеры
qa-lab владеет универсальным транспортным швом для YAML-сценариев QA. qa-channel —
синтетический вариант по умолчанию. crabline запускает локальные серверы в форме поставщиков и выполняет
обычные channel plugins OpenClaw против них. live зарезервирован для реальных
учетных данных поставщиков и внешних каналов.
На уровне архитектуры разделение такое:
qa-labвладеет универсальным выполнением сценариев, параллелизмом воркеров, записью артефактов и отчетностью.- Транспортный адаптер владеет конфигурацией Gateway, готовностью, входящим и исходящим наблюдением, транспортными действиями и нормализованным состоянием транспорта.
- YAML-файлы сценариев в
qa/scenarios/определяют тестовый запуск;qa-labпредоставляет повторно используемую runtime-поверхность, которая их выполняет.
Добавление канала
Добавление канала в YAML-систему QA требует реализации канала плюс пакет сценариев, проверяющий контракт канала. Для smoke-покрытия в CI добавьте соответствующий локальный сервер поставщика Crabline и откройте его через драйверcrabline.
Не добавляйте новый верхнеуровневый корень команды QA, когда общий хост qa-lab может владеть потоком.
qa-lab владеет общей механикой хоста:
- корнем команды
openclaw qa - запуском и завершением suite
- параллелизмом воркеров
- записью артефактов
- генерацией отчетов
- выполнением сценариев
- алиасами совместимости для старых сценариев
qa-channel
- как
openclaw qa <runner>монтируется под общим корнемqa - как Gateway настраивается для этого транспорта
- как проверяется готовность
- как внедряются входящие события
- как наблюдаются исходящие сообщения
- как открываются транскрипты и нормализованное состояние транспорта
- как выполняются действия на базе транспорта
- как обрабатывается специфичный для транспорта сброс или очистка
- Оставьте
qa-labвладельцем общего корняqa. - Реализуйте транспортный раннер на общем шве хоста
qa-lab. - Держите специфичную для транспорта механику внутри runner plugin или harness канала.
- Монтируйте раннер как
openclaw qa <runner>вместо регистрации конкурирующей корневой команды. Plugins раннеров должны объявлятьqaRunnersвopenclaw.plugin.jsonи экспортировать соответствующий массивqaRunnerCliRegistrationsизruntime-api.ts. Держитеruntime-api.tsлегким; ленивые CLI и выполнение раннера должны оставаться за отдельными точками входа. - Создайте или адаптируйте YAML-сценарии в тематических директориях
qa/scenarios/. - Используйте универсальные помощники сценариев для новых сценариев.
- Сохраняйте работу существующих алиасов совместимости, если репозиторий не выполняет намеренную миграцию.
- Если поведение можно выразить один раз в
qa-lab, поместите его вqa-lab. - Если поведение зависит от одного транспорта канала, держите его в этом runner plugin или plugin harness.
- Если сценарию нужна новая возможность, которую может использовать более одного канала, добавьте универсальный помощник вместо ветки, специфичной для канала, в
suite.ts. - Если поведение имеет смысл только для одного транспорта, оставьте сценарий специфичным для транспорта и явно укажите это в контракте сценария.
Имена помощников сценариев
Предпочтительные универсальные помощники для новых сценариев:waitForTransportReadywaitForChannelReadyinjectInboundMessageinjectOutboundMessagewaitForTransportOutboundMessagewaitForChannelOutboundMessagewaitForNoTransportOutboundgetTransportSnapshotreadTransportMessagereadTransportTranscriptformatTransportTranscriptresetTransport
waitForQaChannelReady, waitForOutboundMessage, waitForNoOutbound, formatConversationTranscript, resetBus - но при создании новых сценариев следует использовать универсальные имена. Алиасы существуют, чтобы избежать одномоментной миграции, а не как модель на будущее.
Отчетность
qa-lab экспортирует Markdown-отчет протокола из наблюдаемой временной шкалы шины.
Отчет должен отвечать на вопросы:
- Что сработало
- Что не сработало
- Что осталось заблокированным
- Какие последующие сценарии стоит добавить
pnpm openclaw qa coverage (добавьте --json для машиночитаемого вывода).
При выборе сфокусированного подтверждения для затронутого поведения или пути файла выполните pnpm openclaw qa coverage --match <query>.
Отчет сопоставления ищет в метаданных сценариев, ссылках на документацию, ссылках на код, идентификаторах покрытия, plugins и требованиях поставщиков, а затем печатает подходящие цели qa suite --scenario ....
Каждый запуск qa suite записывает верхнеуровневые артефакты qa-evidence.json,
qa-suite-summary.json и qa-suite-report.md для выбранного
набора сценариев. Сценарии, объявляющие execution.kind: vitest или
execution.kind: playwright, запускают соответствующий путь теста и также записывают
логи по сценариям. Сценарии, объявляющие execution.kind: script, запускают
производитель подтверждений по execution.path через node --import tsx (с
развернутыми ${outputDir} и ${scenarioId} в execution.args); производитель
записывает собственный qa-evidence.json, записи которого импортируются в вывод
suite, а пути его артефактов разрешаются относительно этого
qa-evidence.json производителя. Когда qa suite достигается через
qa run --qa-profile, тот же qa-evidence.json также включает сводку scorecard профиля
для выбранных категорий таксономии.
Рассматривайте это как средство обнаружения, а не замену gate; выбранному сценарию все равно нужен правильный режим поставщика, live-транспорт, Multipass, Testbox или release-контур для проверяемого поведения.
Контекст scorecard см. в Scorecard зрелости.
Для проверок характера и стиля запустите один и тот же сценарий по нескольким live-ссылкам моделей
и запишите оцененный Markdown-отчет:
SOUL.md, затем выполнять обычные
пользовательские ходы, такие как чат, помощь с рабочей областью и небольшие
задачи с файлами. Модели-кандидату не следует сообщать, что ее оценивают.
Команда сохраняет каждый полный транскрипт, записывает базовую статистику
запуска, а затем просит модели-судьи в быстром режиме с рассуждением xhigh,
где оно поддерживается, ранжировать запуски по естественности, атмосфере и юмору.
Используйте --blind-judge-models при сравнении провайдеров: подсказка судьи
по-прежнему получает каждый транскрипт и статус запуска, но ссылки на кандидатов
заменяются нейтральными метками, такими как candidate-01; после разбора отчет
сопоставляет ранжирование с реальными ссылками.
Запуски кандидатов по умолчанию используют мышление high, с medium для GPT-5.5
и xhigh для более старых оценочных ссылок OpenAI, которые его поддерживают.
Переопределите конкретного кандидата прямо в строке с помощью
--model provider/model,thinking=<level>. --thinking <level> по-прежнему задает
глобальный запасной вариант, а более старая форма
--model-thinking <provider/model=level> сохранена для совместимости.
Ссылки на кандидатов OpenAI по умолчанию используют быстрый режим, чтобы
приоритетная обработка применялась там, где провайдер ее поддерживает. Добавьте
,fast, ,no-fast или ,fast=false прямо в строке, когда отдельному кандидату
или судье нужно переопределение. Передавайте --fast только тогда, когда хотите
принудительно включить быстрый режим для каждой модели-кандидата. Длительности
запусков кандидатов и судей записываются в отчет для анализа бенчмарков, но
подсказки судей явно указывают не ранжировать по скорости.
Запуски моделей-кандидатов и моделей-судей по умолчанию используют concurrency
16. Уменьшайте --concurrency или --judge-concurrency, когда ограничения
провайдера или нагрузка на локальный Gateway делают запуск слишком шумным.
Если кандидат --model не передан, оценка персонажа по умолчанию использует
openai/gpt-5.5, openai/gpt-5.2, openai/gpt-5, anthropic/claude-opus-4-8,
anthropic/claude-sonnet-4-6, zai/glm-5.1,
moonshot/kimi-k2.5 и
google/gemini-3.1-pro-preview, когда --model не передан.
Если --judge-model не передан, судьи по умолчанию используют
openai/gpt-5.5,thinking=xhigh,fast и
anthropic/claude-opus-4-8,thinking=high.