Testing

테스트

OpenClaw에는 세 가지 Vitest 스위트(단위/통합, e2e, 라이브)와 소수의 Docker runner가 있습니다. 이 문서는 "테스트 방식" 가이드입니다.

  • 각 스위트가 다루는 범위와 의도적으로 다루지 않는 범위.
  • 일반적인 워크플로(로컬, 푸시 전, 디버깅)에 실행할 명령.
  • 라이브 테스트가 자격 증명을 찾고 모델/공급자를 선택하는 방식.
  • 실제 모델/공급자 문제에 대한 회귀 테스트를 추가하는 방식.

빠른 시작

대부분의 경우:

  • 전체 게이트(푸시 전 예상): pnpm build && pnpm check && pnpm check:test-types && pnpm test
  • 여유 있는 머신에서 더 빠른 로컬 전체 스위트 실행: pnpm test:max
  • 직접 Vitest watch 루프: pnpm test:watch
  • 이제 직접 파일 대상 지정은 extension/channel 경로도 라우팅합니다: pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts
  • 단일 실패를 반복 수정 중이라면 먼저 대상 지정 실행을 선호하세요.
  • Docker 기반 QA 사이트: pnpm qa:lab:up
  • Linux VM 기반 QA lane: pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline

테스트를 수정했거나 추가 확신이 필요할 때:

  • 커버리지 게이트: pnpm test:coverage
  • E2E 스위트: pnpm test:e2e

실제 공급자/모델을 디버깅할 때(실제 자격 증명 필요):

  • 라이브 스위트(모델 + Gateway 도구/이미지 probe): pnpm test:live
  • 하나의 라이브 파일을 조용히 대상으로 지정: pnpm test:live -- src/agents/models.profiles.live.test.ts
  • 런타임 성능 보고서: 실제 openai/gpt-5.4 에이전트 턴에는 live_gpt54=true로, Kova CPU/heap/trace 아티팩트에는 deep_profile=trueOpenClaw Performance를 dispatch합니다. CLAWGRIT_REPORTS_TOKEN이 구성되어 있으면 일일 예약 실행이 mock-provider, deep-profile, GPT 5.4 lane 아티팩트를 openclaw/clawgrit-reports에 게시합니다. mock-provider 보고서에는 소스 수준 Gateway 부팅, 메모리, Plugin 압력, 반복 fake-model hello-loop, CLI 시작 시간도 포함됩니다.
  • Docker 라이브 모델 sweep: pnpm test:docker:live-models
    • 선택된 각 모델은 이제 텍스트 턴과 작은 file-read 스타일 probe를 실행합니다. 메타데이터가 image 입력을 알리는 모델은 작은 이미지 턴도 실행합니다. 공급자 실패를 격리할 때는 OPENCLAW_LIVE_MODEL_FILE_PROBE=0 또는 OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0으로 추가 probe를 비활성화하세요.
    • CI 커버리지: 일일 OpenClaw Scheduled Live And E2E Checks와 수동 OpenClaw Release Checks는 모두 include_live_suites: true로 재사용 가능한 라이브/E2E 워크플로를 호출하며, 여기에는 공급자별로 sharding된 별도의 Docker 라이브 모델 matrix 작업이 포함됩니다.
    • 집중 CI 재실행의 경우 include_live_suites: truelive_models_only: trueOpenClaw Live And E2E Checks (Reusable)를 dispatch하세요.
    • 새 high-signal 공급자 secret은 scripts/ci-hydrate-live-auth.sh.github/workflows/openclaw-live-and-e2e-checks-reusable.yml, 그리고 그 scheduled/release 호출자에 추가하세요.
  • 네이티브 Codex bound-chat smoke: pnpm test:docker:live-codex-bind
    • Codex app-server 경로에 대해 Docker 라이브 lane을 실행하고, /codex bind로 합성 Slack DM을 바인딩하며, /codex fast/codex permissions를 실행한 뒤, 일반 답장과 이미지 첨부 파일이 ACP 대신 네이티브 Plugin 바인딩을 통해 라우팅되는지 확인합니다.
  • Codex app-server harness smoke: pnpm test:docker:live-codex-harness
    • Plugin 소유 Codex app-server harness를 통해 Gateway 에이전트 턴을 실행하고, /codex status/codex models를 확인하며, 기본적으로 이미지, cron MCP, sub-agent, Guardian probe를 실행합니다. 다른 Codex app-server 실패를 격리할 때는 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0으로 sub-agent probe를 비활성화하세요. 집중 sub-agent 확인의 경우 다른 probe를 비활성화하세요: OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness. OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0이 설정되어 있지 않으면 sub-agent probe 후 종료됩니다.
  • Crestodian rescue 명령 smoke: pnpm test:live:crestodian-rescue-channel
    • 메시지 채널 rescue 명령 표면에 대한 옵트인 이중 확인입니다. /crestodian status를 실행하고, 영구 모델 변경을 큐에 넣고, /crestodian yes에 답장하며, audit/config 쓰기 경로를 확인합니다.
  • Crestodian planner Docker smoke: pnpm test:docker:crestodian-planner
    • PATH에 가짜 Claude CLI가 있는 configless 컨테이너에서 Crestodian을 실행하고, fuzzy planner fallback이 감사된 typed config 쓰기로 변환되는지 확인합니다.
  • Crestodian first-run Docker smoke: pnpm test:docker:crestodian-first-run
    • 빈 OpenClaw state 디렉터리에서 시작하고, bare openclaw를 Crestodian으로 라우팅하며, setup/model/agent/Discord Plugin + SecretRef 쓰기를 적용하고, config를 검증하며, audit entry를 확인합니다. 동일한 Ring 0 설정 경로는 QA Lab에서도 pnpm openclaw qa suite --scenario crestodian-ring-zero-setup으로 다룹니다.
  • Moonshot/Kimi cost smoke: MOONSHOT_API_KEY가 설정된 상태에서 openclaw models list --provider moonshot --json을 실행한 다음, moonshot/kimi-k2.6에 대해 격리된 openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json을 실행합니다. JSON이 Moonshot/K2.6을 보고하고 assistant transcript가 정규화된 usage.cost를 저장하는지 확인합니다.

QA 전용 runner

QA-lab의 현실성이 필요할 때 이 명령들은 메인 테스트 스위트 옆에 위치합니다.

CI는 전용 워크플로에서 QA Lab을 실행합니다. Agentic parity는 독립형 PR 워크플로가 아니라 QA-Lab - All Lanes와 릴리스 검증 아래에 중첩되어 있습니다. 광범위한 검증은 rerun_group=qa-parity 또는 release-checks QA 그룹과 함께 Full Release Validation을 사용해야 합니다. 안정/기본 릴리스 체크는 포괄적인 라이브/Docker soak를 run_release_soak=true 뒤에 유지하며, full 프로필은 soak를 강제로 켭니다. QA-Lab - All Lanesmain에서 야간 실행되고 수동 dispatch에서 mock parity lane, live Matrix lane, Convex 관리 라이브 Telegram lane, Convex 관리 라이브 Discord lane을 병렬 작업으로 실행합니다. 예약 QA와 릴리스 체크는 Matrix --profile fast를 명시적으로 전달하는 반면, Matrix CLI와 수동 워크플로 입력 기본값은 all로 유지됩니다. 수동 dispatch는 alltransport, media, e2ee-smoke, e2ee-deep, e2ee-cli 작업으로 sharding할 수 있습니다. OpenClaw Release Checks는 릴리스 승인 전에 parity와 빠른 Matrix 및 Telegram lane을 실행하며, 릴리스 전송 체크에는 mock-openai/gpt-5.5를 사용해 결정성을 유지하고 일반 공급자 Plugin 시작을 피합니다. 이러한 라이브 전송 Gateway는 메모리 검색을 비활성화합니다. 메모리 동작은 QA parity 스위트에서 계속 다룹니다.

