所有範囲
- OpenClaw(
extensions/qa-lab/src/mantis/*):シナリオランタイム、pnpm openclaw qa mantis <command>CLI、エビデンススキーマ。 - QA Lab(
extensions/qa-lab/src/live-transports/*):ライブトランスポートハーネス、ドライバー/SUT bot、レポート/エビデンスライター。 - 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 も受け付けます。特記がない限り、provider/class のローカル CLI デフォルトは
hetzner/beast です。CI ワークフローでは通常、両方を上書きします。
discord-smoke
https://discord.com/api/v10)を呼び出して bot
ユーザー、guild、guild のチャンネル、および対象チャンネルを取得し、そのチャンネルが
guild に属することをアサートします。その後、--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 で上書き)です。guild/チャンネル ID は
OPENCLAW_QA_DISCORD_GUILD_ID / OPENCLAW_QA_DISCORD_CHANNEL_ID(
--guild-id / --channel-id で上書き)から取得し、17~20 桁の Discord snowflake でなければなりません。
公開される概要とレポート内で bot/guild/チャンネル/メッセージの ID
および名前を <redacted> に置き換えるには、OPENCLAW_QA_REDACT_PUBLIC_METADATA=1 を設定します。
run
--transport は現在、discord のみを受け付けます。--scenario は 2 つある
組み込み ID のいずれかで、それぞれ独自のデフォルトベースライン ref と、想定される前後の
ラベル(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 を
実行し(スキップされない場合)、その後、各 worktree に対して
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)は非ゼロで終了します。
2 番目の Discord シナリオ(discord-thread-reply-filepath-attachment)は、
ドライバー bot で親メッセージを投稿し、実際のスレッドを作成して、リポジトリローカルの filePath を使用して SUT の
message.thread-reply アクションを呼び出し、その後、返信と添付ファイル名を確認するために
スレッドをポーリングします。mantis-thread-report.md という名前の添付ファイルを想定します。
desktop-browser-smoke
--browser-url(デフォルト https://openclaw.ai)またはレンダリングされた
--html-file を表示し、待機して、scrot でスクリーンショットを取得します。必要に応じて
ffmpeg で MP4 を録画し、desktop-browser-smoke.png / .mp4 / remote-metadata.json
を --output-dir へ rsync で戻します。
フラグ:
--lease-id <cbx_...>は、新規作成せずにウォームアップ済みのデスクトップを再利用します。--browser-profile-dir <remote-path>は、リモートの Chrome user-data-dir を再利用し、永続デスクトップが実行間でログイン状態を維持できるようにします(長期間使用する Discord Web ビューアープロファイルに使用)。--browser-profile-archive-env <name>は、起動前にその環境変数から base64 の.tgzChrome プロファイルアーカイブを復元します(デフォルトOPENCLAW_MANTIS_BROWSER_PROFILE_TGZ_B64)。Discord Web のようなログイン済み確認環境に使用します。--video-duration <seconds>は MP4 のキャプチャ時間を制御します(デフォルト 10 秒)。--keep-lease(またはOPENCLAW_MANTIS_KEEP_VM=1)は、この実行で作成したリースを VNC 検査用に開いたままにします。リースを作成した実行が失敗した場合も、デフォルトでリースを保持します。
qa discord 経由)は引き続き信頼できる基準です。OPENCLAW_QA_DISCORD_CAPTURE_UI_METADATA=1 が設定されている場合、シナリオは
Discord Web URL アーティファクトも書き込み、OPENCLAW_QA_DISCORD_KEEP_THREADS=1 は
ブラウザがスレッドを開けるだけの時間、スレッドを開いたままにします。
GitHub ワークフローでは、
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR による永続ビューアープロファイルを優先します(完全なプロファイルアーカイブは
GitHub のシークレットサイズ上限を超える可能性があります)。小規模なプロファイルやブートストラップ用プロファイルの場合は、代わりに
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64 から base64 の .tgz を復元できます。どちらのソースも
設定されていない場合でも、ワークフローは決定論的な
ベースライン/候補のスクリーンショットを公開し、ログイン済みの確認が
スキップされたことをログに記録します。
slack-desktop-smoke
pnpm openclaw qa slack を実行し、VNC ブラウザで Slack Web を開き、
デスクトップをキャプチャして、Slack QA アーティファクト(slack-qa/)と
VNC のスクリーンショット/動画の両方をローカルへコピーします。これは、
SUT Gateway とブラウザの両方が同じ VM 内で実行される唯一の Mantis 形式です。
--gateway-setup を指定すると、コマンドは VM 内の
$HOME/.openclaw-mantis/slack-openclaw に永続的で破棄可能な OpenClaw
ホームを作成し、対象チャンネル向けの Slack
Socket Mode 設定をパッチして、
openclaw gateway run --dev --allow-unconfigured --port 38973 を起動し、
Chrome を VNC セッション内で実行したままにします。--gateway-setup を省略すると、代わりに通常の
bot 間 Slack QA レーンを実行します。
--credential-source env に必要な環境変数(ローカルのデフォルトは env、role
のデフォルトは 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 は Crabbox を 呼び出す前にそれをOPENCLAW_LIVE_OPENAI_KEYへコピーします)
--credential-source convex を指定すると、Mantis は VM を作成する前に
共有プールから Slack SUT 認証情報をリースし、チャンネル ID、app token、bot token を
OPENCLAW_MANTIS_SLACK_* 環境変数として VM に転送します。そのため、GitHub
ワークフローに必要なのは Convex broker secret のみで、生の Slack token は不要です。
その他のフラグ:--slack-url <url> は特定の URL を開きます(指定しない場合、Mantis は
auth.test から https://app.slack.com/client/<team>/<channel> を導出します)。
--slack-channel-id <id> は Gateway の許可リストチャンネルを設定します。
OPENCLAW_MANTIS_SLACK_BROWSER_PROFILE_DIR は VM 内の永続 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 UI ではなく、
シナリオが観測した Slack API メッセージからレンダリングされます。slack-desktop-smoke.png が
Slack Web 自体の証拠となるのは、リースのブラウザプロファイルがすでにログイン済みだった場合のみです。
telegram-desktop-builder
openclaw gateway run --dev --allow-unconfigured --port 38974 を起動し、
ドライバー bot の準備完了メッセージをリースしたプライベートグループに投稿してから、
スクリーンショットと MP4 をキャプチャします。bot token は OpenClaw の設定にのみ使用され、
Telegram Desktop へのログインには決して使用されません。デスクトップビューアーは別の Telegram ユーザーセッションであり、
--telegram-profile-archive-env <name> から復元するか、
VNC 経由で手動ログインし、--keep-lease によって稼働状態を維持します。
フラグ:--lease-id <cbx_...> は、Telegram Desktop にすでにログイン済みの VM に対して再実行します。
--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 を設定してください。Discord/Slack/Telegram の GitHub ワークフローではデフォルトで有効です。
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を設定)
github-actions[bot] ではなく、Mantis GitHub App(MANTIS_GITHUB_APP_ID/MANTIS_GITHUB_APP_PRIVATE_KEY)を通じて投稿され、非表示のマーカーコメントを upsert キーとして使用します。
Mantis Discord Status Reactions と Mantis Telegram Live はどちらも baseline_ref/candidate_ref(または PR コメント内の baseline=/candidate=)を受け取り、シークレットを含む認証情報を使用して実行する前に、解決された SHA が origin/main の祖先、リリースタグ(v*)、またはオープンな PR の head のいずれかであることを検証します。
write/maintain/admin アクセスを持つユーザーが PR から使用できるコメントトリガー:
telegram-status-command をシナリオとして使用します。特定の Crabbox プロバイダーまたは事前にウォームアップされたデスクトップを対象にするため、provider=aws|hetzner と lease=<cbx_...> を指定できます。Mantis Telegram Desktop Proof は、PR に mantis: telegram-visible-proof ラベルがすでに付いている場合にのみ PR コメントへ応答します。
Web UI チャットのコメントトリガーでは、デフォルトで PR の head SHA を候補として使用します。Control UI のモック Gateway チャット証明を実行し、ブラウザーアーティファクトを公開します。ほかの Web ページやネイティブアプリのサーフェスでは、通常の Playwright/ブラウザー証明、メンテナーのスクリーンショット、Crabbox、またはローカルアーティファクトを使用してください。
ClawSweeper からシナリオを直接ディスパッチすることもできます。
マシンとシークレット
ローカル CLI の Crabbox のデフォルトは--provider hetzner --class beast です。--provider、--class/--machine-class、または OPENCLAW_MANTIS_CRABBOX_PROVIDER/OPENCLAW_MANTIS_CRABBOX_CLASS で上書きできます。GitHub ワークフローでは通常、両方を上書きします(例:--class standard、および Slack ワークフローの aws/hetzner プロバイダー選択入力)。プロバイダーが遅すぎるか利用できない場合は、フォールバックをハードコードするのではなく、同じ Crabbox インターフェースの背後に追加してください。
VM のベースライン:デスクトップ対応の Chrome/Chromium、CDP アクセス、VNC/noVNC、Node 22.22.3+、24.15+、または 25.9+ と pnpm、OpenClaw のチェックアウトを備え、対象トランスポート、GitHub、モデルプロバイダー、認証情報ブローカーへのアウトバウンドアクセスが可能な Linux。
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 ワークフローでは通常、生の Discord bot トークンの代わりに--credential-source convexと以下のブローカー認証情報を使用します。 - 公開アーティファクトのアップロード用の
OPENCLAW_QA_REDACT_PUBLIC_METADATA=1 OPENCLAW_QA_CONVEX_SITE_URL、OPENCLAW_QA_CONVEX_SECRET_CIOPENAI_API_KEY(または Telegram Desktop 証明専用のOPENCLAW_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 の変更前/変更後の形式については、extensions/qa-lab/src/mantis/run.runtime.ts の MANTIS_SCENARIO_CONFIGS を参照)。各シナリオには、ID とタイトル、トランスポート、必須の認証情報、ベースラインの ref ポリシー、候補の ref ポリシー、OpenClaw 設定パッチ、セットアップ/刺激ステップ、想定されるベースラインと候補のオラクル、ビジュアル取得対象、タイムアウト枠、クリーンアップ手順が必要です。
対象を絞った候補のみのブラウザー証明では、専用の決定論的 E2E テストとワークフローを使用できます。スコープを明示し、実行前に候補の ref を検証し、シークレットを使用する公開処理を分離して、同じ証拠マニフェスト契約を出力してください。
ビジョンチェックよりも、小さく型付けされたオラクルを優先してください。たとえば、Discord のリアクション状態またはメッセージ参照、Slack スレッドの ts/リアクション API 状態、メールのメッセージ ID とヘッダーです。UI が唯一の信頼できる観測対象である場合はブラウザーのスクリーンショットを使用し、プラットフォーム API のオラクルが存在する場合は、ビジョンチェックをそれに追加する形にしてください。
Discord、Slack、Telegram に続き、同じランナー形式を WhatsApp(QR ログイン、再識別、配信、メディア、リアクション)および Matrix(暗号化ルーム、スレッド/返信関係、再起動後の再開)へ拡張できますが、どちらもまだ実装されていません。
未解決の課題
- 既存の Mantis ボットを再利用する場合、どの Discord ボットをドライバーとし、どのボットを SUT とすべきですか?
- GitHub は PR の Mantis アーティファクトをどのくらいの期間保持すべきですか?
- ClawSweeper は、メンテナーのコマンドを待たずに、どのような場合に Mantis シナリオを自動的に推奨すべきですか?
- 公開 PR にアップロードする前に、スクリーンショットを墨消しまたは切り抜きすべきですか?