Fundamentals
Przegląd QA
Prywatny stos QA ma ćwiczyć OpenClaw w bardziej realistyczny, kanałowy sposób, niż pozwala na to pojedynczy test jednostkowy.
Obecne elementy:
extensions/qa-channel: syntetyczny kanał wiadomości z powierzchniami DM, kanału, wątku, reakcji, edycji i usuwania.extensions/qa-lab: interfejs debuggera i magistrala QA do obserwowania transkryptu, wstrzykiwania wiadomości przychodzących i eksportowania raportu Markdown.extensions/qa-matrix, przyszłe pluginy uruchamiające: adaptery transportu na żywo, które sterują prawdziwym kanałem w podrzędnym QA gateway.qa/: zasoby źródłowe z repozytorium dla zadania startowego i bazowych scenariuszy QA.- Mantis: weryfikacja na żywo przed i po dla błędów, które wymagają prawdziwych transportów, zrzutów ekranu przeglądarki, stanu VM i dowodów PR.
Powierzchnia poleceń
Każdy przepływ QA działa pod pnpm openclaw qa <subcommand>. Wiele z nich ma aliasy skryptów pnpm qa:*;
obsługiwane są obie formy.
| Polecenie | Cel |
|---|---|
qa run |
Dołączony autotest QA; zapisuje raport Markdown. |
qa suite |
Uruchom scenariusze z repozytorium względem ścieżki QA gateway. Aliasy: pnpm openclaw qa suite --runner multipass dla jednorazowej maszyny VM z Linuksem. |
qa coverage |
Wypisz markdownowy spis pokrycia scenariuszy (--json dla wyjścia maszynowego). |
qa parity-report |
Porównaj dwa pliki qa-suite-summary.json i zapisz raport parytetu agentowego. |
qa character-eval |
Uruchom scenariusz QA postaci na wielu modelach live z ocenianym raportem. Zobacz Raportowanie. |
qa manual |
Uruchom jednorazowy prompt względem wybranej ścieżki dostawcy/modelu. |
qa ui |
Uruchom interfejs debuggera QA i lokalną magistralę QA (alias: pnpm qa:lab:ui). |
qa docker-build-image |
Zbuduj wstępnie przygotowany obraz Docker QA. |
qa docker-scaffold |
Zapisz szkielet docker-compose dla panelu QA + ścieżki gateway. |
qa up |
Zbuduj stronę QA, uruchom stos wsparty Dockerem, wypisz URL (alias: pnpm qa:lab:up; wariant :fast dodaje --use-prebuilt-image --bind-ui-dist --skip-ui-build). |
qa aimock |
Uruchom tylko serwer dostawcy AIMock. |
qa mock-openai |
Uruchom tylko świadomy scenariuszy serwer dostawcy mock-openai. |
qa credentials doctor / add / list / remove |
Zarządzaj współdzieloną pulą poświadczeń Convex. |
qa matrix |
Ścieżka transportu live względem jednorazowego homeservera Tuwunel. Zobacz Matrix QA. |
qa telegram |
Ścieżka transportu live względem prawdziwej prywatnej grupy Telegram. |
qa discord |
Ścieżka transportu live względem prawdziwego prywatnego kanału gildii Discord. |
qa slack |
Ścieżka transportu live względem prawdziwego prywatnego kanału Slack. |
qa mantis |
Runner weryfikacji przed i po dla błędów transportu live, z dowodami w postaci reakcji statusu Discord, smoke testem pulpitu/przeglądarki Crabbox oraz smoke testem Slack-in-VNC. Zobacz Mantis i Runbook Mantis Slack Desktop. |
Przepływ operatora
Obecny przepływ operatora QA to dwupanelowa strona QA:
- Lewo: panel Gateway (Control UI) z agentem.
- Prawo: QA Lab, pokazujące transkrypt w stylu Slack i plan scenariusza.
Uruchom go przez:
pnpm qa:lab:up
To buduje stronę QA, uruchamia wspartą Dockerem ścieżkę gateway i udostępnia stronę QA Lab, gdzie operator lub pętla automatyzacji może przekazać agentowi misję QA, obserwować rzeczywiste zachowanie kanału i zapisać, co zadziałało, zawiodło lub pozostało zablokowane.
Aby szybciej iterować nad interfejsem QA Lab bez przebudowywania obrazu Docker za każdym razem, uruchom stos z podmontowanym bindem pakietem QA Lab:
pnpm openclaw qa docker-build-image
pnpm qa:lab:build
pnpm qa:lab:up:fast
pnpm qa:lab:watch
qa:lab:up:fast utrzymuje usługi Docker na wstępnie zbudowanym obrazie i podmontowuje bindem
extensions/qa-lab/web/dist do kontenera qa-lab. qa:lab:watch
przebudowuje ten pakiet po zmianie, a przeglądarka automatycznie przeładowuje się, gdy zmieni się
hash zasobów QA Lab.
Dla lokalnego smoke testu śladu OpenTelemetry uruchom:
pnpm qa:otel:smoke
Ten skrypt uruchamia lokalny odbiornik śladów OTLP/HTTP, uruchamia scenariusz QA
otel-trace-smoke z włączonym pluginem diagnostics-otel, następnie
dekoduje wyeksportowane spany protobuf i sprawdza krytyczny dla wydania kształt:
openclaw.run, openclaw.harness.run, openclaw.model.call,
openclaw.context.assembled i openclaw.message.delivery muszą być obecne;
wywołania modelu nie mogą eksportować StreamAbandoned przy udanych turach; surowe identyfikatory diagnostyczne i
atrybuty openclaw.content.* muszą pozostać poza śladem. Skrypt zapisuje
otel-smoke-summary.json obok artefaktów zestawu QA.
QA obserwowalności pozostaje dostępne tylko z checkoutu źródeł. Tarball npm celowo pomija
QA Lab, więc ścieżki wydania pakietów Docker nie uruchamiają poleceń qa. Użyj
pnpm qa:otel:smoke ze zbudowanego checkoutu źródeł przy zmianie instrumentacji
diagnostycznej.
Dla ścieżki smoke Matrix z prawdziwym transportem uruchom:
pnpm openclaw qa matrix --profile fast --fail-fast
Pełna referencja CLI, katalog profili/scenariuszy, zmienne env i układ artefaktów dla tej ścieżki znajdują się w Matrix QA. W skrócie: aprowizuje jednorazowy homeserver Tuwunel w Dockerze, rejestruje tymczasowych użytkowników driver/SUT/observer, uruchamia prawdziwy Plugin Matrix w podrzędnym QA gateway ograniczonym do tego transportu (bez qa-channel), a następnie zapisuje raport Markdown, podsumowanie JSON, artefakt zaobserwowanych zdarzeń i połączony log wyjścia pod .artifacts/qa-e2e/matrix-<timestamp>/.
Scenariusze obejmują zachowanie transportu, którego testy jednostkowe nie mogą udowodnić end to end: bramkowanie wzmianek, zasady allow-bot, listy dozwolonych, odpowiedzi najwyższego poziomu i w wątkach, routing DM, obsługę reakcji, tłumienie edycji przychodzących, deduplikację replay po restarcie, odzyskiwanie po przerwaniu homeservera, dostarczanie metadanych zatwierdzeń, obsługę mediów oraz przepływy rozruchu/odzyskiwania/weryfikacji Matrix E2EE. Profil CLI E2EE uruchamia także openclaw matrix encryption setup i polecenia weryfikacji przez ten sam jednorazowy homeserver przed sprawdzeniem odpowiedzi gateway.
Discord ma też scenariusze opt-in tylko dla Mantis do reprodukcji błędów. Użyj
--scenario discord-status-reactions-tool-only dla jawnej osi czasu reakcji statusu
albo --scenario discord-thread-reply-filepath-attachment, aby utworzyć
prawdziwy wątek Discord i zweryfikować, że message.thread-reply zachowuje
załącznik filePath. Te scenariusze pozostają poza domyślną ścieżką live Discord,
ponieważ są próbami reprodukcji przed/po, a nie szerokim pokryciem smoke.
Przepływ Mantis dla załączników w wątku może też dodać nagranie świadka w Discord Web
z zalogowaną sesją, gdy w środowisku QA skonfigurowano
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR lub
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64. Ten profil widza służy tylko do przechwytywania wizualnego; decyzja pass/fail
nadal pochodzi z wyroczni Discord REST.
CI używa tej samej powierzchni poleceń w .github/workflows/qa-live-transports-convex.yml. Zaplanowane i domyślne ręczne uruchomienia wykonują szybki profil Matrix z poświadczeniami live frontier, --fast i OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000. Ręczne matrix_profile=all rozdziela się na pięć shardów profili, aby wyczerpujący katalog mógł działać równolegle, zachowując jeden katalog artefaktów na shard.
Dla ścieżek smoke z prawdziwym transportem Telegram, Discord i Slack:
pnpm openclaw qa telegram
pnpm openclaw qa discord
pnpm openclaw qa slack
Celują one w istniejący prawdziwy kanał z dwoma botami (driver + SUT). Wymagane zmienne env, listy scenariuszy, artefakty wyjściowe i pula poświadczeń Convex są udokumentowane w referencji QA Telegram, Discord i Slack poniżej.
Dla pełnego uruchomienia VM pulpitu Slack z ratunkiem przez VNC uruchom:
pnpm openclaw qa mantis slack-desktop-smoke \
--gateway-setup \
--scenario slack-canary \
--keep-lease
To polecenie dzierżawi maszynę Crabbox z pulpitem/przeglądarką, uruchamia ścieżkę live Slack
wewnątrz VM, otwiera Slack Web w przeglądarce VNC, przechwytuje pulpit i
kopiuje slack-qa/, slack-desktop-smoke.png oraz slack-desktop-smoke.mp4
z powrotem do katalogu artefaktów Mantis, gdy przechwytywanie wideo jest dostępne. Dzierżawy Crabbox
z pulpitem/przeglądarką zapewniają z góry narzędzia przechwytywania oraz pakiety pomocnicze przeglądarki/natywnej kompilacji,
więc scenariusz powinien instalować rozwiązania awaryjne tylko na starszych
dzierżawach. Mantis raportuje łączne czasy oraz czasy poszczególnych faz w
mantis-slack-desktop-smoke-report.md, dzięki czemu przy wolnych uruchomieniach widać, czy czas został zużyty na
rozgrzanie dzierżawy, pozyskanie poświadczeń, zdalną konfigurację czy kopiowanie artefaktów. Użyj ponownie
--lease-id <cbx_...> po ręcznym zalogowaniu się do Slack Web przez VNC;
ponownie użyte dzierżawy utrzymują też rozgrzaną pamięć podręczną magazynu pnpm Crabbox. Domyślne
--hydrate-mode source weryfikuje z checkoutu źródeł i uruchamia instalację/kompilację
wewnątrz VM. Użyj --hydrate-mode prehydrated tylko wtedy, gdy ponownie używany zdalny
obszar roboczy ma już node_modules i zbudowany dist/; ten tryb pomija
kosztowny krok instalacji/kompilacji i zamyka się niepowodzeniem, gdy obszar roboczy nie jest gotowy.
Z --gateway-setup Mantis pozostawia trwały Gateway Slack OpenClaw
uruchomiony wewnątrz VM na porcie 38973; bez tego polecenie uruchamia standardową
ścieżkę QA bot-do-bota Slack i kończy pracę po przechwyceniu artefaktów.
Lista kontrolna operatora, polecenie wywołania workflow GitHub, kontrakt komentarza z dowodami, tabela decyzyjna trybu hydratacji, interpretacja czasów i kroki obsługi awarii znajdują się w Runbook Mantis Slack Desktop.
Dla zadania pulpitu w stylu agenta/CV uruchom:
pnpm openclaw qa mantis visual-task \
--browser-url https://example.net \
--expect-text "Example Domain" \
--vision-model openai/gpt-5.4
visual-task dzierżawi lub ponownie używa maszyny Crabbox z pulpitem/przeglądarką, uruchamia
crabbox record --while, steruje widoczną przeglądarką przez zagnieżdżony
visual-driver, przechwytuje visual-task.png, uruchamia openclaw infer image describe
na zrzucie ekranu, gdy wybrano --vision-mode image-describe, oraz
zapisuje visual-task.mp4, mantis-visual-task-summary.json,
mantis-visual-task-driver-result.json i mantis-visual-task-report.md.
Gdy ustawiono --expect-text, prompt wizyjny prosi o ustrukturyzowany werdykt JSON
i przechodzi tylko wtedy, gdy model zgłasza pozytywny widoczny dowód; odpowiedź
negatywna, która jedynie cytuje tekst docelowy, nie spełnia asercji.
Użyj --vision-mode metadata do smoke bez modelu, który potwierdza działanie pulpitu,
przeglądarki, zrzutu ekranu i instalacji wideo bez wywoływania dostawcy
rozumienia obrazu. Nagranie jest wymaganym artefaktem dla visual-task; jeśli Crabbox nie nagra
niepustego visual-task.mp4, zadanie kończy się niepowodzeniem nawet wtedy, gdy sterownik wizyjny
przeszedł. Przy awarii Mantis zachowuje dzierżawę dla VNC, chyba że zadanie już
przeszło, a --keep-lease nie zostało ustawione.
Przed użyciem pulowanych poświadczeń live uruchom:
pnpm openclaw qa credentials doctor
Doctor sprawdza env brokera Convex, waliduje ustawienia endpointu i weryfikuje osiągalność admin/list, gdy sekret maintenera jest obecny. Raportuje dla sekretów tylko stan ustawione/brakujące.
Pokrycie transportu live
Ścieżki transportu live współdzielą jeden kontrakt, zamiast każda wymyślała własny kształt listy scenariuszy. qa-channel jest szerokim syntetycznym pakietem zachowań produktu i nie należy do macierzy pokrycia transportu live.
| Ścieżka | Kanarek | Bramkowanie wzmianek | Bot-do-bota | Blokada listy dozwolonych | Odpowiedź najwyższego poziomu | Wznowienie po restarcie | Dalsza odpowiedź w wątku | Izolacja wątku | Obserwacja reakcji | Polecenie pomocy | Rejestracja poleceń natywnych |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 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 |
To utrzymuje qa-channel jako szeroki pakiet zachowań produktu, podczas gdy Matrix,
Telegram i przyszłe transporty live współdzielą jedną jawną listę kontrolną
kontraktu transportu.
Dla jednorazowej ścieżki VM Linux bez wprowadzania Docker do ścieżki QA uruchom:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
To uruchamia świeżego gościa Multipass, instaluje zależności, buduje OpenClaw
wewnątrz gościa, uruchamia qa suite, a następnie kopiuje standardowy raport QA i
podsumowanie z powrotem do .artifacts/qa-e2e/... na hoście.
Używa tego samego zachowania wyboru scenariuszy co qa suite na hoście.
Uruchomienia pakietu na hoście i w Multipass domyślnie wykonują wiele wybranych scenariuszy równolegle
z izolowanymi pracownikami Gateway. qa-channel domyślnie używa współbieżności
4, ograniczonej liczbą wybranych scenariuszy. Użyj --concurrency <count>, aby dostroić
liczbę pracowników, albo --concurrency 1 dla wykonania szeregowego.
Polecenie kończy się kodem różnym od zera, gdy dowolny scenariusz zakończy się niepowodzeniem. Użyj --allow-failures, gdy
chcesz artefakty bez nieudanego kodu wyjścia.
Uruchomienia live przekazują obsługiwane wejścia uwierzytelniania QA, które są praktyczne dla
gościa: klucze dostawców z env, ścieżkę konfiguracji dostawcy QA live oraz
CODEX_HOME, gdy jest obecne. Trzymaj --output-dir pod katalogiem głównym repozytorium, aby gość
mógł zapisywać z powrotem przez zamontowany obszar roboczy.
Referencja QA dla Telegram, Discord i Slack
Matrix ma dedykowaną stronę z powodu liczby scenariuszy i provisioningu homeservera opartego na Docker. Telegram, Discord i Slack są mniejsze - po kilka scenariuszy każdy, bez systemu profili, względem wcześniej istniejących prawdziwych kanałów - więc ich referencja znajduje się tutaj.
Wspólne flagi CLI
Te ścieżki rejestrują się przez extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts i akceptują te same flagi:
| Flaga | Domyślnie | Opis |
|---|---|---|
--scenario <id> |
- | Uruchom tylko ten scenariusz. Powtarzalne. |
--output-dir <path> |
<repo>/.artifacts/qa-e2e/{telegram,discord,slack}-<timestamp> |
Miejsce zapisu raportów/podsumowania/zaobserwowanych wiadomości oraz dziennika wyjściowego. Ścieżki względne są rozwiązywane względem --repo-root. |
--repo-root <path> |
process.cwd() |
Katalog główny repozytorium przy wywołaniu z neutralnego cwd. |
--sut-account <id> |
sut |
Tymczasowy identyfikator konta wewnątrz konfiguracji Gateway QA. |
--provider-mode <mode> |
live-frontier |
mock-openai lub live-frontier (starsze live-openai nadal działa). |
--model <ref> / --alt-model <ref> |
domyślne dostawcy | Referencje modelu podstawowego/alternatywnego. |
--fast |
wyłączone | Tryb szybki dostawcy tam, gdzie jest obsługiwany. |
--credential-source <env|convex> |
env |
Zobacz pula poświadczeń Convex. |
--credential-role <maintainer|ci> |
ci w CI, w przeciwnym razie maintainer |
Rola używana przy --credential-source convex. |
Każda ścieżka kończy się kodem różnym od zera przy dowolnym nieudanym scenariuszu. --allow-failures zapisuje artefakty bez ustawiania nieudanego kodu wyjścia.
QA Telegram
pnpm openclaw qa telegram
Celuje w jedną prawdziwą prywatną grupę Telegram z dwoma różnymi botami (sterownik + SUT). Bot SUT musi mieć nazwę użytkownika Telegram; obserwacja bot-do-bota działa najlepiej, gdy oba boty mają włączony Tryb komunikacji bot-do-bota w @BotFather.
Wymagane env przy --credential-source env:
OPENCLAW_QA_TELEGRAM_GROUP_ID- numeryczny identyfikator czatu (ciąg znaków).OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKENOPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN
Opcjonalne:
OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1zachowuje treści wiadomości w artefaktach zaobserwowanych wiadomości (domyślnie redaguje).
Scenariusze (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
Artefakty wyjściowe:
telegram-qa-report.mdtelegram-qa-summary.json- zawiera RTT dla każdej odpowiedzi (wysłanie przez sterownik → zaobserwowana odpowiedź SUT), zaczynając od kanarka.telegram-qa-observed-messages.json- treści redagowane, chyba żeOPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1.
QA Discord
pnpm openclaw qa discord
Celuje w jeden prawdziwy prywatny kanał gildii Discord z dwoma botami: botem sterownika kontrolowanym przez harness oraz botem SUT uruchamianym przez podrzędny Gateway OpenClaw przez dołączony Plugin Discord. Weryfikuje obsługę wzmianek w kanale, to, że bot SUT zarejestrował natywne polecenie /help w Discord, oraz opcjonalne scenariusze dowodów Mantis.
Wymagane env przy --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- musi odpowiadać identyfikatorowi użytkownika bota SUT zwróconemu przez Discord (w przeciwnym razie ścieżka szybko kończy się niepowodzeniem).
Opcjonalne:
OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1zachowuje treści wiadomości w artefaktach zaobserwowanych wiadomości.OPENCLAW_QA_DISCORD_VOICE_CHANNEL_IDwybiera kanał głosowy/sceniczny dladiscord-voice-autojoin; bez tego scenariusz wybiera pierwszy widoczny kanał głosowy/sceniczny dla bota SUT.
Scenariusze (extensions/qa-lab/src/live-transports/discord/discord-live.runtime.ts:36):
discord-canarydiscord-mention-gatingdiscord-native-help-command-registrationdiscord-voice-autojoin- opcjonalny scenariusz głosowy. Uruchamia się samodzielnie, włączachannels.discord.voice.autoJoini sprawdza, czy bieżący stan głosowy bota SUT w Discord jest docelowym kanałem głosowym/scenicznym. Dane uwierzytelniające Convex Discord mogą zawierać opcjonalnevoiceChannelId; w przeciwnym razie runner wykrywa pierwszy widoczny kanał głosowy/sceniczny w gildii.discord-status-reactions-tool-only- opcjonalny scenariusz Mantis. Uruchamia się samodzielnie, ponieważ przełącza SUT na stale włączone odpowiedzi w gildii wyłącznie z narzędziami zmessages.statusReactions.enabled=true, a następnie przechwytuje oś czasu reakcji REST oraz artefakty wizualne HTML/PNG. Raporty Mantis przed/po zachowują także artefakty MP4 dostarczone przez scenariusz jakobaseline.mp4icandidate.mp4.
Uruchom jawnie scenariusz automatycznego dołączania do kanału głosowego Discord:
pnpm openclaw qa discord \
--scenario discord-voice-autojoin \
--provider-mode mock-openai
Uruchom jawnie scenariusz reakcji statusu Mantis:
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
Artefakty wyjściowe:
discord-qa-report.mddiscord-qa-summary.jsondiscord-qa-observed-messages.json- treści zredagowane, chyba że ustawionoOPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1.discord-qa-reaction-timelines.jsonidiscord-status-reactions-tool-only-timeline.png, gdy uruchamiany jest scenariusz reakcji statusu.
QA Slack
pnpm openclaw qa slack
Celuje w jeden rzeczywisty prywatny kanał Slack z dwoma odrębnymi botami: botem sterownika kontrolowanym przez harness oraz botem SUT uruchamianym przez podrzędny Gateway OpenClaw za pośrednictwem dołączonego Pluginu Slack.
Wymagane zmienne środowiskowe przy --credential-source env:
OPENCLAW_QA_SLACK_CHANNEL_IDOPENCLAW_QA_SLACK_DRIVER_BOT_TOKENOPENCLAW_QA_SLACK_SUT_BOT_TOKENOPENCLAW_QA_SLACK_SUT_APP_TOKEN
Opcjonalnie:
OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1zachowuje treści wiadomości w artefaktach obserwowanych wiadomości.
Scenariusze (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
Artefakty wyjściowe:
slack-qa-report.mdslack-qa-summary.jsonslack-qa-observed-messages.json- treści zredagowane, chyba że ustawionoOPENCLAW_QA_SLACK_CAPTURE_CONTENT=1.
Konfigurowanie obszaru roboczego Slack
Ta ścieżka wymaga dwóch odrębnych aplikacji Slack w jednym obszarze roboczym oraz kanału, którego członkami są oba boty:
channelId- identyfikatorCxxxxxxxxxxkanału, do którego zaproszono oba boty. Użyj dedykowanego kanału; ścieżka publikuje w nim przy każdym uruchomieniu.driverBotToken- token bota (xoxb-...) aplikacji Driver.sutBotToken- token bota (xoxb-...) aplikacji SUT, która musi być oddzielną aplikacją Slack od sterownika, aby identyfikator użytkownika jej bota był odrębny.sutAppToken- token na poziomie aplikacji (xapp-...) aplikacji SUT zconnections:write, używany przez Socket Mode, aby aplikacja SUT mogła odbierać zdarzenia.
Preferuj obszar roboczy Slack dedykowany QA zamiast ponownego użycia produkcyjnego obszaru roboczego.
Poniższy manifest SUT celowo zawęża produkcyjną instalację dołączonego Pluginu Slack (extensions/slack/src/setup-shared.ts:10) do uprawnień i zdarzeń objętych zestawem live QA Slack. Konfigurację kanału produkcyjnego widzianą przez użytkowników opisuje szybka konfiguracja kanału Slack; para QA Driver/SUT jest celowo oddzielna, ponieważ ścieżka wymaga dwóch odrębnych identyfikatorów użytkowników botów w jednym obszarze roboczym.
1. Utwórz aplikację Driver
Przejdź do api.slack.com/apps → Create New App → From a manifest → wybierz obszar roboczy QA, wklej następujący manifest, a następnie 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
}
}
Skopiuj Bot User OAuth Token (xoxb-...) - staje się on driverBotToken. Sterownik potrzebuje tylko publikować wiadomości i identyfikować siebie; bez zdarzeń, bez Socket Mode.
2. Utwórz aplikację SUT
Powtórz Create New App → From a manifest w tym samym obszarze roboczym. Ta aplikacja QA celowo używa węższej wersji produkcyjnego manifestu dołączonego Pluginu Slack (extensions/slack/src/setup-shared.ts:10): zakresy i zdarzenia reakcji są pominięte, ponieważ zestaw live QA Slack nie obejmuje jeszcze obsługi reakcji.
{
"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"
]
}
}
}
Po utworzeniu aplikacji przez Slack wykonaj dwie czynności na jej stronie ustawień:
- Install to Workspace → skopiuj Bot User OAuth Token → staje się on
sutBotToken. - Basic Information → App-Level Tokens → Generate Token and Scopes → dodaj zakres
connections:write→ zapisz → skopiuj wartośćxapp-...→ staje się onasutAppToken.
Sprawdź, czy oba boty mają odrębne identyfikatory użytkowników, wywołując auth.test na każdym tokenie. Runtime rozróżnia sterownik i SUT według identyfikatora użytkownika; ponowne użycie jednej aplikacji dla obu spowoduje natychmiastową porażkę mention-gating.
3. Utwórz kanał
W obszarze roboczym QA utwórz kanał (np. #openclaw-qa) i zaproś oba boty z wnętrza kanału:
/invite @OpenClaw QA Driver
/invite @OpenClaw QA SUT
Skopiuj identyfikator Cxxxxxxxxxx z channel info → About → Channel ID - staje się on channelId. Kanał publiczny działa; jeśli użyjesz kanału prywatnego, obie aplikacje już mają groups:history, więc odczyty historii przez harness nadal się powiodą.
4. Zarejestruj dane uwierzytelniające
Dwie opcje. Użyj zmiennych środowiskowych do debugowania na jednej maszynie (ustaw cztery zmienne OPENCLAW_QA_SLACK_* i przekaż --credential-source env) albo zasiej współdzieloną pulę Convex, aby CI i inni maintainerzy mogli je dzierżawić.
Dla puli Convex zapisz cztery pola do pliku JSON:
{
"channelId": "Cxxxxxxxxxx",
"driverBotToken": "xoxb-...",
"sutBotToken": "xoxb-...",
"sutAppToken": "xapp-..."
}
Po wyeksportowaniu OPENCLAW_QA_CONVEX_SITE_URL i OPENCLAW_QA_CONVEX_SECRET_MAINTAINER w swojej powłoce zarejestruj i sprawdź:
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
Oczekuj count: 1, status: "active", bez pola lease.
5. Sprawdź end to end
Uruchom ścieżkę lokalnie, aby potwierdzić, że oba boty mogą rozmawiać ze sobą przez brokera:
pnpm openclaw qa slack \
--credential-source convex \
--credential-role maintainer \
--output-dir .artifacts/qa-e2e/slack-local
Zielone uruchomienie kończy się znacznie poniżej 30 sekund, a slack-qa-report.md pokazuje zarówno slack-canary, jak i slack-mention-gating ze statusem pass. Jeśli ścieżka zawiesza się na około 90 sekund i kończy komunikatem Convex credential pool exhausted for kind "slack", pula jest pusta albo każdy wiersz jest wydzierżawiony - qa credentials list --kind slack --status all --json wskaże, która sytuacja zachodzi.
Pula danych uwierzytelniających Convex
Ścieżki Telegram, Discord i Slack mogą dzierżawić dane uwierzytelniające ze współdzielonej puli Convex zamiast odczytywać powyższe zmienne środowiskowe. Przekaż --credential-source convex (albo ustaw OPENCLAW_QA_CREDENTIAL_SOURCE=convex); QA Lab pozyskuje wyłączną dzierżawę, wysyła Heartbeat przez czas trwania uruchomienia i zwalnia ją przy zamykaniu. Typy puli to "telegram", "discord" i "slack".
Kształty payloadów walidowane przez brokera przy admin/add:
- Telegram (
kind: "telegram"):{ groupId: string, driverToken: string, sutToken: string }-groupIdmusi być liczbowym ciągiem identyfikatora czatu. - Discord (
kind: "discord"):{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }. - Slack (
kind: "slack"):{ channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string }-channelIdmusi pasować do^[A-Z][A-Z0-9]+$(identyfikator Slack taki jakCxxxxxxxxxx). Zobacz Konfigurowanie obszaru roboczego Slack, aby poznać aprowizację aplikacji i zakresów.
Operacyjne zmienne środowiskowe i kontrakt endpointu brokera Convex znajdują się w Testowanie → Współdzielone dane uwierzytelniające Telegram przez Convex (nazwa sekcji poprzedza obsługę Discord; semantyka brokera jest identyczna dla obu typów).
Seedy oparte na repozytorium
Zasoby seedów znajdują się w qa/:
qa/scenarios/index.mdqa/scenarios/<theme>/*.md
Są one celowo przechowywane w git, aby plan QA był widoczny zarówno dla ludzi, jak i dla agenta.
qa-lab powinien pozostać generycznym runnerem Markdown. Każdy plik Markdown scenariusza jest źródłem prawdy dla jednego uruchomienia testu i powinien definiować:
- metadane scenariusza
- opcjonalne metadane kategorii, możliwości, ścieżki i ryzyka
- odwołania do dokumentacji i kodu
- opcjonalne wymagania dotyczące Pluginu
- opcjonalną poprawkę konfiguracji Gateway
- wykonywalny
qa-flow
Wielokrotnego użytku powierzchnia runtime, która obsługuje qa-flow, może pozostać generyczna i przekrojowa. Na przykład scenariusze Markdown mogą łączyć helpery po stronie transportu z helperami po stronie przeglądarki, które sterują osadzonym Control UI przez szew Gateway browser.request bez dodawania runnera dla szczególnego przypadku.
Pliki scenariuszy powinny być grupowane według możliwości produktu, a nie folderu drzewa źródłowego. Zachowuj stabilne identyfikatory scenariuszy przy przenoszeniu plików; używaj docsRefs i codeRefs do śledzenia implementacji.
Lista bazowa powinna pozostać wystarczająco szeroka, aby obejmować:
- czat DM i kanałowy
- zachowanie wątków
- cykl życia akcji wiadomości
- wywołania zwrotne Cron
- przywoływanie pamięci
- przełączanie modeli
- przekazywanie do subagenta
- czytanie repozytorium i dokumentacji
- jedno małe zadanie build, takie jak Lobster Invaders
Ścieżki mocków providerów
qa suite ma dwie lokalne ścieżki mocków providerów:
mock-openaito świadomy scenariuszy mock OpenClaw. Pozostaje domyślną deterministyczną ścieżką mocków dla QA opartego na repozytorium i bram parytetu.aimockuruchamia serwer providera oparty na AIMock do eksperymentalnego pokrycia protokołu, fixture, record/replay i chaos. Jest addytywny i nie zastępuje dyspozytora scenariuszymock-openai.
Implementacja ścieżek providerów znajduje się w extensions/qa-lab/src/providers/. Każdy provider posiada swoje wartości domyślne, uruchamianie serwera lokalnego, konfigurację modelu Gateway, potrzeby stagingu auth-profile oraz flagi możliwości live/mock. Kod współdzielonego zestawu i Gateway powinien przechodzić przez rejestr providerów zamiast rozgałęziać się po nazwach providerów.
Adaptery transportu
qa-lab odpowiada za ogólną warstwę transportu dla scenariuszy QA w Markdown. qa-channel jest pierwszym adapterem w tej warstwie, ale cel projektowy jest szerszy: przyszłe kanały rzeczywiste lub syntetyczne powinny wpinać się w ten sam runner pakietu zamiast dodawać transportowo specyficzny runner QA.
Na poziomie architektury podział wygląda tak:
qa-labodpowiada za ogólne wykonywanie scenariuszy, współbieżność workerów, zapisywanie artefaktów i raportowanie.- Adapter transportu odpowiada za konfigurację Gateway, gotowość, obserwację ruchu przychodzącego i wychodzącego, akcje transportu oraz znormalizowany stan transportu.
- Pliki scenariuszy Markdown w
qa/scenarios/definiują uruchomienie testu;qa-labudostępnia wielokrotnego użytku powierzchnię runtime, która je wykonuje.
Dodawanie kanału
Dodanie kanału do systemu QA opartego na Markdown wymaga dokładnie dwóch rzeczy:
- Adaptera transportu dla kanału.
- Pakietu scenariuszy, który sprawdza kontrakt kanału.
Nie dodawaj nowego głównego korzenia poleceń QA, gdy współdzielony host qa-lab może odpowiadać za przepływ.
qa-lab odpowiada za współdzieloną mechanikę hosta:
- korzeń poleceń
openclaw qa - uruchamianie i sprzątanie pakietu
- współbieżność workerów
- zapisywanie artefaktów
- generowanie raportów
- wykonywanie scenariuszy
- aliasy zgodności dla starszych scenariuszy
qa-channel
Pluginy runnerów odpowiadają za kontrakt transportu:
- sposób montowania
openclaw qa <runner>pod współdzielonym korzeniemqa - sposób konfiguracji Gateway dla tego transportu
- sposób sprawdzania gotowości
- sposób wstrzykiwania zdarzeń przychodzących
- sposób obserwowania wiadomości wychodzących
- sposób udostępniania transkryptów i znormalizowanego stanu transportu
- sposób wykonywania akcji opartych na transporcie
- sposób obsługi resetu lub sprzątania specyficznego dla transportu
Minimalny próg wdrożenia dla nowego kanału:
- Zachowaj
qa-labjako właściciela współdzielonego korzeniaqa. - Zaimplementuj runner transportu na współdzielonej warstwie hosta
qa-lab. - Trzymaj mechanikę specyficzną dla transportu wewnątrz Pluginu runnera albo harnessu kanału.
- Montuj runner jako
openclaw qa <runner>zamiast rejestrować konkurencyjne polecenie korzenia. Pluginy runnerów powinny deklarowaćqaRunnerswopenclaw.plugin.jsoni eksportować pasującą tablicęqaRunnerCliRegistrationszruntime-api.ts. Utrzymujruntime-api.tsjako lekkie; leniwe CLI i wykonywanie runnera powinny pozostać za oddzielnymi punktami wejścia. - Utwórz lub dostosuj scenariusze Markdown w tematycznych katalogach
qa/scenarios/. - Używaj ogólnych helperów scenariuszy dla nowych scenariuszy.
- Utrzymuj działanie istniejących aliasów zgodności, chyba że repo wykonuje zamierzoną migrację.
Reguła decyzyjna jest ścisła:
- Jeśli zachowanie można wyrazić raz w
qa-lab, umieść je wqa-lab. - Jeśli zachowanie zależy od jednego transportu kanału, trzymaj je w tym Pluginie runnera albo harnessie Pluginu.
- Jeśli scenariusz potrzebuje nowej możliwości, z której może korzystać więcej niż jeden kanał, dodaj ogólny helper zamiast gałęzi specyficznej dla kanału w
suite.ts. - Jeśli zachowanie ma sens tylko dla jednego transportu, utrzymaj scenariusz jako specyficzny dla transportu i jasno zaznacz to w kontrakcie scenariusza.
Nazwy helperów scenariuszy
Preferowane ogólne helpery dla nowych scenariuszy:
waitForTransportReadywaitForChannelReadyinjectInboundMessageinjectOutboundMessagewaitForTransportOutboundMessagewaitForChannelOutboundMessagewaitForNoTransportOutboundgetTransportSnapshotreadTransportMessagereadTransportTranscriptformatTransportTranscriptresetTransport
Aliasy zgodności pozostają dostępne dla istniejących scenariuszy - waitForQaChannelReady, waitForOutboundMessage, waitForNoOutbound, formatConversationTranscript, resetBus - ale nowe scenariusze powinny używać nazw ogólnych. Aliasy istnieją po to, aby uniknąć migracji typu flag-day, a nie jako docelowy model.
Raportowanie
qa-lab eksportuje raport protokołu w Markdown z obserwowanej osi czasu magistrali.
Raport powinien odpowiadać na pytania:
- Co zadziałało
- Co się nie powiodło
- Co pozostało zablokowane
- Jakie scenariusze uzupełniające warto dodać
Aby uzyskać inwentarz dostępnych scenariuszy - przydatny przy określaniu zakresu dalszych prac albo podłączaniu nowego transportu - uruchom pnpm openclaw qa coverage (dodaj --json, aby uzyskać dane wyjściowe czytelne maszynowo).
Do sprawdzania charakteru i stylu uruchom ten sam scenariusz na wielu żywych referencjach modeli i zapisz oceniony raport Markdown:
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
Polecenie uruchamia lokalne procesy potomne Gateway QA, a nie Docker. Scenariusze oceny charakteru
powinny ustawiać personę przez SOUL.md, a następnie wykonywać zwykłe tury użytkownika,
takie jak czat, pomoc w workspace i małe zadania na plikach. Model kandydujący nie powinien
być informowany, że jest oceniany. Polecenie zachowuje każdy pełny
transkrypt, zapisuje podstawowe statystyki uruchomienia, a następnie prosi modele sędziowskie w trybie szybkim z
rozumowaniem xhigh, tam gdzie jest obsługiwane, o uszeregowanie uruchomień według naturalności, vibe'u i humoru.
Użyj --blind-judge-models przy porównywaniu providerów: prompt sędziowski nadal otrzymuje
każdy transkrypt i status uruchomienia, ale referencje kandydatów są zastępowane neutralnymi
etykietami, takimi jak candidate-01; raport mapuje rankingi z powrotem na rzeczywiste referencje po
parsowaniu.
Uruchomienia kandydatów domyślnie używają high thinking, z medium dla GPT-5.5 i xhigh
dla starszych referencji ewaluacyjnych OpenAI, które je obsługują. Nadpisz konkretnego kandydata inline za pomocą
--model provider/model,thinking=<level>. --thinking <level> nadal ustawia
globalny fallback, a starsza forma --model-thinking <provider/model=level> jest
zachowana dla zgodności.
Referencje kandydatów OpenAI domyślnie używają trybu szybkiego, aby wykorzystywać przetwarzanie priorytetowe tam,
gdzie provider je obsługuje. Dodaj ,fast, ,no-fast albo ,fast=false inline, gdy
pojedynczy kandydat lub sędzia potrzebuje nadpisania. Przekaż --fast tylko wtedy, gdy chcesz
wymusić tryb szybki dla każdego modelu kandydującego. Czasy trwania kandydatów i sędziów są
zapisywane w raporcie do analizy benchmarków, ale prompty sędziowskie wyraźnie mówią,
aby nie klasyfikować według szybkości.
Uruchomienia modeli kandydatów i sędziów domyślnie używają współbieżności 16. Obniż
--concurrency albo --judge-concurrency, gdy limity providera albo obciążenie lokalnego Gateway
powodują, że uruchomienie jest zbyt zaszumione.
Gdy nie zostanie przekazany żaden kandydat --model, ocena charakteru domyślnie używa
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 i
google/gemini-3.1-pro-preview, gdy nie przekazano żadnego --model.
Gdy nie zostanie przekazany żaden --judge-model, domyślnymi sędziami są
openai/gpt-5.5,thinking=xhigh,fast oraz
anthropic/claude-opus-4-6,thinking=high.