전체 릴리스 라이브 미디어 shard는 이미 ffmpegffprobe가 포함된 ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04를 사용합니다. Docker 라이브 모델/backend shard는 선택된 커밋마다 한 번 빌드되는 공유 ghcr.io/openclaw/openclaw-live-test:<sha> 이미지를 사용한 다음, 각 shard 내부에서 다시 빌드하는 대신 OPENCLAW_SKIP_DOCKER_BUILD=1로 pull합니다.

  • pnpm openclaw qa suite
    • 호스트에서 repo 기반 QA 시나리오를 직접 실행합니다.
    • 기본적으로 격리된 gateway 워커를 사용해 선택한 여러 시나리오를 병렬로 실행합니다. qa-channel은 기본 동시성이 4입니다(선택한 시나리오 수에 따라 제한됨). 워커 수를 조정하려면 --concurrency <count>를 사용하고, 이전 직렬 레인에는 --concurrency 1을 사용하세요.
    • 시나리오가 하나라도 실패하면 0이 아닌 코드로 종료합니다. 실패 종료 코드 없이 아티팩트를 원할 때는 --allow-failures를 사용하세요.
    • provider 모드 live-frontier, mock-openai, aimock를 지원합니다. aimock는 시나리오 인식 mock-openai 레인을 대체하지 않고 실험적 fixture 및 protocol mock 커버리지를 위해 로컬 AIMock 기반 provider 서버를 시작합니다.
  • pnpm test:plugins:kitchen-sink-live
    • QA Lab을 통해 live OpenAI Kitchen Sink Plugin gauntlet을 실행합니다. 외부 Kitchen Sink 패키지를 설치하고, Plugin SDK surface inventory를 검증하며, /healthz/readyz를 탐색하고, gateway CPU/RSS 증거를 기록하며, live OpenAI turn을 실행하고, 적대적 진단을 확인합니다. OPENAI_API_KEY 같은 live OpenAI 인증이 필요합니다. hydration된 Testbox 세션에서는 openclaw-testbox-env helper가 있으면 Testbox live-auth profile을 자동으로 source합니다.
  • pnpm test:gateway:cpu-scenarios
    • gateway startup bench와 작은 mock QA Lab 시나리오 팩(channel-chat-baseline, memory-failure-fallback, gateway-restart-inflight-run)을 실행하고, 결합된 CPU 관찰 요약을 .artifacts/gateway-cpu-scenarios/ 아래에 작성합니다.
    • 기본적으로 지속적인 hot CPU 관찰만 flag 처리합니다(--cpu-core-warn--hot-wall-warn-ms). 따라서 짧은 startup burst는 몇 분 동안 이어지는 gateway peg 회귀처럼 보이지 않고 metric으로 기록됩니다.
    • 빌드된 dist 아티팩트를 사용합니다. checkout에 최신 runtime output이 아직 없으면 먼저 build를 실행하세요.
  • pnpm openclaw qa suite --runner multipass
    • 동일한 QA suite를 폐기 가능한 Multipass Linux VM 내부에서 실행합니다.
    • 호스트의 qa suite와 동일한 시나리오 선택 동작을 유지합니다.
    • qa suite와 동일한 provider/model 선택 flag를 재사용합니다.
    • live run은 guest에 실용적인 지원 QA 인증 input을 전달합니다: env 기반 provider key, QA live provider config path, 그리고 존재하는 경우 CODEX_HOME.
    • output dir은 guest가 mounted workspace를 통해 다시 쓸 수 있도록 repo root 아래에 있어야 합니다.
    • 일반 QA report 및 summary와 Multipass log를 .artifacts/qa-e2e/... 아래에 작성합니다.
  • pnpm qa:lab:up
    • operator 스타일 QA 작업을 위해 Docker 기반 QA site를 시작합니다.
  • pnpm test:docker:npm-onboard-channel-agent
    • 현재 checkout에서 npm tarball을 build하고, Docker에 전역 설치하며, non-interactive OpenAI API-key onboarding을 실행하고, 기본적으로 Telegram을 구성하며, 패키지된 Plugin runtime이 startup dependency repair 없이 load되는지 검증하고, doctor를 실행한 뒤 mocked OpenAI endpoint를 대상으로 로컬 agent turn 하나를 실행합니다.
    • Discord로 동일한 packaged-install 레인을 실행하려면 OPENCLAW_NPM_ONBOARD_CHANNEL=discord를 사용하세요.
  • pnpm test:docker:session-runtime-context
    • embedded runtime context transcript에 대한 deterministic built-app Docker smoke를 실행합니다. 숨겨진 OpenClaw runtime context가 보이는 user turn으로 누출되지 않고 non-display custom message로 persisted되는지 검증한 다음, 영향을 받는 깨진 session JSONL을 seed하고 openclaw doctor --fix가 backup과 함께 active branch로 다시 쓰는지 검증합니다.
  • pnpm test:docker:npm-telegram-live
    • Docker에 OpenClaw 패키지 candidate를 설치하고, installed-package onboarding을 실행하며, 설치된 CLI를 통해 Telegram을 구성한 다음, 해당 설치 패키지를 SUT Gateway로 사용해 live Telegram QA 레인을 재사용합니다.
    • 기본값은 OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta입니다. registry에서 설치하는 대신 해결된 로컬 tarball을 테스트하려면 OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgz 또는 OPENCLAW_CURRENT_PACKAGE_TGZ를 설정하세요.
    • pnpm openclaw qa telegram과 동일한 Telegram env credential 또는 Convex credential source를 사용합니다. CI/release automation에서는 OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convexOPENCLAW_QA_CONVEX_SITE_URL 및 role secret을 설정하세요. OPENCLAW_QA_CONVEX_SITE_URL과 Convex role secret이 CI에 있으면 Docker wrapper가 Convex를 자동으로 선택합니다.
    • wrapper는 Docker build/install 작업 전에 host에서 Telegram 또는 Convex credential env를 검증합니다. pre-credential setup을 의도적으로 debug할 때만 OPENCLAW_NPM_TELEGRAM_SKIP_CREDENTIAL_PREFLIGHT=1을 설정하세요.
    • OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer는 이 레인에 한해서만 공유 OPENCLAW_QA_CREDENTIAL_ROLE을 override합니다.
    • GitHub Actions는 이 레인을 수동 maintainer workflow NPM Telegram Beta E2E로 노출합니다. merge 시 실행되지 않습니다. workflow는 qa-live-shared environment와 Convex CI credential lease를 사용합니다.
  • GitHub Actions는 하나의 candidate package에 대한 side-run product proof용 Package Acceptance도 노출합니다. trusted ref, published npm spec, SHA-256이 포함된 HTTPS tarball URL, 또는 다른 run의 tarball artifact를 허용하고, 정규화된 openclaw-current.tgzpackage-under-test로 upload한 다음, smoke, package, product, full 또는 custom lane profile로 기존 Docker E2E scheduler를 실행합니다. 동일한 package-under-test artifact를 대상으로 Telegram QA workflow를 실행하려면 telegram_mode=mock-openai 또는 live-frontier를 설정하세요.
    • 최신 beta product proof:
gh workflow run package-acceptance.yml --ref main \
  -f source=npm \
  -f package_spec=openclaw@beta \
  -f suite_profile=product \
  -f telegram_mode=mock-openai
  • 정확한 tarball URL proof에는 digest가 필요합니다:
gh workflow run package-acceptance.yml --ref main \
  -f source=url \
  -f package_url=https://registry.npmjs.org/openclaw/-/openclaw-VERSION.tgz \
  -f package_sha256=<sha256> \
  -f suite_profile=package
  • Artifact proof는 다른 Actions run에서 tarball artifact를 download합니다:
gh workflow run package-acceptance.yml --ref main \
  -f source=artifact \
  -f artifact_run_id=<run-id> \
  -f artifact_name=<artifact-name> \
  -f suite_profile=smoke
  • pnpm test:docker:plugins

    • 현재 OpenClaw build를 Docker에서 pack 및 install하고, OpenAI가 구성된 상태로 Gateway를 시작한 다음, config edit를 통해 bundled channel/Plugin을 enable합니다.
    • setup discovery가 구성되지 않은 downloadable Plugin을 absent 상태로 두는지, 처음 구성된 doctor repair가 누락된 각 downloadable Plugin을 명시적으로 설치하는지, 두 번째 restart에서 hidden dependency repair가 실행되지 않는지 검증합니다.
    • 또한 알려진 이전 npm baseline을 설치하고, openclaw update --tag <candidate>를 실행하기 전에 Telegram을 enable하며, candidate의 post-update doctor가 harness-side postinstall repair 없이 legacy Plugin dependency debris를 정리하는지 검증합니다.
  • pnpm test:parallels:npm-update

    • Parallels guest 전반에서 native packaged-install update smoke를 실행합니다. 선택된 각 platform은 먼저 요청된 baseline package를 설치한 다음, 동일한 guest에서 설치된 openclaw update command를 실행하고 설치된 version, update status, gateway readiness, 그리고 로컬 agent turn 하나를 검증합니다.

    • 하나의 guest를 반복 작업할 때는 --platform macos, --platform windows, 또는 --platform linux를 사용하세요. summary artifact path와 lane별 status에는 --json을 사용하세요.

    • OpenAI 레인은 기본적으로 live agent-turn proof에 openai/gpt-5.5를 사용합니다. 다른 OpenAI model을 의도적으로 검증할 때는 --model <provider/model>을 전달하거나 OPENCLAW_PARALLELS_OPENAI_MODEL을 설정하세요.

    • Parallels transport stall이 남은 testing window를 소모하지 않도록 긴 local run은 host timeout으로 감싸세요:

      timeout --foreground 150m pnpm test:parallels:npm-update -- --json
      timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json
      
    • script는 nested lane log를 /tmp/openclaw-parallels-npm-update.* 아래에 작성합니다. outer wrapper가 멈췄다고 가정하기 전에 windows-update.log, macos-update.log, 또는 linux-update.log를 검사하세요.

    • Windows update는 cold guest에서 post-update doctor 및 package update 작업에 10~15분이 걸릴 수 있습니다. nested npm debug log가 진행 중이면 정상입니다.

    • 이 aggregate wrapper를 개별 Parallels macOS, Windows 또는 Linux smoke lane과 병렬로 실행하지 마세요. 이들은 VM state를 공유하며 snapshot restore, package serving 또는 guest gateway state에서 충돌할 수 있습니다.

    • post-update proof는 일반 bundled Plugin surface를 실행합니다. speech, image generation, media understanding 같은 capability facade는 agent turn 자체가 간단한 text response만 확인하더라도 bundled runtime API를 통해 load되기 때문입니다.

  • pnpm openclaw qa aimock

    • direct protocol smoke testing을 위해 로컬 AIMock provider server만 시작합니다.
  • pnpm openclaw qa matrix

    • 폐기 가능한 Docker 기반 Tuwunel homeserver를 대상으로 Matrix live QA 레인을 실행합니다. source-checkout 전용입니다. packaged install에는 qa-lab이 포함되지 않습니다.
    • 전체 CLI, profile/scenario catalog, env var, artifact layout: Matrix QA.
  • pnpm openclaw qa telegram

    • env의 driver 및 SUT bot token을 사용해 실제 private group을 대상으로 Telegram live QA 레인을 실행합니다.
    • OPENCLAW_QA_TELEGRAM_GROUP_ID, OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN, OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN이 필요합니다. group id는 숫자 Telegram chat id여야 합니다.
    • 공유 pooled credential을 위해 --credential-source convex를 지원합니다. 기본적으로 env mode를 사용하거나, pooled lease를 사용하도록 opt in하려면 OPENCLAW_QA_CREDENTIAL_SOURCE=convex를 설정하세요.
    • 시나리오가 하나라도 실패하면 0이 아닌 코드로 종료합니다. 실패 종료 코드 없이 아티팩트를 원할 때는 --allow-failures를 사용하세요.
    • 동일한 private group에 서로 다른 bot 두 개가 필요하며, SUT bot은 Telegram username을 노출해야 합니다.
    • 안정적인 bot-to-bot 관찰을 위해 두 bot 모두 @BotFather에서 Bot-to-Bot Communication Mode를 enable하고 driver bot이 group bot traffic을 관찰할 수 있도록 하세요.
    • Telegram QA report, summary, observed-messages artifact를 .artifacts/qa-e2e/... 아래에 작성합니다. reply 시나리오에는 driver send request부터 관찰된 SUT reply까지의 RTT가 포함됩니다.

