Fundamentals
Ikhtisar QA
Stack QA privat dimaksudkan untuk menguji OpenClaw dengan cara yang lebih realistis dan berbentuk kanal daripada yang dapat dilakukan oleh satu pengujian unit.
Bagian saat ini:
extensions/qa-channel: kanal pesan sintetis dengan permukaan DM, kanal, thread, reaksi, edit, dan hapus.extensions/qa-lab: UI debugger dan bus QA untuk mengamati transkrip, menyuntikkan pesan masuk, dan mengekspor laporan Markdown.extensions/qa-matrix, Plugin runner masa depan: adaptor transport langsung yang menjalankan kanal nyata di dalam Gateway QA anak.qa/: aset seed yang didukung repo untuk tugas awal dan skenario QA baseline.- Mantis: verifikasi langsung sebelum dan sesudah untuk bug yang memerlukan transport nyata, tangkapan layar browser, status VM, dan bukti PR.
Permukaan perintah
Setiap alur QA berjalan di bawah pnpm openclaw qa <subcommand>. Banyak yang memiliki alias skrip pnpm qa:*;
kedua bentuk didukung.
| Perintah | Tujuan |
|---|---|
qa run |
Pemeriksaan mandiri QA bawaan; menulis laporan Markdown. |
qa suite |
Jalankan skenario yang didukung repo terhadap jalur Gateway QA. Alias: pnpm openclaw qa suite --runner multipass untuk VM Linux sekali pakai. |
qa coverage |
Cetak inventaris cakupan skenario markdown (--json untuk keluaran mesin). |
qa parity-report |
Bandingkan dua file qa-suite-summary.json dan tulis laporan paritas agentik. |
qa character-eval |
Jalankan skenario QA karakter di beberapa model langsung dengan laporan yang dinilai. Lihat Pelaporan. |
qa manual |
Jalankan prompt sekali pakai terhadap jalur provider/model yang dipilih. |
qa ui |
Mulai UI debugger QA dan bus QA lokal (alias: pnpm qa:lab:ui). |
qa docker-build-image |
Bangun image Docker QA prabangun. |
qa docker-scaffold |
Tulis scaffold docker-compose untuk dasbor QA + jalur Gateway. |
qa up |
Bangun situs QA, mulai stack yang didukung Docker, cetak URL (alias: pnpm qa:lab:up; varian :fast menambahkan --use-prebuilt-image --bind-ui-dist --skip-ui-build). |
qa aimock |
Mulai hanya server provider AIMock. |
qa mock-openai |
Mulai hanya server provider mock-openai yang sadar skenario. |
qa credentials doctor / add / list / remove |
Kelola pool kredensial Convex bersama. |
qa matrix |
Jalur transport langsung terhadap homeserver Tuwunel sekali pakai. Lihat Matrix QA. |
qa telegram |
Jalur transport langsung terhadap grup Telegram privat nyata. |
qa discord |
Jalur transport langsung terhadap kanal guild Discord privat nyata. |
qa slack |
Jalur transport langsung terhadap kanal Slack privat nyata. |
qa mantis |
Runner verifikasi sebelum dan sesudah untuk bug transport langsung, dengan bukti reaksi status Discord, smoke desktop/browser Crabbox, dan smoke Slack-di-VNC. Lihat Mantis dan Runbook Desktop Slack Mantis. |
Alur operator
Alur operator QA saat ini adalah situs QA dua panel:
- Kiri: dasbor Gateway (Control UI) dengan agen.
- Kanan: QA Lab, menampilkan transkrip mirip Slack dan rencana skenario.
Jalankan dengan:
pnpm qa:lab:up
Itu membangun situs QA, memulai jalur Gateway yang didukung Docker, dan mengekspos halaman QA Lab tempat operator atau loop otomatisasi dapat memberi agen sebuah misi QA, mengamati perilaku kanal nyata, dan mencatat apa yang berhasil, gagal, atau tetap terblokir.
Untuk iterasi UI QA Lab lokal yang lebih cepat tanpa membangun ulang image Docker setiap kali, mulai stack dengan bundel QA Lab yang dipasang sebagai bind mount:
pnpm openclaw qa docker-build-image
pnpm qa:lab:build
pnpm qa:lab:up:fast
pnpm qa:lab:watch
qa:lab:up:fast mempertahankan layanan Docker pada image prabangun dan memasang
extensions/qa-lab/web/dist ke dalam kontainer qa-lab sebagai bind mount. qa:lab:watch
membangun ulang bundel itu saat ada perubahan, dan browser memuat ulang otomatis ketika hash aset QA Lab berubah.
Untuk smoke trace OpenTelemetry lokal, jalankan:
pnpm qa:otel:smoke
Skrip itu memulai penerima trace OTLP/HTTP lokal, menjalankan skenario QA
otel-trace-smoke dengan Plugin diagnostics-otel diaktifkan, lalu
mendekode span protobuf yang diekspor dan menegaskan bentuk kritis rilis:
openclaw.run, openclaw.harness.run, openclaw.model.call,
openclaw.context.assembled, dan openclaw.message.delivery harus ada;
panggilan model tidak boleh mengekspor StreamAbandoned pada giliran yang berhasil; ID diagnostik mentah dan
atribut openclaw.content.* harus tetap berada di luar trace. Ini menulis
otel-smoke-summary.json di sebelah artefak suite QA.
QA observabilitas tetap hanya untuk checkout sumber. Tarball npm sengaja menghilangkan
QA Lab, jadi jalur rilis Docker paket tidak menjalankan perintah qa. Gunakan
pnpm qa:otel:smoke dari checkout sumber yang telah dibangun saat mengubah instrumentasi
diagnostik.
Untuk jalur smoke Matrix yang benar-benar memakai transport nyata, jalankan:
pnpm openclaw qa matrix --profile fast --fail-fast
Referensi CLI lengkap, katalog profil/skenario, variabel lingkungan, dan tata letak artefak untuk jalur ini ada di Matrix QA. Sekilas: ini menyediakan homeserver Tuwunel sekali pakai di Docker, mendaftarkan pengguna driver/SUT/observer sementara, menjalankan Plugin Matrix nyata di dalam Gateway QA anak yang dibatasi ke transport itu (tanpa qa-channel), lalu menulis laporan Markdown, ringkasan JSON, artefak peristiwa yang diamati, dan log keluaran gabungan di bawah .artifacts/qa-e2e/matrix-<timestamp>/.
Skenario mencakup perilaku transport yang tidak dapat dibuktikan pengujian unit secara end to end: gating mention, kebijakan allow-bot, allowlist, balasan tingkat atas dan dalam thread, perutean DM, penanganan reaksi, penekanan edit masuk, dedupe replay restart, pemulihan interupsi homeserver, pengiriman metadata persetujuan, penanganan media, dan alur bootstrap/pemulihan/verifikasi Matrix E2EE. Profil CLI E2EE juga menjalankan openclaw matrix encryption setup dan perintah verifikasi melalui homeserver sekali pakai yang sama sebelum memeriksa balasan Gateway.
Discord juga memiliki skenario opt-in khusus Mantis untuk reproduksi bug. Gunakan
--scenario discord-status-reactions-tool-only untuk timeline reaksi status eksplisit,
atau --scenario discord-thread-reply-filepath-attachment untuk membuat thread
Discord nyata dan memverifikasi bahwa message.thread-reply mempertahankan lampiran
filePath. Skenario ini tetap berada di luar jalur Discord langsung default
karena merupakan probe repro sebelum/sesudah, bukan cakupan smoke luas.
Workflow Mantis lampiran thread juga dapat menambahkan video saksi Discord Web
yang sudah login saat MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR atau
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64 dikonfigurasi di lingkungan QA.
Profil penampil itu hanya untuk pengambilan visual; keputusan lulus/gagal
tetap berasal dari oracle REST Discord.
CI menggunakan permukaan perintah yang sama di .github/workflows/qa-live-transports-convex.yml. Run terjadwal dan manual default menjalankan profil Matrix cepat dengan kredensial frontier langsung, --fast, dan OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000. matrix_profile=all manual bercabang ke lima shard profil sehingga katalog menyeluruh dapat berjalan paralel sambil mempertahankan satu direktori artefak per shard.
Untuk jalur smoke Telegram, Discord, dan Slack yang benar-benar memakai transport nyata:
pnpm openclaw qa telegram
pnpm openclaw qa discord
pnpm openclaw qa slack
Jalur-jalur itu menargetkan kanal nyata yang sudah ada dengan dua bot (driver + SUT). Variabel lingkungan yang diperlukan, daftar skenario, artefak keluaran, dan pool kredensial Convex didokumentasikan dalam referensi QA Telegram, Discord, dan Slack di bawah.
Untuk menjalankan VM desktop Slack penuh dengan penyelamatan VNC, jalankan:
pnpm openclaw qa mantis slack-desktop-smoke \
--gateway-setup \
--scenario slack-canary \
--keep-lease
Perintah tersebut menyewa mesin desktop/browser Crabbox, menjalankan lane live Slack
di dalam VM, membuka Slack Web di browser VNC, menangkap desktop, dan
menyalin slack-qa/, slack-desktop-smoke.png, dan slack-desktop-smoke.mp4
saat perekaman video tersedia kembali ke direktori artefak Mantis. Sewa
desktop/browser Crabbox menyediakan alat tangkap dan paket pembantu browser/native-build
sejak awal, sehingga skenario hanya perlu memasang fallback pada sewa yang lebih lama. Mantis
melaporkan waktu total dan per fase di
mantis-slack-desktop-smoke-report.md sehingga run yang lambat menunjukkan apakah waktu digunakan untuk
pemanasan sewa, akuisisi kredensial, penyiapan remote, atau penyalinan artefak. Gunakan kembali
--lease-id <cbx_...> setelah masuk ke Slack Web secara manual melalui VNC;
sewa yang digunakan kembali juga menjaga cache store pnpm Crabbox tetap hangat. Default
--hydrate-mode source memverifikasi dari checkout sumber dan menjalankan install/build
di dalam VM. Gunakan --hydrate-mode prehydrated hanya ketika workspace remote yang digunakan kembali
sudah memiliki node_modules dan dist/ yang sudah dibangun; mode tersebut melewati
langkah install/build yang mahal dan gagal tertutup ketika workspace belum siap.
Dengan --gateway-setup, Mantis membiarkan Gateway OpenClaw Slack persisten
berjalan di dalam VM pada port 38973; tanpa itu, perintah menjalankan
lane QA Slack bot-ke-bot normal dan keluar setelah tangkapan artefak.
Checklist operator, perintah dispatch workflow GitHub, kontrak komentar bukti, tabel keputusan hydrate-mode, interpretasi waktu, dan langkah penanganan kegagalan ada di Runbook Desktop Slack Mantis.
Untuk tugas desktop bergaya agent/CV, jalankan:
pnpm openclaw qa mantis visual-task \
--browser-url https://example.net \
--expect-text "Example Domain" \
--vision-model openai/gpt-5.4
visual-task menyewa atau menggunakan kembali mesin desktop/browser Crabbox, memulai
crabbox record --while, mengendalikan browser yang terlihat melalui
visual-driver bertingkat, menangkap visual-task.png, menjalankan openclaw infer image describe
terhadap tangkapan layar saat --vision-mode image-describe dipilih, dan
menulis visual-task.mp4, mantis-visual-task-summary.json,
mantis-visual-task-driver-result.json, dan mantis-visual-task-report.md.
Saat --expect-text disetel, prompt vision meminta verdict JSON terstruktur
dan hanya lulus ketika model melaporkan bukti terlihat yang positif; respons
negatif yang hanya mengutip teks target akan menggagalkan asersi.
Gunakan --vision-mode metadata untuk smoke tanpa model yang membuktikan plumbing desktop,
browser, tangkapan layar, dan video tanpa memanggil penyedia pemahaman gambar.
Perekaman adalah artefak wajib untuk visual-task; jika Crabbox tidak merekam
visual-task.mp4 yang tidak kosong, tugas gagal meskipun visual driver
lulus. Saat gagal, Mantis mempertahankan sewa untuk VNC kecuali tugas sudah
lulus dan --keep-lease tidak disetel.
Sebelum menggunakan kredensial live yang dipool, jalankan:
pnpm openclaw qa credentials doctor
Doctor memeriksa env broker Convex, memvalidasi pengaturan endpoint, dan memverifikasi keterjangkauan admin/list saat rahasia maintainer ada. Ini hanya melaporkan status disetel/hilang untuk rahasia.
Cakupan transport live
Lane transport live berbagi satu kontrak alih-alih masing-masing menciptakan bentuk daftar skenarionya sendiri. qa-channel adalah suite perilaku produk sintetis yang luas dan bukan bagian dari matriks cakupan transport live.
| Lane | Canary | Gating mention | Bot-ke-bot | Blok allowlist | Balasan tingkat atas | Lanjutkan setelah restart | Tindak lanjut thread | Isolasi thread | Observasi reaksi | Perintah bantuan | Registrasi perintah native |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Matrix | x | x | x | x | x | x | x | x | x | ||
| Telegram | x | x | x | x | |||||||
| Discord | x | x | x | x | |||||||
| Slack | x | x | x | x | x | x | x | x |
Ini menjaga qa-channel sebagai suite perilaku produk yang luas sementara Matrix,
Telegram, dan transport live mendatang berbagi satu checklist kontrak transport
yang eksplisit.
Untuk lane VM Linux sekali pakai tanpa membawa Docker ke jalur QA, jalankan:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
Ini mem-boot guest Multipass baru, memasang dependensi, membangun OpenClaw
di dalam guest, menjalankan qa suite, lalu menyalin laporan QA normal dan
ringkasan kembali ke .artifacts/qa-e2e/... pada host.
Ini menggunakan kembali perilaku pemilihan skenario yang sama seperti qa suite pada host.
Run suite host dan Multipass mengeksekusi beberapa skenario terpilih secara paralel
dengan worker Gateway terisolasi secara default. qa-channel default ke konkurensi
4, dibatasi oleh jumlah skenario yang dipilih. Gunakan --concurrency <count> untuk menyesuaikan
jumlah worker, atau --concurrency 1 untuk eksekusi serial.
Perintah keluar non-zero saat ada skenario yang gagal. Gunakan --allow-failures saat
Anda menginginkan artefak tanpa kode keluar gagal.
Run live meneruskan input auth QA yang didukung dan praktis untuk
guest: kunci penyedia berbasis env, path konfigurasi penyedia live QA, dan
CODEX_HOME saat ada. Jaga --output-dir di bawah root repo agar guest
dapat menulis kembali melalui workspace yang dipasang.
Referensi QA Telegram, Discord, dan Slack
Matrix memiliki halaman khusus karena jumlah skenarionya dan penyediaan homeserver berbasis Docker. Telegram, Discord, dan Slack lebih kecil - masing-masing beberapa skenario, tanpa sistem profil, terhadap kanal nyata yang sudah ada - sehingga referensinya berada di sini.
Flag CLI bersama
Lane ini mendaftar melalui extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts dan menerima flag yang sama:
| Flag | Default | Deskripsi |
|---|---|---|
--scenario <id> |
- | Jalankan hanya skenario ini. Dapat diulang. |
--output-dir <path> |
<repo>/.artifacts/qa-e2e/{telegram,discord,slack}-<timestamp> |
Tempat laporan/ringkasan/pesan teramati dan log output ditulis. Path relatif diresolve terhadap --repo-root. |
--repo-root <path> |
process.cwd() |
Root repositori saat dipanggil dari cwd netral. |
--sut-account <id> |
sut |
Id akun sementara di dalam konfigurasi Gateway QA. |
--provider-mode <mode> |
live-frontier |
mock-openai atau live-frontier (live-openai lama masih berfungsi). |
--model <ref> / --alt-model <ref> |
default penyedia | Ref model primer/alternatif. |
--fast |
nonaktif | Mode cepat penyedia jika didukung. |
--credential-source <env|convex> |
env |
Lihat pool kredensial Convex. |
--credential-role <maintainer|ci> |
ci di CI, selain itu maintainer |
Peran yang digunakan saat --credential-source convex. |
Setiap lane keluar non-zero pada skenario gagal apa pun. --allow-failures menulis artefak tanpa menetapkan kode keluar gagal.
QA Telegram
pnpm openclaw qa telegram
Menargetkan satu grup Telegram privat nyata dengan dua bot berbeda (driver + SUT). Bot SUT harus memiliki username Telegram; observasi bot-ke-bot bekerja paling baik saat kedua bot mengaktifkan Mode Komunikasi Bot-ke-Bot di @BotFather.
Env wajib saat --credential-source env:
OPENCLAW_QA_TELEGRAM_GROUP_ID- id chat numerik (string).OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKENOPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN
Opsional:
OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1mempertahankan body pesan dalam artefak pesan teramati (default meredaksi).
Skenario (extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts:44):
telegram-canarytelegram-mention-gatingtelegram-mentioned-message-replytelegram-help-commandtelegram-commands-commandtelegram-tools-compact-commandtelegram-whoami-commandtelegram-context-commandtelegram-long-final-reuses-previewtelegram-long-final-three-chunks
Artefak output:
telegram-qa-report.mdtelegram-qa-summary.json- mencakup RTT per balasan (driver mengirim → balasan SUT teramati) dimulai dari canary.telegram-qa-observed-messages.json- body diredaksi kecualiOPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1.
QA Discord
pnpm openclaw qa discord
Menargetkan satu kanal guild Discord privat nyata dengan dua bot: bot driver yang dikendalikan oleh harness dan bot SUT yang dimulai oleh Gateway OpenClaw anak melalui Plugin Discord bawaan. Memverifikasi penanganan mention kanal, bahwa bot SUT telah mendaftarkan perintah native /help dengan Discord, dan skenario bukti Mantis opt-in.
Env wajib saat --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- harus cocok dengan id pengguna bot SUT yang dikembalikan oleh Discord (jika tidak, lane gagal cepat).
Opsional:
OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1mempertahankan body pesan dalam artefak pesan teramati.OPENCLAW_QA_DISCORD_VOICE_CHANNEL_IDmemilih kanal voice/stage untukdiscord-voice-autojoin; tanpanya, skenario memilih kanal voice/stage pertama yang terlihat untuk bot SUT.
Skenario (extensions/qa-lab/src/live-transports/discord/discord-live.runtime.ts:36):
discord-canarydiscord-mention-gatingdiscord-native-help-command-registrationdiscord-voice-autojoin- skenario suara opt-in. Berjalan sendiri, mengaktifkanchannels.discord.voice.autoJoin, dan memverifikasi bahwa status suara Discord bot SUT saat ini adalah channel suara/stage target. Kredensial Convex Discord dapat menyertakanvoiceChannelIdopsional; jika tidak, runner menemukan channel suara/stage pertama yang terlihat di guild.discord-status-reactions-tool-only- skenario Mantis opt-in. Berjalan sendiri karena skenario ini mengalihkan SUT ke balasan guild selalu aktif dan hanya alat denganmessages.statusReactions.enabled=true, lalu menangkap timeline reaksi REST beserta artefak visual HTML/PNG. Laporan Mantis sebelum/sesudah juga mempertahankan artefak MP4 yang disediakan skenario sebagaibaseline.mp4dancandidate.mp4.
Jalankan skenario gabung otomatis suara Discord secara eksplisit:
pnpm openclaw qa discord \
--scenario discord-voice-autojoin \
--provider-mode mock-openai
Jalankan skenario reaksi status Mantis secara eksplisit:
pnpm openclaw qa discord \
--scenario discord-status-reactions-tool-only \
--provider-mode live-frontier \
--model openai/gpt-5.4 \
--alt-model openai/gpt-5.4 \
--fast
Artefak output:
discord-qa-report.mddiscord-qa-summary.jsondiscord-qa-observed-messages.json- isi disamarkan kecualiOPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1.discord-qa-reaction-timelines.jsondandiscord-status-reactions-tool-only-timeline.pngsaat skenario reaksi status berjalan.
QA Slack
pnpm openclaw qa slack
Menargetkan satu channel privat Slack nyata dengan dua bot berbeda: bot driver yang dikendalikan oleh harness dan bot SUT yang dimulai oleh Gateway OpenClaw anak melalui Plugin Slack bawaan.
Env yang wajib saat --credential-source env:
OPENCLAW_QA_SLACK_CHANNEL_IDOPENCLAW_QA_SLACK_DRIVER_BOT_TOKENOPENCLAW_QA_SLACK_SUT_BOT_TOKENOPENCLAW_QA_SLACK_SUT_APP_TOKEN
Opsional:
OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1mempertahankan isi pesan dalam artefak pesan-teramati.
Skenario (extensions/qa-lab/src/live-transports/slack/slack-live.runtime.ts:39):
slack-canaryslack-mention-gatingslack-allowlist-blockslack-top-level-reply-shapeslack-restart-resumeslack-thread-follow-upslack-thread-isolation
Artefak output:
slack-qa-report.mdslack-qa-summary.jsonslack-qa-observed-messages.json- isi disamarkan kecualiOPENCLAW_QA_SLACK_CAPTURE_CONTENT=1.
Menyiapkan workspace Slack
Lane ini memerlukan dua aplikasi Slack berbeda dalam satu workspace, ditambah sebuah channel tempat kedua bot menjadi anggota:
channelId- idCxxxxxxxxxxdari channel tempat kedua bot telah diundang. Gunakan channel khusus; lane ini memposting pada setiap run.driverBotToken- token bot (xoxb-...) dari aplikasi Driver.sutBotToken- token bot (xoxb-...) dari aplikasi SUT, yang harus berupa aplikasi Slack terpisah dari driver agar id pengguna botnya berbeda.sutAppToken- token tingkat aplikasi (xapp-...) dari aplikasi SUT denganconnections:write, digunakan oleh Socket Mode agar aplikasi SUT dapat menerima event.
Lebih disarankan menggunakan workspace Slack khusus untuk QA daripada memakai ulang workspace produksi.
Manifest SUT di bawah ini sengaja mempersempit instalasi produksi Plugin Slack bawaan (extensions/slack/src/setup-shared.ts:10) ke izin dan event yang dicakup oleh rangkaian QA Slack live. Untuk penyiapan channel produksi sebagaimana dilihat pengguna, lihat Penyiapan cepat channel Slack; pasangan Driver/SUT QA sengaja terpisah karena lane ini memerlukan dua id pengguna bot berbeda dalam satu workspace.
1. Buat aplikasi Driver
Buka api.slack.com/apps → Create New App → From a manifest → pilih workspace QA, tempel manifest berikut, lalu Install to Workspace:
{
"display_information": {
"name": "OpenClaw QA Driver",
"description": "Test driver bot for OpenClaw QA Slack live lane"
},
"features": {
"bot_user": {
"display_name": "OpenClaw QA Driver",
"always_online": true
}
},
"oauth_config": {
"scopes": {
"bot": ["chat:write", "channels:history", "groups:history", "users:read"]
}
},
"settings": {
"socket_mode_enabled": false
}
}
Salin Bot User OAuth Token (xoxb-...) - itu menjadi driverBotToken. Driver hanya perlu memposting pesan dan mengidentifikasi dirinya; tanpa event, tanpa Socket Mode.
2. Buat aplikasi SUT
Ulangi Create New App → From a manifest di workspace yang sama. Aplikasi QA ini sengaja menggunakan versi yang lebih sempit dari manifest produksi Plugin Slack bawaan (extensions/slack/src/setup-shared.ts:10): scope dan event reaksi dihilangkan karena rangkaian QA Slack live belum mencakup penanganan reaksi.
{
"display_information": {
"name": "OpenClaw QA SUT",
"description": "OpenClaw QA SUT connector for OpenClaw"
},
"features": {
"bot_user": {
"display_name": "OpenClaw QA SUT",
"always_online": true
},
"app_home": {
"home_tab_enabled": true,
"messages_tab_enabled": true,
"messages_tab_read_only_enabled": false
}
},
"oauth_config": {
"scopes": {
"bot": [
"app_mentions:read",
"assistant:write",
"channels:history",
"channels:read",
"chat:write",
"commands",
"emoji:read",
"files:read",
"files:write",
"groups:history",
"groups:read",
"im:history",
"im:read",
"im:write",
"mpim:history",
"mpim:read",
"mpim:write",
"pins:read",
"pins:write",
"usergroups:read",
"users:read"
]
}
},
"settings": {
"socket_mode_enabled": true,
"event_subscriptions": {
"bot_events": [
"app_home_opened",
"app_mention",
"channel_rename",
"member_joined_channel",
"member_left_channel",
"message.channels",
"message.groups",
"message.im",
"message.mpim",
"pin_added",
"pin_removed"
]
}
}
}
Setelah Slack membuat aplikasi, lakukan dua hal pada halaman pengaturannya:
- Install to Workspace → salin Bot User OAuth Token → itu menjadi
sutBotToken. - Basic Information → App-Level Tokens → Generate Token and Scopes → tambahkan scope
connections:write→ simpan → salin nilaixapp-...→ itu menjadisutAppToken.
Verifikasi kedua bot memiliki id pengguna yang berbeda dengan memanggil auth.test pada masing-masing token. Runtime membedakan driver dan SUT berdasarkan id pengguna; memakai ulang satu aplikasi untuk keduanya akan langsung menggagalkan mention-gating.
3. Buat channel
Di workspace QA, buat channel (mis. #openclaw-qa) dan undang kedua bot dari dalam channel:
/invite @OpenClaw QA Driver
/invite @OpenClaw QA SUT
Salin id Cxxxxxxxxxx dari channel info → About → Channel ID - itu menjadi channelId. Channel publik bisa digunakan; jika Anda menggunakan channel privat, kedua aplikasi sudah memiliki groups:history sehingga pembacaan riwayat oleh harness tetap berhasil.
4. Daftarkan kredensial
Ada dua opsi. Gunakan variabel env untuk debugging satu mesin (atur empat variabel OPENCLAW_QA_SLACK_* dan berikan --credential-source env), atau seed pool Convex bersama agar CI dan maintainer lain dapat menyewanya.
Untuk pool Convex, tulis empat bidang ke file JSON:
{
"channelId": "Cxxxxxxxxxx",
"driverBotToken": "xoxb-...",
"sutBotToken": "xoxb-...",
"sutAppToken": "xapp-..."
}
Dengan OPENCLAW_QA_CONVEX_SITE_URL dan OPENCLAW_QA_CONVEX_SECRET_MAINTAINER diekspor di shell Anda, daftarkan dan verifikasi:
pnpm openclaw qa credentials add \
--kind slack \
--payload-file slack-creds.json \
--note "QA Slack pool seed"
pnpm openclaw qa credentials list --kind slack --status all --json
Harapkan count: 1, status: "active", tanpa bidang lease.
5. Verifikasi end to end
Jalankan lane secara lokal untuk mengonfirmasi kedua bot dapat saling berkomunikasi melalui broker:
pnpm openclaw qa slack \
--credential-source convex \
--credential-role maintainer \
--output-dir .artifacts/qa-e2e/slack-local
Run yang berhasil selesai jauh di bawah 30 detik dan slack-qa-report.md menampilkan slack-canary dan slack-mention-gating dengan status pass. Jika lane menggantung selama ~90 detik dan keluar dengan Convex credential pool exhausted for kind "slack", pool kosong atau setiap baris sedang disewa - qa credentials list --kind slack --status all --json akan memberi tahu yang mana.
Pool kredensial Convex
Lane Telegram, Discord, dan Slack dapat menyewa kredensial dari pool Convex bersama alih-alih membaca variabel env di atas. Berikan --credential-source convex (atau atur OPENCLAW_QA_CREDENTIAL_SOURCE=convex); QA Lab memperoleh lease eksklusif, mengirim Heartbeat selama durasi run, dan melepaskannya saat shutdown. Jenis pool adalah "telegram", "discord", dan "slack".
Bentuk payload yang divalidasi broker pada admin/add:
- Telegram (
kind: "telegram"):{ groupId: string, driverToken: string, sutToken: string }-groupIdharus berupa string chat-id numerik. - Discord (
kind: "discord"):{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }. - Slack (
kind: "slack"):{ channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string }-channelIdharus cocok dengan^[A-Z][A-Z0-9]+$(id Slack sepertiCxxxxxxxxxx). Lihat Menyiapkan workspace Slack untuk penyediaan aplikasi dan scope.
Variabel env operasional dan kontrak endpoint broker Convex ada di Pengujian → Kredensial Telegram bersama melalui Convex (nama bagian ini sudah ada sebelum dukungan Discord; semantik broker identik untuk kedua jenis).
Seed berbasis repo
Aset seed berada di qa/:
qa/scenarios/index.mdqa/scenarios/<theme>/*.md
Aset ini sengaja ada di git agar rencana QA terlihat oleh manusia dan agen.
qa-lab harus tetap menjadi runner markdown generik. Setiap file markdown skenario adalah sumber kebenaran untuk satu run pengujian dan harus mendefinisikan:
- metadata skenario
- metadata kategori, kapabilitas, lane, dan risiko opsional
- referensi docs dan kode
- persyaratan Plugin opsional
- patch konfigurasi Gateway opsional
qa-flowyang dapat dieksekusi
Permukaan runtime pakai ulang yang mendukung qa-flow boleh tetap generik dan lintas-cutting. Misalnya, skenario markdown dapat menggabungkan helper sisi transport dengan helper sisi browser yang menggerakkan Control UI tertanam melalui seam browser.request Gateway tanpa menambahkan runner kasus khusus.
File skenario harus dikelompokkan berdasarkan kapabilitas produk, bukan folder source tree. Pertahankan ID skenario tetap stabil saat file dipindahkan; gunakan docsRefs dan codeRefs untuk keterlacakan implementasi.
Daftar baseline harus tetap cukup luas untuk mencakup:
- chat DM dan channel
- perilaku thread
- siklus hidup tindakan pesan
- callback Cron
- recall memori
- perpindahan model
- handoff subagent
- pembacaan repo dan pembacaan docs
- satu tugas build kecil seperti Lobster Invaders
Lane mock provider
qa suite memiliki dua lane mock provider lokal:
mock-openaiadalah mock OpenClaw yang sadar skenario. Ini tetap menjadi lane mock deterministik default untuk QA berbasis repo dan parity gate.aimockmemulai server provider berbasis AIMock untuk cakupan protokol, fixture, record/replay, dan chaos eksperimental. Ini bersifat aditif dan tidak menggantikan dispatcher skenariomock-openai.
Implementasi provider-lane berada di bawah extensions/qa-lab/src/providers/. Setiap provider memiliki default, startup server lokal, konfigurasi model Gateway, kebutuhan staging auth-profile, dan flag kapabilitas live/mock miliknya sendiri. Kode shared suite dan Gateway harus merutekan melalui registry provider alih-alih bercabang berdasarkan nama provider.
Adapter transport
qa-lab memiliki seam transport generik untuk skenario QA markdown. qa-channel adalah adapter pertama pada seam tersebut, tetapi target desainnya lebih luas: channel nyata atau sintetis di masa depan harus dapat terhubung ke runner suite yang sama, bukan menambahkan runner QA khusus transport.
Pada tingkat arsitektur, pembagiannya adalah:
qa-labmemiliki eksekusi skenario generik, konkurensi worker, penulisan artefak, dan pelaporan.- Adapter transport memiliki konfigurasi Gateway, kesiapan, observasi inbound dan outbound, tindakan transport, dan status transport yang dinormalisasi.
- File skenario Markdown di bawah
qa/scenarios/mendefinisikan test run;qa-labmenyediakan permukaan runtime pakai ulang yang mengeksekusinya.
Menambahkan channel
Menambahkan channel ke sistem QA markdown memerlukan tepat dua hal:
- Adapter transport untuk channel tersebut.
- Paket skenario yang menguji kontrak channel.
Jangan tambahkan root perintah QA tingkat atas baru ketika host bersama qa-lab dapat memiliki alurnya.
qa-lab memiliki mekanisme host bersama:
- root perintah
openclaw qa - startup dan teardown suite
- konkurensi worker
- penulisan artefak
- pembuatan laporan
- eksekusi skenario
- alias kompatibilitas untuk skenario
qa-channellama
Plugin runner memiliki kontrak transport:
- bagaimana
openclaw qa <runner>dipasang di bawah rootqabersama - bagaimana Gateway dikonfigurasi untuk transport tersebut
- bagaimana kesiapan diperiksa
- bagaimana event inbound disuntikkan
- bagaimana pesan outbound diamati
- bagaimana transkrip dan status transport yang dinormalisasi diekspos
- bagaimana tindakan berbasis transport dieksekusi
- bagaimana reset atau pembersihan khusus transport ditangani
Batas minimum adopsi untuk channel baru:
- Pertahankan
qa-labsebagai pemilik rootqabersama. - Implementasikan runner transport pada seam host
qa-labbersama. - Pertahankan mekanisme khusus transport di dalam Plugin runner atau harness channel.
- Pasang runner sebagai
openclaw qa <runner>, bukan mendaftarkan root perintah pesaing. Plugin runner harus mendeklarasikanqaRunnersdiopenclaw.plugin.jsondan mengekspor arrayqaRunnerCliRegistrationsyang sesuai dariruntime-api.ts. Jagaruntime-api.tstetap ringan; CLI lazy dan eksekusi runner harus tetap berada di balik entrypoint terpisah. - Tulis atau adaptasi skenario markdown di bawah direktori bertema
qa/scenarios/. - Gunakan helper skenario generik untuk skenario baru.
- Pertahankan alias kompatibilitas yang ada tetap berfungsi kecuali repo sedang melakukan migrasi yang disengaja.
Aturan keputusannya ketat:
- Jika perilaku dapat diekspresikan sekali di
qa-lab, letakkan diqa-lab. - Jika perilaku bergantung pada satu transport channel, pertahankan di Plugin runner atau harness Plugin tersebut.
- Jika sebuah skenario membutuhkan kapabilitas baru yang dapat digunakan oleh lebih dari satu channel, tambahkan helper generik alih-alih cabang khusus channel di
suite.ts. - Jika suatu perilaku hanya bermakna untuk satu transport, pertahankan skenario tersebut khusus transport dan buat itu eksplisit dalam kontrak skenario.
Nama helper skenario
Helper generik yang disarankan untuk skenario baru:
waitForTransportReadywaitForChannelReadyinjectInboundMessageinjectOutboundMessagewaitForTransportOutboundMessagewaitForChannelOutboundMessagewaitForNoTransportOutboundgetTransportSnapshotreadTransportMessagereadTransportTranscriptformatTransportTranscriptresetTransport
Alias kompatibilitas tetap tersedia untuk skenario yang ada - waitForQaChannelReady, waitForOutboundMessage, waitForNoOutbound, formatConversationTranscript, resetBus - tetapi penulisan skenario baru harus menggunakan nama generik. Alias tersebut ada untuk menghindari migrasi flag-day, bukan sebagai model ke depan.
Pelaporan
qa-lab mengekspor laporan protokol Markdown dari timeline bus yang diamati.
Laporan tersebut harus menjawab:
- Apa yang berhasil
- Apa yang gagal
- Apa yang tetap terblokir
- Skenario tindak lanjut apa yang layak ditambahkan
Untuk inventaris skenario yang tersedia - berguna saat mengukur pekerjaan tindak lanjut atau memasang transport baru - jalankan pnpm openclaw qa coverage (tambahkan --json untuk output yang dapat dibaca mesin).
Untuk pemeriksaan karakter dan gaya, jalankan skenario yang sama di beberapa ref model live dan tulis laporan Markdown yang dinilai:
pnpm openclaw qa character-eval \
--model openai/gpt-5.5,thinking=medium,fast \
--model openai/gpt-5.2,thinking=xhigh \
--model openai/gpt-5,thinking=xhigh \
--model anthropic/claude-opus-4-6,thinking=high \
--model anthropic/claude-sonnet-4-6,thinking=high \
--model zai/glm-5.1,thinking=high \
--model moonshot/kimi-k2.5,thinking=high \
--model google/gemini-3.1-pro-preview,thinking=high \
--judge-model openai/gpt-5.5,thinking=xhigh,fast \
--judge-model anthropic/claude-opus-4-6,thinking=high \
--blind-judge-models \
--concurrency 16 \
--judge-concurrency 16
Perintah tersebut menjalankan proses anak Gateway QA lokal, bukan Docker. Skenario evaluasi karakter
harus menetapkan persona melalui SOUL.md, lalu menjalankan giliran pengguna biasa
seperti chat, bantuan workspace, dan tugas file kecil. Model kandidat tidak boleh
diberi tahu bahwa ia sedang dievaluasi. Perintah tersebut mempertahankan setiap transkrip
lengkap, mencatat statistik run dasar, lalu meminta model juri dalam mode fast dengan
reasoning xhigh jika didukung untuk memberi peringkat run berdasarkan kewajaran, vibe, dan humor.
Gunakan --blind-judge-models saat membandingkan provider: prompt juri tetap mendapatkan
setiap transkrip dan status run, tetapi ref kandidat diganti dengan label netral
seperti candidate-01; laporan memetakan peringkat kembali ke ref nyata setelah
parsing.
Run kandidat default ke thinking high, dengan medium untuk GPT-5.5 dan xhigh
untuk ref eval OpenAI lama yang mendukungnya. Timpa kandidat tertentu secara inline dengan
--model provider/model,thinking=<level>. --thinking <level> tetap menetapkan
fallback global, dan bentuk lama --model-thinking <provider/model=level> tetap
dipertahankan untuk kompatibilitas.
Ref kandidat OpenAI default ke mode fast agar pemrosesan prioritas digunakan jika
provider mendukungnya. Tambahkan ,fast, ,no-fast, atau ,fast=false secara inline saat
satu kandidat atau juri membutuhkan override. Berikan --fast hanya saat Anda ingin
memaksa mode fast aktif untuk setiap model kandidat. Durasi kandidat dan juri
dicatat dalam laporan untuk analisis benchmark, tetapi prompt juri secara eksplisit mengatakan
untuk tidak memberi peringkat berdasarkan kecepatan.
Run model kandidat dan juri sama-sama default ke konkurensi 16. Turunkan
--concurrency atau --judge-concurrency ketika batas provider atau tekanan Gateway
lokal membuat run terlalu berisik.
Ketika tidak ada kandidat --model yang diberikan, evaluasi karakter default ke
openai/gpt-5.5, openai/gpt-5.2, openai/gpt-5, anthropic/claude-opus-4-6,
anthropic/claude-sonnet-4-6, zai/glm-5.1,
moonshot/kimi-k2.5, dan
google/gemini-3.1-pro-preview ketika tidak ada --model yang diberikan.
Ketika tidak ada --judge-model yang diberikan, juri default ke
openai/gpt-5.5,thinking=xhigh,fast dan
anthropic/claude-opus-4-6,thinking=high.