Live transport lane은 새 transport가 drift되지 않도록 하나의 표준 contract를 공유합니다. lane별 coverage matrix는 QA overview → Live transport coverage에 있습니다. qa-channel은 광범위한 synthetic suite이며 해당 matrix의 일부가 아닙니다.

Convex를 통한 공유 Telegram credential (v1)

openclaw qa telegram에 대해 --credential-source convex(또는 OPENCLAW_QA_CREDENTIAL_SOURCE=convex)가 enable되면 QA lab은 Convex 기반 pool에서 exclusive lease를 획득하고, lane이 실행되는 동안 해당 lease에 Heartbeat를 보내며, shutdown 시 lease를 release합니다.

참조 Convex project scaffold:

  • qa/convex-credential-broker/

필수 env var:

  • OPENCLAW_QA_CONVEX_SITE_URL(예: https://your-deployment.convex.site)
  • 선택한 role에 대한 secret 하나:
    • maintainerOPENCLAW_QA_CONVEX_SECRET_MAINTAINER
    • ciOPENCLAW_QA_CONVEX_SECRET_CI
  • Credential role selection:
    • CLI: --credential-role maintainer|ci
    • Env default: OPENCLAW_QA_CREDENTIAL_ROLE(CI에서는 기본값 ci, 그 외에는 maintainer)

선택 env var:

  • OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS(기본값 1200000)
  • OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS(기본값 30000)
  • OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS(기본값 90000)
  • OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS(기본값 15000)
  • OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX(기본값 /qa-credentials/v1)
  • OPENCLAW_QA_CREDENTIAL_OWNER_ID(선택적 trace id)
  • OPENCLAW_QA_ALLOW_INSECURE_HTTP=1은 local-only development를 위해 loopback http:// Convex URL을 허용합니다.

OPENCLAW_QA_CONVEX_SITE_URL은 일반 운영에서 https://를 사용해야 합니다.

Maintainer 관리자 명령(pool add/remove/list)에는 OPENCLAW_QA_CONVEX_SECRET_MAINTAINER가 정확히 필요합니다.

Maintainer용 CLI 도우미:

pnpm openclaw qa credentials doctor
pnpm openclaw qa credentials add --kind telegram --payload-file qa/telegram-credential.json
pnpm openclaw qa credentials list --kind telegram
pnpm openclaw qa credentials remove --credential-id <credential-id>

라이브 실행 전에 doctor를 사용해 비밀 값을 출력하지 않고 Convex 사이트 URL, 브로커 비밀, 엔드포인트 접두사, HTTP 타임아웃, admin/list 도달 가능성을 확인하세요. 스크립트와 CI 유틸리티에서 기계가 읽을 수 있는 출력을 원하면 --json을 사용하세요.

기본 엔드포인트 계약(OPENCLAW_QA_CONVEX_SITE_URL + /qa-credentials/v1):

  • POST /acquire
    • 요청: { kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }
    • 성공: { status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }
    • 고갈/재시도 가능: { status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }
  • POST /heartbeat
    • 요청: { kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }
    • 성공: { status: "ok" }(또는 빈 2xx)
  • POST /release
    • 요청: { kind, ownerId, actorRole, credentialId, leaseToken }
    • 성공: { status: "ok" }(또는 빈 2xx)
  • POST /admin/add(maintainer 비밀 전용)
    • 요청: { kind, actorId, payload, note?, status? }
    • 성공: { status: "ok", credential }
  • POST /admin/remove(maintainer 비밀 전용)
    • 요청: { credentialId, actorId }
    • 성공: { status: "ok", changed, credential }
    • 활성 lease 가드: { status: "error", code: "LEASE_ACTIVE", ... }
  • POST /admin/list(maintainer 비밀 전용)
    • 요청: { kind?, status?, includePayload?, limit? }
    • 성공: { status: "ok", credentials, count }

Telegram kind의 payload 형태:

  • { groupId: string, driverToken: string, sutToken: string }
  • groupId는 숫자로 된 Telegram 채팅 ID 문자열이어야 합니다.
  • admin/addkind: "telegram"에 대해 이 형태를 검증하고 잘못된 payload를 거부합니다.

QA에 채널 추가하기

새 채널 어댑터의 아키텍처와 시나리오 도우미 이름은 QA 개요 → 채널 추가하기에 있습니다. 최소 기준: 공유 qa-lab 호스트 seam에서 전송 runner를 구현하고, Plugin manifest에 qaRunners를 선언하며, openclaw qa <runner>로 마운트하고, qa/scenarios/ 아래에 시나리오를 작성합니다.

테스트 스위트(어디에서 무엇이 실행되는가)

스위트는 "현실성 증가"(그리고 flakiness/비용 증가)로 생각하세요.

단위 / 통합(기본값)

  • 명령: pnpm test
  • 구성: 대상이 지정되지 않은 실행은 vitest.full-*.config.ts shard 집합을 사용하며 병렬 스케줄링을 위해 다중 프로젝트 shard를 프로젝트별 구성으로 확장할 수 있습니다.
  • 파일: src/**/*.test.ts, packages/**/*.test.ts, test/**/*.test.ts 아래의 core/unit 인벤토리; UI 단위 테스트는 전용 unit-ui shard에서 실행됩니다.
  • 범위:
    • 순수 단위 테스트
    • 프로세스 내 통합 테스트(Gateway 인증, 라우팅, 도구, 파싱, 구성)
    • 알려진 버그에 대한 결정적 회귀 테스트
  • 기대 사항:
    • CI에서 실행됩니다.
    • 실제 키가 필요 없습니다.
    • 빠르고 안정적이어야 합니다.
    • resolver 및 공개 표면 loader 테스트는 실제 번들 Plugin 소스 API가 아니라 생성된 작은 Plugin fixture로 넓은 api.jsruntime-api.js fallback 동작을 증명해야 합니다. 실제 Plugin API 로드는 Plugin 소유 계약/통합 스위트에 속합니다.
프로젝트, shard, 범위 지정 lane
  • 대상이 지정되지 않은 pnpm test는 하나의 거대한 네이티브 root-project 프로세스 대신 열두 개의 더 작은 shard 구성(core-unit-fast, core-unit-src, core-unit-security, core-unit-ui, core-unit-support, core-support-boundary, core-contracts, core-bundled, core-runtime, agentic, auto-reply, extensions)을 실행합니다. 이는 부하가 있는 머신에서 최대 RSS를 줄이고 auto-reply/extension 작업이 관련 없는 스위트를 굶기지 않도록 합니다.
  • pnpm test --watch는 여전히 네이티브 루트 vitest.config.ts 프로젝트 그래프를 사용합니다. 다중 shard watch loop는 실용적이지 않기 때문입니다.
  • pnpm test, pnpm test:watch, pnpm test:perf:imports는 명시적 파일/디렉터리 대상을 먼저 범위 지정 lane을 통해 라우팅하므로 pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts는 전체 루트 프로젝트 시작 비용을 치르지 않습니다.
  • pnpm test:changed는 변경된 git 경로를 기본적으로 저렴한 범위 지정 lane으로 확장합니다. 직접 테스트 편집, sibling *.test.ts 파일, 명시적 소스 매핑, 로컬 import-graph 의존 항목이 포함됩니다. 구성/setup/package 편집은 명시적으로 OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed를 사용하지 않는 한 테스트를 넓게 실행하지 않습니다.
  • pnpm check:changed는 좁은 작업을 위한 일반적인 스마트 로컬 check gate입니다. diff를 core, core tests, extensions, extension tests, apps, docs, release metadata, live Docker tooling, tooling으로 분류한 다음 일치하는 typecheck, lint, guard 명령을 실행합니다. Vitest 테스트는 실행하지 않습니다. 테스트 증명이 필요하면 pnpm test:changed 또는 명시적 pnpm test <target>을 호출하세요. 릴리스 메타데이터 전용 버전 bump는 대상 지정 버전/config/root-dependency check를 실행하며, 최상위 버전 필드 밖의 package 변경을 거부하는 guard가 있습니다.
  • Live Docker ACP harness 편집은 집중 check를 실행합니다. live Docker 인증 스크립트의 shell 문법과 live Docker scheduler dry-run입니다. package.json 변경은 diff가 scripts["test:docker:live-*"]로 제한된 경우에만 포함됩니다. dependency, export, version 및 기타 package-surface 편집은 여전히 더 넓은 guard를 사용합니다.
  • agents, commands, plugins, auto-reply 도우미, plugin-sdk 및 유사한 순수 utility 영역의 import-light 단위 테스트는 unit-fast lane을 통해 라우팅되며, 이 lane은 test/setup-openclaw-runtime.ts를 건너뜁니다. 상태를 갖거나 런타임이 무거운 파일은 기존 lane에 남습니다.
  • 선택된 plugin-sdkcommands 도우미 소스 파일도 changed-mode 실행을 해당 가벼운 lane의 명시적 sibling 테스트에 매핑하므로, 도우미 편집은 해당 디렉터리의 전체 무거운 스위트를 다시 실행하지 않아도 됩니다.
  • auto-reply에는 최상위 core 도우미, 최상위 reply.* 통합 테스트, src/auto-reply/reply/** subtree를 위한 전용 bucket이 있습니다. CI는 reply subtree를 agent-runner, dispatch, commands/state-routing shard로 추가 분할하여 import가 무거운 하나의 bucket이 전체 Node tail을 독점하지 않도록 합니다.
  • 일반 PR/main CI는 extension batch sweep과 릴리스 전용 agentic-plugins shard를 의도적으로 건너뜁니다. Full Release Validation은 릴리스 후보에서 이러한 Plugin/extension-heavy 스위트를 위해 별도의 Plugin Prerelease child workflow를 dispatch합니다.
Embedded runner coverage
  • message-tool discovery 입력이나 compaction 런타임 컨텍스트를 변경할 때는 두 수준의 coverage를 모두 유지하세요.
  • 순수 라우팅 및 정규화 경계를 위한 집중 도우미 회귀 테스트를 추가하세요.
  • embedded runner 통합 스위트를 정상 상태로 유지하세요. src/agents/pi-embedded-runner/compact.hooks.test.ts, src/agents/pi-embedded-runner/run.overflow-compaction.test.ts, 그리고 src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts.
  • 이러한 스위트는 범위 지정 ID와 compaction 동작이 실제 run.ts / compact.ts 경로를 통해 계속 흐르는지 검증합니다. 도우미 전용 테스트는 이러한 통합 경로를 충분히 대체하지 못합니다.
Vitest pool 및 isolation 기본값
  • 기본 Vitest 구성은 threads가 기본값입니다.
  • 공유 Vitest 구성은 isolate: false를 고정하고 root projects, e2e, live configs 전체에서 non-isolated runner를 사용합니다.
  • 루트 UI lane은 jsdom setup과 optimizer를 유지하지만, 공유 non-isolated runner에서도 실행됩니다.
  • pnpm test shard는 공유 Vitest 구성에서 동일한 threads + isolate: false 기본값을 상속합니다.
  • scripts/run-vitest.mjs는 큰 로컬 실행 중 V8 compile churn을 줄이기 위해 기본적으로 Vitest child Node 프로세스에 --no-maglev를 추가합니다. stock V8 동작과 비교하려면 OPENCLAW_VITEST_ENABLE_MAGLEV=1을 설정하세요.
빠른 로컬 반복
  • pnpm changed:lanes는 diff가 어떤 아키텍처 lane을 트리거하는지 보여줍니다.
  • pre-commit hook은 formatting 전용입니다. 형식이 지정된 파일을 다시 stage하며 lint, typecheck 또는 tests는 실행하지 않습니다.
  • 스마트 로컬 check gate가 필요할 때는 handoff 또는 push 전에 pnpm check:changed를 명시적으로 실행하세요.
  • pnpm test:changed는 기본적으로 저렴한 범위 지정 lane을 통해 라우팅됩니다. agent가 harness, config, package 또는 contract 편집에 정말 더 넓은 Vitest coverage가 필요하다고 판단한 경우에만 OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed를 사용하세요.
  • pnpm test:maxpnpm test:changed:max는 동일한 라우팅 동작을 유지하되 더 높은 worker cap만 사용합니다.
  • 로컬 worker auto-scaling은 의도적으로 보수적이며 host load average가 이미 높을 때 물러나므로, 여러 동시 Vitest 실행이 기본적으로 덜 해롭게 동작합니다.
  • 기본 Vitest 구성은 projects/config files를 forceRerunTriggers로 표시하여 test wiring이 변경될 때 changed-mode rerun이 정확하게 유지되도록 합니다.
  • 구성은 지원되는 host에서 OPENCLAW_VITEST_FS_MODULE_CACHE를 활성화된 상태로 유지합니다. 직접 profiling을 위한 명시적 cache 위치 하나를 원하면 OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path를 설정하세요.
Perf debugging
  • pnpm test:perf:imports는 Vitest import-duration reporting과 import-breakdown output을 활성화합니다.
  • pnpm test:perf:imports:changed는 동일한 profiling view를 origin/main 이후 변경된 파일로 범위 지정합니다.
  • Shard timing data는 .artifacts/vitest-shard-timings.json에 기록됩니다. Whole-config 실행은 config path를 key로 사용합니다. include-pattern CI shard는 shard name을 덧붙여 filtered shard를 별도로 추적할 수 있게 합니다.
  • 하나의 hot test가 여전히 시작 import에 대부분의 시간을 쓰는 경우, 무거운 dependency를 좁은 로컬 *.runtime.ts seam 뒤에 두고, runtime helper를 단지 vi.mock(...)에 통과시키려고 deep-import하는 대신 해당 seam을 직접 mock하세요.
  • pnpm test:perf:changed:bench -- --ref <git-ref>는 해당 커밋된 diff에 대해 라우팅된 test:changed를 네이티브 root-project 경로와 비교하고 wall time과 macOS max RSS를 출력합니다.
  • pnpm test:perf:changed:bench -- --worktree는 변경된 파일 목록을 scripts/test-projects.mjs와 루트 Vitest config를 통해 라우팅하여 현재 dirty tree를 benchmark합니다.
  • pnpm test:perf:profile:main은 Vitest/Vite startup 및 transform overhead에 대한 main-thread CPU profile을 기록합니다.
  • pnpm test:perf:profile:runner는 file parallelism을 비활성화한 unit suite의 runner CPU+heap profile을 기록합니다.

안정성(Gateway)

  • 명령: pnpm test:stability:gateway
  • 구성: vitest.gateway.config.ts, worker 하나로 강제
  • 범위:
    • 기본적으로 diagnostics가 활성화된 실제 loopback Gateway를 시작합니다.
    • synthetic gateway message, memory, large-payload churn을 diagnostic event path를 통해 구동합니다.
    • Gateway WS RPC를 통해 diagnostics.stability를 쿼리합니다.
    • diagnostic stability bundle persistence 도우미를 다룹니다.
    • recorder가 bounded 상태를 유지하고, synthetic RSS sample이 pressure budget 아래에 머물며, session별 queue depth가 다시 0으로 drain되는지 assert합니다.
  • 기대 사항:
    • CI-safe이며 keyless입니다.
    • stability-regression follow-up을 위한 좁은 lane이며, 전체 Gateway 스위트를 대체하지 않습니다.

E2E(Gateway smoke)

  • 명령: pnpm test:e2e
  • 구성: vitest.e2e.config.ts
  • 파일: src/**/*.e2e.test.ts, test/**/*.e2e.test.ts, 그리고 extensions/ 아래의 번들 Plugin E2E 테스트
  • 런타임 기본값:
    • 저장소의 나머지 부분과 일치하도록 isolate: false와 함께 Vitest threads를 사용합니다.
    • 적응형 워커를 사용합니다(CI: 최대 2개, 로컬: 기본값 1개).
    • 콘솔 I/O 오버헤드를 줄이기 위해 기본적으로 무음 모드로 실행됩니다.
  • 유용한 재정의:
    • OPENCLAW_E2E_WORKERS=<n>으로 워커 수를 강제합니다(최대 16개).
    • OPENCLAW_E2E_VERBOSE=1로 자세한 콘솔 출력을 다시 활성화합니다.
  • 범위:
    • 다중 인스턴스 Gateway 엔드 투 엔드 동작
    • WebSocket/HTTP 표면, Node 페어링, 더 무거운 네트워킹
  • 기대 사항:
    • CI에서 실행됩니다(파이프라인에서 활성화된 경우).
    • 실제 키가 필요하지 않습니다.
    • 단위 테스트보다 움직이는 부분이 더 많습니다(더 느릴 수 있음).

E2E: OpenShell 백엔드 스모크

  • 명령: pnpm test:e2e:openshell
  • 파일: extensions/openshell/src/backend.e2e.test.ts
  • 범위:
    • Docker를 통해 호스트에서 격리된 OpenShell Gateway를 시작합니다.
    • 임시 로컬 Dockerfile에서 샌드박스를 생성합니다.
    • 실제 sandbox ssh-config + SSH exec을 통해 OpenClaw의 OpenShell 백엔드를 실행해 봅니다.
    • 샌드박스 fs 브리지를 통해 원격 표준 파일 시스템 동작을 검증합니다.
  • 기대 사항:
    • 옵트인 전용이며, 기본 pnpm test:e2e 실행에 포함되지 않습니다.
    • 로컬 openshell CLI와 작동 중인 Docker 데몬이 필요합니다.
    • 격리된 HOME / XDG_CONFIG_HOME을 사용한 다음 테스트 Gateway와 샌드박스를 삭제합니다.
  • 유용한 재정의:
    • 더 넓은 e2e 제품군을 수동으로 실행할 때 OPENCLAW_E2E_OPENSHELL=1로 테스트를 활성화합니다.
    • OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell로 기본값이 아닌 CLI 바이너리 또는 래퍼 스크립트를 가리킵니다.

라이브(실제 제공자 + 실제 모델)

  • 명령: pnpm test:live
  • 구성: vitest.live.config.ts
  • 파일: src/**/*.live.test.ts, test/**/*.live.test.ts, 그리고 extensions/ 아래의 번들 Plugin 라이브 테스트
  • 기본값: pnpm test:live활성화됨(OPENCLAW_LIVE_TEST=1 설정)
  • 범위:
    • "이 제공자/모델이 실제 자격 증명으로 오늘 실제로 작동하는가?"
    • 제공자 형식 변경, 도구 호출 특이점, 인증 문제, 속도 제한 동작 포착
  • 기대 사항:
    • 설계상 CI 안정적이지 않습니다(실제 네트워크, 실제 제공자 정책, 할당량, 장애).
    • 비용이 발생하거나 속도 제한을 사용합니다.
    • "모든 것" 대신 좁힌 하위 집합을 실행하는 것을 권장합니다.
  • 라이브 실행은 누락된 API 키를 가져오기 위해 ~/.profile을 소스로 로드합니다.
  • 기본적으로 라이브 실행은 여전히 HOME을 격리하고 구성/인증 자료를 임시 테스트 홈으로 복사하므로 단위 픽스처가 실제 ~/.openclaw를 변경할 수 없습니다.
  • 라이브 테스트가 실제 홈 디렉터리를 사용해야 하는 경우에만 OPENCLAW_LIVE_USE_REAL_HOME=1을 설정합니다.
  • 이제 pnpm test:live는 더 조용한 모드를 기본값으로 사용합니다. [live] ... 진행 출력은 유지하지만 추가 ~/.profile 알림을 억제하고 Gateway 부트스트랩 로그/Bonjour 잡음을 음소거합니다. 전체 시작 로그를 다시 보려면 OPENCLAW_LIVE_TEST_QUIET=0을 설정합니다.
  • API 키 로테이션(제공자별): 쉼표/세미콜론 형식의 *_API_KEYS 또는 *_API_KEY_1, *_API_KEY_2를 설정하거나(예: OPENAI_API_KEYS, ANTHROPIC_API_KEYS, GEMINI_API_KEYS) OPENCLAW_LIVE_*_KEY를 통해 라이브별 재정의를 설정합니다. 테스트는 속도 제한 응답에서 재시도합니다.
  • 진행/Heartbeat 출력:
    • 이제 라이브 제품군은 stderr로 진행 줄을 내보내므로 Vitest 콘솔 캡처가 조용한 경우에도 긴 제공자 호출이 눈에 보이게 활성 상태로 표시됩니다.
    • vitest.live.config.ts는 Vitest 콘솔 가로채기를 비활성화하여 라이브 실행 중 제공자/Gateway 진행 줄이 즉시 스트리밍되도록 합니다.
    • 직접 모델 Heartbeat는 OPENCLAW_LIVE_HEARTBEAT_MS로 조정합니다.
    • Gateway/프로브 Heartbeat는 OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS로 조정합니다.

어떤 제품군을 실행해야 하나요?

이 결정 표를 사용하세요.

  • 로직/테스트 편집: pnpm test를 실행합니다(많이 변경했다면 pnpm test:coverage도 실행).
  • Gateway 네트워킹 / WS 프로토콜 / 페어링 수정: pnpm test:e2e를 추가합니다.
  • "내 봇이 다운됨" / 제공자별 실패 / 도구 호출 디버깅: 좁힌 pnpm test:live를 실행합니다.

라이브(네트워크에 접속하는) 테스트

라이브 모델 매트릭스, CLI 백엔드 스모크, ACP 스모크, Codex 앱 서버 하네스, 모든 미디어 제공자 라이브 테스트(Deepgram, BytePlus, ComfyUI, 이미지, 음악, 비디오, 미디어 하네스)와 라이브 실행을 위한 자격 증명 처리에 대해서는 라이브 제품군 테스트를 참조하세요. 전용 업데이트 및 Plugin 검증 체크리스트는 업데이트 및 Plugin 테스트를 참조하세요.

Docker 러너(선택 사항인 "Linux에서 작동함" 확인)

이 Docker 러너는 두 버킷으로 나뉩니다.

  • 라이브 모델 러너: test:docker:live-modelstest:docker:live-gateway는 저장소 Docker 이미지 안에서 일치하는 프로필 키 라이브 파일(src/agents/models.profiles.live.test.tssrc/gateway/gateway-models.profiles.live.test.ts)만 실행하며, 로컬 구성 디렉터리와 워크스페이스를 마운트합니다(마운트된 경우 ~/.profile도 소스로 로드). 일치하는 로컬 진입점은 test:live:models-profilestest:live:gateway-profiles입니다.
  • Docker 라이브 러너는 전체 Docker 스윕을 실용적으로 유지하기 위해 기본적으로 더 작은 스모크 상한을 사용합니다. test:docker:live-models의 기본값은 OPENCLAW_LIVE_MAX_MODELS=12이고, test:docker:live-gateway의 기본값은 OPENCLAW_LIVE_GATEWAY_SMOKE=1, OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8, OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000, 그리고 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000입니다. 더 큰 완전 스캔을 명시적으로 원할 때 해당 env vars를 재정의하세요.
  • test:docker:alltest:docker:live-build를 통해 라이브 Docker 이미지를 한 번 빌드하고, scripts/package-openclaw-for-docker.mjs를 통해 OpenClaw를 npm tarball로 한 번 패킹한 다음, 두 개의 scripts/e2e/Dockerfile 이미지를 빌드/재사용합니다. 베어 이미지는 install/update/plugin-dependency 레인을 위한 Node/Git 러너일 뿐이며, 해당 레인은 사전 빌드된 tarball을 마운트합니다. 기능 이미지는 빌드된 앱 기능 레인을 위해 동일한 tarball을 /app에 설치합니다. Docker 레인 정의는 scripts/lib/docker-e2e-scenarios.mjs에 있으며, 플래너 로직은 scripts/lib/docker-e2e-plan.mjs에 있고, scripts/test-docker-all.mjs가 선택된 계획을 실행합니다. 집계는 가중 로컬 스케줄러를 사용합니다. OPENCLAW_DOCKER_ALL_PARALLELISM은 프로세스 슬롯을 제어하고, 리소스 상한은 무거운 라이브, npm-install, 다중 서비스 레인이 모두 한꺼번에 시작되지 않도록 합니다. 단일 레인이 활성 상한보다 무거운 경우에도 풀_empty 상태이면 스케줄러가 이를 시작할 수 있으며, 이후 용량이 다시 사용 가능해질 때까지 단독 실행을 유지합니다. 기본값은 10개 슬롯, OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9, OPENCLAW_DOCKER_ALL_NPM_LIMIT=10, OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7입니다. Docker 호스트에 더 많은 여유가 있을 때만 OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT 또는 OPENCLAW_DOCKER_ALL_DOCKER_LIMIT를 조정하세요. 러너는 기본적으로 Docker 사전 점검을 수행하고, 오래된 OpenClaw E2E 컨테이너를 제거하며, 30초마다 상태를 출력하고, 성공한 레인 타이밍을 .artifacts/docker-tests/lane-timings.json에 저장한 뒤 이후 실행에서 더 긴 레인을 먼저 시작하는 데 해당 타이밍을 사용합니다. 빌드하거나 Docker를 실행하지 않고 가중 레인 매니페스트를 출력하려면 OPENCLAW_DOCKER_ALL_DRY_RUN=1을 사용하고, 선택한 레인, 패키지/이미지 필요 사항, 자격 증명에 대한 CI 계획을 출력하려면 node scripts/test-docker-all.mjs --plan-json을 사용하세요.
  • Package Acceptance는 "이 설치 가능한 tarball이 제품으로 작동하는가?"를 확인하는 GitHub 네이티브 패키지 게이트입니다. source=npm, source=ref, source=url, 또는 source=artifact에서 후보 패키지 하나를 해석하고, 이를 package-under-test로 업로드한 다음, 선택한 ref를 다시 패킹하는 대신 해당 정확한 tarball에 대해 재사용 가능한 Docker E2E 레인을 실행합니다. 프로필은 범위 순서대로 smoke, package, product, full입니다. 패키지/업데이트/Plugin 계약, 게시된 업그레이드 생존자 매트릭스, 릴리스 기본값, 실패 분류에 대해서는 업데이트 및 Plugin 테스트를 참조하세요.
  • 빌드 및 릴리스 확인은 tsdown 이후 scripts/check-cli-bootstrap-imports.mjs를 실행합니다. 가드는 dist/entry.jsdist/cli/run-main.js에서 정적 빌드 그래프를 탐색하고, 명령 디스패치 전에 Commander, 프롬프트 UI, undici, 로깅 같은 패키지 의존성을 사전 디스패치 시작이 가져오면 실패합니다. 또한 번들된 Gateway 실행 청크를 예산 아래로 유지하고 알려진 콜드 Gateway 경로의 정적 가져오기를 거부합니다. 패키지된 CLI 스모크는 루트 도움말, 온보드 도움말, doctor 도움말, 상태, 구성 스키마, 모델 목록 명령도 다룹니다.
  • Package Acceptance 레거시 호환성은 2026.4.25(2026.4.25-beta.* 포함)로 제한됩니다. 해당 마감까지 하네스는 출시된 패키지 메타데이터 공백만 허용합니다. 생략된 비공개 QA 인벤토리 항목, 누락된 gateway install --wrapper, tarball 파생 git 픽스처의 누락된 패치 파일, 누락된 지속 update.channel, 레거시 Plugin 설치 기록 위치, 누락된 마켓플레이스 설치 기록 지속성, 그리고 plugins update 중 구성 메타데이터 마이그레이션입니다. 2026.4.25 이후 패키지에서는 이러한 경로가 엄격한 실패입니다.
  • 컨테이너 스모크 러너: test:docker:openwebui, test:docker:onboard, test:docker:npm-onboard-channel-agent, test:docker:update-channel-switch, test:docker:upgrade-survivor, test:docker:published-upgrade-survivor, test:docker:session-runtime-context, test:docker:agents-delete-shared-workspace, test:docker:gateway-network, test:docker:browser-cdp-snapshot, test:docker:mcp-channels, test:docker:pi-bundle-mcp-tools, test:docker:cron-mcp-cleanup, test:docker:plugins, test:docker:plugin-update, test:docker:plugin-lifecycle-matrix, 그리고 test:docker:config-reload는 하나 이상의 실제 컨테이너를 부팅하고 더 높은 수준의 통합 경로를 검증합니다.

라이브 모델 Docker 러너는 필요한 CLI 인증 홈만(또는 실행이 좁혀지지 않은 경우 지원되는 모든 홈을) 바인드 마운트한 다음, 실행 전에 컨테이너 홈으로 복사하여 외부 CLI OAuth가 호스트 인증 저장소를 변경하지 않고 토큰을 새로 고칠 수 있게 합니다:

  • 직접 모델: pnpm test:docker:live-models (스크립트: scripts/test-live-models-docker.sh)
  • ACP 바인드 스모크: pnpm test:docker:live-acp-bind (스크립트: scripts/test-live-acp-bind-docker.sh; 기본적으로 Claude, Codex, Gemini를 포함하며, Droid/OpenCode 엄격 커버리지는 pnpm test:docker:live-acp-bind:droidpnpm test:docker:live-acp-bind:opencode로 제공)
  • CLI 백엔드 스모크: pnpm test:docker:live-cli-backend (스크립트: scripts/test-live-cli-backend-docker.sh)
  • Codex 앱 서버 하네스 스모크: pnpm test:docker:live-codex-harness (스크립트: scripts/test-live-codex-harness-docker.sh)
  • Gateway + 개발 에이전트: pnpm test:docker:live-gateway (스크립트: scripts/test-live-gateway-models-docker.sh)
  • 관측성 스모크: pnpm qa:otel:smoke는 비공개 QA 소스 체크아웃 레인입니다. npm tarball은 QA Lab을 생략하므로 의도적으로 패키지 Docker 릴리스 레인에 포함되지 않습니다.
  • Open WebUI 라이브 스모크: pnpm test:docker:openwebui (스크립트: scripts/e2e/openwebui-docker.sh)
  • 온보딩 마법사(TTY, 전체 스캐폴딩): pnpm test:docker:onboard (스크립트: scripts/e2e/onboard-docker.sh)
  • Npm tarball 온보딩/채널/에이전트 스모크: pnpm test:docker:npm-onboard-channel-agent는 패킹된 OpenClaw tarball을 Docker에 전역 설치하고, env-ref 온보딩과 기본 Telegram을 통해 OpenAI를 구성하며, doctor를 실행하고, 모킹된 OpenAI 에이전트 턴을 한 번 실행합니다. 미리 빌드된 tarball을 재사용하려면 OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz를 사용하고, 호스트 재빌드를 건너뛰려면 OPENCLAW_NPM_ONBOARD_HOST_BUILD=0을 사용하거나, 채널을 전환하려면 OPENCLAW_NPM_ONBOARD_CHANNEL=discord 또는 OPENCLAW_NPM_ONBOARD_CHANNEL=slack을 사용하세요.
  • 업데이트 채널 전환 스모크: pnpm test:docker:update-channel-switch는 패킹된 OpenClaw tarball을 Docker에 전역 설치하고, 패키지 stable에서 git dev로 전환하며, 지속된 채널과 Plugin 업데이트 후 동작을 검증한 다음, 다시 패키지 stable로 전환하고 업데이트 상태를 확인합니다.
  • 업그레이드 생존자 스모크: pnpm test:docker:upgrade-survivor는 에이전트, 채널 구성, Plugin 허용 목록, 오래된 Plugin 의존성 상태, 기존 workspace/session 파일이 포함된 지저분한 이전 사용자 fixture 위에 패킹된 OpenClaw tarball을 설치합니다. 라이브 provider나 채널 키 없이 패키지 업데이트와 비대화형 doctor를 실행한 다음, loopback Gateway를 시작하고 구성/상태 보존과 시작/상태 예산을 확인합니다.
  • 게시된 업그레이드 생존자 스모크: pnpm test:docker:published-upgrade-survivor는 기본적으로 openclaw@latest를 설치하고, 현실적인 기존 사용자 파일을 시드하며, 구워진 명령 레시피로 해당 baseline을 구성하고, 결과 구성을 검증하며, 게시된 설치를 후보 tarball로 업데이트하고, 비대화형 doctor를 실행하고, .artifacts/upgrade-survivor/summary.json을 작성한 다음, loopback Gateway를 시작하고 구성된 intent, 상태 보존, 시작, /healthz, /readyz, RPC 상태 예산을 확인합니다. 하나의 baseline을 재정의하려면 OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC을 사용하고, 집계 스케줄러가 [email protected] [email protected] [email protected] 같은 정확한 로컬 baseline을 확장하도록 요청하려면 OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS를 사용하며, reported-issues 같은 이슈 형태 fixture를 확장하려면 OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS를 사용하세요. reported-issues 세트에는 외부 OpenClaw Plugin 설치 자동 복구를 위한 configured-plugin-installs가 포함됩니다. Package Acceptance는 이를 published_upgrade_survivor_baseline, published_upgrade_survivor_baselines, published_upgrade_survivor_scenarios로 노출하고, last-stable-4 또는 all-since-2026.4.23 같은 메타 baseline 토큰을 해석하며, Full Release Validation은 release-soak 패키지 게이트를 last-stable-4 2026.4.23 2026.5.2 2026.4.15reported-issues로 확장합니다.
  • 세션 런타임 컨텍스트 스모크: pnpm test:docker:session-runtime-context는 숨겨진 런타임 컨텍스트 transcript 지속성과 영향을 받은 중복 prompt-rewrite 브랜치의 doctor 복구를 검증합니다.
  • Bun 전역 설치 스모크: bash scripts/e2e/bun-global-install-smoke.sh는 현재 트리를 패킹하고, 격리된 home에서 bun install -g로 설치하며, openclaw infer image providers --json이 멈추지 않고 번들 이미지 provider를 반환하는지 검증합니다. 미리 빌드된 tarball을 재사용하려면 OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz를 사용하고, 호스트 빌드를 건너뛰려면 OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0을 사용하거나, 빌드된 Docker 이미지에서 dist/를 복사하려면 OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local을 사용하세요.
  • 설치 프로그램 Docker 스모크: bash scripts/test-install-sh-docker.sh는 root, update, direct-npm 컨테이너 전체에서 하나의 npm cache를 공유합니다. 업데이트 스모크는 후보 tarball로 업그레이드하기 전 stable baseline으로 기본 npm latest를 사용합니다. 로컬에서는 OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22로 재정의하거나, GitHub에서는 Install Smoke 워크플로의 update_baseline_version 입력으로 재정의하세요. 비-root 설치 프로그램 검사는 격리된 npm cache를 유지하여 root 소유 cache 항목이 사용자 로컬 설치 동작을 가리지 않도록 합니다. 로컬 재실행에서 root/update/direct-npm cache를 재사용하려면 OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache를 설정하세요.
  • Install Smoke CI는 OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1로 중복 direct-npm 전역 업데이트를 건너뜁니다. 직접 npm install -g 커버리지가 필요하면 해당 env 없이 로컬에서 스크립트를 실행하세요.
  • 에이전트 공유 workspace 삭제 CLI 스모크: pnpm test:docker:agents-delete-shared-workspace (스크립트: scripts/e2e/agents-delete-shared-workspace-docker.sh)는 기본적으로 루트 Dockerfile 이미지를 빌드하고, 격리된 컨테이너 home에 하나의 workspace가 있는 두 에이전트를 시드하며, agents delete --json을 실행하고, 유효한 JSON과 workspace 유지 동작을 검증합니다. install-smoke 이미지를 재사용하려면 OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1을 사용하세요.
  • Gateway 네트워킹(두 컨테이너, WS 인증 + health): pnpm test:docker:gateway-network (스크립트: scripts/e2e/gateway-network-docker.sh)
  • 브라우저 CDP 스냅샷 스모크: pnpm test:docker:browser-cdp-snapshot (스크립트: scripts/e2e/browser-cdp-snapshot-docker.sh)는 소스 E2E 이미지와 Chromium 레이어를 빌드하고, 원시 CDP로 Chromium을 시작하며, browser doctor --deep을 실행하고, CDP 역할 스냅샷이 링크 URL, cursor-promoted clickable, iframe ref, frame metadata를 포함하는지 검증합니다.
  • OpenAI Responses web_search 최소 reasoning 회귀: pnpm test:docker:openai-web-search-minimal (스크립트: scripts/e2e/openai-web-search-minimal-docker.sh)는 Gateway를 통해 모킹된 OpenAI 서버를 실행하고, web_searchreasoning.effortminimal에서 low로 올리는지 검증한 다음, provider schema reject를 강제하고 원시 detail이 Gateway 로그에 나타나는지 확인합니다.
  • MCP 채널 브리지(시드된 Gateway + stdio 브리지 + 원시 Claude notification-frame 스모크): pnpm test:docker:mcp-channels (스크립트: scripts/e2e/mcp-channels-docker.sh)
  • Pi 번들 MCP 도구(실제 stdio MCP 서버 + 임베디드 Pi 프로필 allow/deny 스모크): pnpm test:docker:pi-bundle-mcp-tools (스크립트: scripts/e2e/pi-bundle-mcp-tools-docker.sh)
  • Cron/subagent MCP 정리(실제 Gateway + 격리된 cron 및 one-shot subagent 실행 후 stdio MCP child teardown): pnpm test:docker:cron-mcp-cleanup (스크립트: scripts/e2e/cron-mcp-cleanup-docker.sh)
  • Plugins(로컬 경로, file:, hoisted 의존성이 있는 npm registry, git moving refs, ClawHub kitchen-sink, marketplace 업데이트, Claude-bundle 활성화/검사용 install/update 스모크): pnpm test:docker:plugins (스크립트: scripts/e2e/plugins-docker.sh) ClawHub 블록을 건너뛰려면 OPENCLAW_PLUGINS_E2E_CLAWHUB=0을 설정하거나, 기본 kitchen-sink 패키지/runtime 쌍을 재정의하려면 OPENCLAW_PLUGINS_E2E_CLAWHUB_SPECOPENCLAW_PLUGINS_E2E_CLAWHUB_ID를 설정하세요. OPENCLAW_CLAWHUB_URL/CLAWHUB_URL이 없으면 테스트는 hermetic 로컬 ClawHub fixture 서버를 사용합니다.
  • Plugin 업데이트 변경 없음 스모크: pnpm test:docker:plugin-update (스크립트: scripts/e2e/plugin-update-unchanged-docker.sh)
  • Plugin lifecycle matrix 스모크: pnpm test:docker:plugin-lifecycle-matrix는 bare 컨테이너에 패킹된 OpenClaw tarball을 설치하고, npm Plugin을 설치하며, 활성화/비활성화를 전환하고, 로컬 npm registry를 통해 업그레이드 및 다운그레이드하며, 설치된 코드를 삭제한 다음, 각 lifecycle 단계의 RSS/CPU 메트릭을 기록하면서 uninstall이 오래된 상태를 여전히 제거하는지 검증합니다.
  • 구성 reload metadata 스모크: pnpm test:docker:config-reload (스크립트: scripts/e2e/config-reload-source-docker.sh)
  • Plugins: pnpm test:docker:plugins는 로컬 경로, file:, hoisted 의존성이 있는 npm registry, git moving refs, ClawHub fixture, marketplace 업데이트, Claude-bundle 활성화/검사용 install/update 스모크를 포함합니다. pnpm test:docker:plugin-update는 설치된 plugins의 변경 없는 업데이트 동작을 포함합니다. pnpm test:docker:plugin-lifecycle-matrix는 리소스 추적 npm Plugin 설치, 활성화, 비활성화, 업그레이드, 다운그레이드, missing-code uninstall을 포함합니다.

공유 기능 이미지를 수동으로 미리 빌드하고 재사용하려면:

OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker:e2e-build
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels

OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE 같은 suite별 이미지 재정의는 설정된 경우 여전히 우선합니다. OPENCLAW_SKIP_DOCKER_BUILD=1이 원격 공유 이미지를 가리키면, 스크립트는 해당 이미지가 아직 로컬에 없을 때 이를 pull합니다. QR 및 설치 프로그램 Docker 테스트는 공유 built-app 런타임이 아니라 패키지/설치 동작을 검증하므로 자체 Dockerfile을 유지합니다.

라이브 모델 Docker 러너는 현재 체크아웃을 읽기 전용으로 bind-mount하고, 컨테이너 내부의 임시 workdir에 스테이징합니다. 이렇게 하면 런타임 이미지를 작게 유지하면서도 정확한 로컬 소스/구성에 대해 Vitest를 실행할 수 있습니다. 스테이징 단계는 .pnpm-store, .worktrees, __openclaw_vitest__, 그리고 앱 로컬 .build 또는 Gradle 출력 디렉터리처럼 큰 로컬 전용 캐시와 앱 빌드 출력을 건너뛰므로 Docker 라이브 실행이 머신별 아티팩트를 복사하는 데 몇 분씩 쓰지 않습니다. 또한 OPENCLAW_SKIP_CHANNELS=1을 설정하므로 Gateway 라이브 프로브가 컨테이너 내부에서 실제 Telegram/Discord 등 채널 워커를 시작하지 않습니다. test:docker:live-models는 여전히 pnpm test:live를 실행하므로, 해당 Docker lane에서 Gateway 라이브 커버리지를 좁히거나 제외해야 할 때는 OPENCLAW_LIVE_GATEWAY_*도 함께 전달하세요. test:docker:openwebui는 더 높은 수준의 호환성 smoke입니다. OpenAI 호환 HTTP 엔드포인트가 활성화된 OpenClaw Gateway 컨테이너를 시작하고, 해당 Gateway에 연결된 고정 Open WebUI 컨테이너를 시작한 뒤, Open WebUI를 통해 로그인하고, /api/modelsopenclaw/default를 노출하는지 확인한 다음, Open WebUI의 /api/chat/completions 프록시를 통해 실제 채팅 요청을 보냅니다. 첫 실행은 Docker가 Open WebUI 이미지를 가져와야 하고 Open WebUI가 자체 cold-start 설정을 끝내야 할 수 있어 눈에 띄게 느릴 수 있습니다. 이 lane에는 사용 가능한 라이브 모델 키가 필요하며, Docker화된 실행에서는 OPENCLAW_PROFILE_FILE (~/.profile이 기본값)이 이를 제공하는 기본 방법입니다. 성공한 실행은 { "ok": true, "model": "openclaw/default", ... }와 같은 작은 JSON payload를 출력합니다. test:docker:mcp-channels는 의도적으로 결정적이며 실제 Telegram, Discord, iMessage 계정이 필요하지 않습니다. 시드된 Gateway 컨테이너를 부팅하고, openclaw mcp serve를 spawn하는 두 번째 컨테이너를 시작한 다음, 라우팅된 대화 검색, transcript 읽기, attachment 메타데이터, 라이브 이벤트 큐 동작, outbound send 라우팅, 그리고 실제 stdio MCP bridge를 통한 Claude 스타일 채널 및 권한 알림을 검증합니다. 알림 검사는 raw stdio MCP frame을 직접 검사하므로, smoke는 특정 클라이언트 SDK가 우연히 surface하는 것뿐 아니라 bridge가 실제로 emit하는 내용을 검증합니다. test:docker:pi-bundle-mcp-tools는 결정적이며 라이브 모델 키가 필요하지 않습니다. repo Docker 이미지를 빌드하고, 컨테이너 내부에서 실제 stdio MCP probe server를 시작하고, embedded Pi bundle MCP runtime을 통해 해당 서버를 materialize하고, tool을 실행한 다음, codingmessagingbundle-mcp tool을 유지하고 minimaltools.deny: ["bundle-mcp"]는 이를 필터링하는지 검증합니다. test:docker:cron-mcp-cleanup은 결정적이며 라이브 모델 키가 필요하지 않습니다. 실제 stdio MCP probe server가 있는 시드된 Gateway를 시작하고, 격리된 cron turn과 /subagents spawn one-shot child turn을 실행한 뒤, 각 실행 후 MCP child process가 종료되는지 검증합니다.

수동 ACP 일반 언어 thread smoke(CI 아님):

  • bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...
  • 이 스크립트는 regression/debug workflow를 위해 유지하세요. ACP thread routing validation에 다시 필요할 수 있으므로 삭제하지 마세요.

유용한 env var:

  • OPENCLAW_CONFIG_DIR=... (기본값: ~/.openclaw)은 /home/node/.openclaw에 mount됩니다
  • OPENCLAW_WORKSPACE_DIR=... (기본값: ~/.openclaw/workspace)은 /home/node/.openclaw/workspace에 mount됩니다
  • OPENCLAW_PROFILE_FILE=... (기본값: ~/.profile)은 /home/node/.profile에 mount되며 테스트 실행 전에 source됩니다
  • OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1은 임시 config/workspace 디렉터리를 사용하고 외부 CLI auth mount 없이 OPENCLAW_PROFILE_FILE에서 source된 env var만 검증합니다
  • OPENCLAW_DOCKER_CLI_TOOLS_DIR=... (기본값: ~/.cache/openclaw/docker-cli-tools)은 Docker 내부의 캐시된 CLI install을 위해 /home/node/.npm-global에 mount됩니다
  • $HOME 아래의 외부 CLI auth dir/file은 /host-auth... 아래에 read-only로 mount된 다음, 테스트가 시작되기 전에 /home/node/...로 복사됩니다
    • 기본 dir: .minimax
    • 기본 file: ~/.codex/auth.json, ~/.codex/config.toml, .claude.json, ~/.claude/.credentials.json, ~/.claude/settings.json, ~/.claude/settings.local.json
    • 좁혀진 provider 실행은 OPENCLAW_LIVE_PROVIDERS / OPENCLAW_LIVE_GATEWAY_PROVIDERS에서 추론한 필요한 dir/file만 mount합니다
    • OPENCLAW_DOCKER_AUTH_DIRS=all, OPENCLAW_DOCKER_AUTH_DIRS=none, 또는 OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex 같은 쉼표 목록으로 수동 override합니다
  • OPENCLAW_LIVE_GATEWAY_MODELS=... / OPENCLAW_LIVE_MODELS=...로 실행 범위를 좁힙니다
  • OPENCLAW_LIVE_GATEWAY_PROVIDERS=... / OPENCLAW_LIVE_PROVIDERS=...로 컨테이너 내부 provider를 필터링합니다
  • OPENCLAW_SKIP_DOCKER_BUILD=1로 rebuild가 필요 없는 재실행에 기존 openclaw:local-live 이미지를 재사용합니다
  • OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1로 creds가 env가 아니라 profile store에서 오도록 보장합니다
  • OPENCLAW_OPENWEBUI_MODEL=...로 Open WebUI smoke를 위해 Gateway가 노출하는 model을 선택합니다
  • OPENCLAW_OPENWEBUI_PROMPT=...로 Open WebUI smoke에서 사용하는 nonce-check prompt를 override합니다
  • OPENWEBUI_IMAGE=...로 고정된 Open WebUI image tag를 override합니다

문서 sanity

문서 편집 후 docs check를 실행하세요: pnpm check:docs. in-page heading check도 필요할 때는 전체 Mintlify anchor validation을 실행하세요: pnpm docs:check-links:anchors.

Offline regression(CI 안전)

다음은 실제 provider 없는 "real pipeline" regression입니다:

  • Gateway tool calling(mock OpenAI, real gateway + agent loop): src/gateway/gateway.test.ts (case: "runs a mock OpenAI tool call end-to-end via gateway agent loop")
  • Gateway wizard(WS wizard.start/wizard.next, config 작성 + auth 강제): src/gateway/gateway.test.ts (case: "runs wizard over ws and writes auth token config")

Agent reliability evals(skills)

이미 "agent reliability evals"처럼 동작하는 몇 가지 CI 안전 테스트가 있습니다:

  • 실제 Gateway + agent loop를 통한 mock tool-calling(src/gateway/gateway.test.ts).
  • session wiring과 config effects를 검증하는 end-to-end wizard flow(src/gateway/gateway.test.ts).

Skills에 아직 부족한 것(Skills 참고):

  • Decisioning: prompt에 skills가 나열되어 있을 때 agent가 올바른 skill을 선택하거나 관련 없는 것을 피하는가?
  • Compliance: agent가 사용 전에 SKILL.md를 읽고 필요한 단계/args를 따르는가?
  • Workflow contracts: tool order, session history carryover, sandbox boundary를 assert하는 multi-turn scenario.

향후 eval은 먼저 결정적으로 유지해야 합니다:

  • mock provider를 사용해 tool call + order, skill file read, session wiring을 assert하는 scenario runner.
  • skill 중심 scenario의 작은 suite(use vs avoid, gating, prompt injection).
  • CI 안전 suite가 갖춰진 뒤에만 선택적 live eval(opt-in, env-gated).

Contract tests(Plugin 및 channel shape)

Contract test는 등록된 모든 Plugin과 channel이 각 interface contract를 준수하는지 검증합니다. 발견된 모든 Plugin을 순회하며 shape 및 behavior assertion suite를 실행합니다. 기본 pnpm test unit lane은 이러한 shared seam 및 smoke file을 의도적으로 건너뜁니다. shared channel 또는 provider surface를 건드릴 때는 contract command를 명시적으로 실행하세요.

명령어

  • 모든 contract: pnpm test:contracts
  • Channel contract만: pnpm test:contracts:channels
  • Provider contract만: pnpm test:contracts:plugins

Channel contract

src/channels/plugins/contracts/*.contract.test.ts에 위치:

  • plugin - 기본 Plugin shape(id, name, capabilities)
  • setup - Setup wizard contract
  • session-binding - Session binding behavior
  • outbound-payload - Message payload structure
  • inbound - Inbound message handling
  • actions - Channel action handler
  • threading - Thread ID handling
  • directory - Directory/roster API
  • group-policy - Group policy enforcement

Provider status contract

src/plugins/contracts/*.contract.test.ts에 위치.

  • status - Channel status probe
  • registry - Plugin registry shape

Provider contract

src/plugins/contracts/*.contract.test.ts에 위치:

  • auth - Auth flow contract
  • auth-choice - Auth choice/selection
  • catalog - Model catalog API
  • discovery - Plugin discovery
  • loader - Plugin loading
  • runtime - Provider runtime
  • shape - Plugin shape/interface
  • wizard - Setup wizard

실행 시점

  • plugin-sdk export 또는 subpath를 변경한 후
  • channel 또는 provider Plugin을 추가하거나 수정한 후
  • Plugin registration 또는 discovery를 refactor한 후

Contract test는 CI에서 실행되며 실제 API key가 필요하지 않습니다.

Regression 추가(가이드)

라이브에서 발견한 provider/model 문제를 수정할 때:

  • 가능하면 CI 안전 regression을 추가하세요(mock/stub provider 또는 정확한 request-shape transformation capture)
  • 본질적으로 live-only(rate limit, auth policy)라면 live test를 좁게 유지하고 env var를 통해 opt-in으로 두세요
  • 버그를 잡는 가장 작은 layer를 대상으로 하는 것을 선호하세요:
    • provider request conversion/replay bug → direct models test
    • gateway session/history/tool pipeline bug → gateway live smoke 또는 CI 안전 gateway mock test
  • SecretRef traversal guardrail:
    • src/secrets/exec-secret-ref-id-parity.test.ts는 registry metadata(listSecretTargetRegistryEntries())에서 SecretRef class별 sampled target 하나를 derive한 다음, traversal-segment exec id가 reject되는지 assert합니다.
    • src/secrets/target-registry-data.ts에 새 includeInPlan SecretRef target family를 추가하면 해당 테스트의 classifyTargetClass를 업데이트하세요. 이 테스트는 분류되지 않은 target id에서 의도적으로 실패하므로 새 class가 조용히 skip될 수 없습니다.

관련 항목