Testing and CI
CI pipeline
This page is an index. CI is documented on nine pages, one per reader job. Open the page that matches your task.
Automation admission filters known no-op events before runner allocation and concurrency, keeping automation on GitHub-hosted runners.
For the published-upgrade regression gate, see selection and routing, runner budgets, and Package Acceptance baselines. Weekly validation is listed under Update Migration.
Docs-only main pushes skip CI and cache warming. The cache warmer publishes dependencies independently of long builds and maintains a bounded hosted seed in hybrid mode. Every admitted canonical main run exercises one published-driver × candidate Docker upgrade; ordinary manual/release validation adds the other five Docker seed lanes. QA Smoke, real-Gateway browser checks, and named process proofs retain their selected main coverage and manual/release validation. Pull requests and exact-head PR fallback dispatches retain unit, boundary, build, and mocked-Gateway coverage. Windows retains its complete inventory across five measured file shards. See scope selection and capacity for the coverage trade-off.
Core-test-only PRs use targeted type checks only when every selected test exists in the checkout. Deleting a core test keeps the full type-check plan, including the existing core stripes on GitHub and hybrid profiles.
Full GitHub and hybrid type checks run the five core stripes independently, retaining two compiler children per job. Current hybrid runs also split extension lint across six hosted jobs. Frozen targets keep their earlier layout; see static checks.
Core lint discovers separate source and UI TypeScript projects, retaining shared ambient declarations and imported dependencies. The source project also includes src/**/*.test-support.cjs; unrelated JavaScript files are not added as roots. See local checks.
Android native resource preparation uses the Mermaid renderer's filtered dependency install, including optional build tooling. Pnpm retains root dependencies but omits unrelated plugin packages; Gradle still builds the assets and runs the selected native tests and lint. Historical targets keep their compatibility path.
Android phone tests use up to two isolated JVMs on Blacksmith and retain Gradle-owned cache expiry. The same four normal rows split phone tests from app lint: Wear owns third-party lint, and Kotlin lint owns Play/shared lint. Normal same-repository Blacksmith runs overlap all four rows; other routes retain two. All test and lint tasks remain selected.
macOS Swift CI runs the app and independent package suites in separate native phases, retaining every test and the existing concurrency and timeout limits.
Native test builds retain coverage and source-line backtraces while omitting IDE indexes and full debugger type metadata. Local development builds keep their normal debug settings.
Short hybrid jobs use a 40-row base threshold and 45-row hosted admission limit, with unchanged coverage and Blacksmith fallback when optional work does not fit.
Additional hybrid check offloads require fresh hosted assignment evidence. Eligible PRs can move five measured checks; main pushes can also move lint and central types within the same hosted row limit. Artifact builds retain Blacksmith because their measured hosted tail leaves no room for the 15-minute routing objective.
Windows keeps its complete explicit test inventory in five measured project-aligned shards, sharing each small project's setup within one job.
Real-Gateway browser checks use job budgets matched to their selected runner.
Control UI CI installs the Chromium revision pinned by Playwright even when the browser cache misses. Current targets use the installer's --require-playwright-chromium mode; historical targets retain their existing installer. Browser startup diagnostics include provider, page, WebSocket, and Chromium process events to diagnose a session-readiness timeout even when it is reported only after unrelated unit work finishes.
Browser extension CI launches the installed, patched Chrome MCP dependency directly.
Build, QA and test orchestration restore the same protected Node compile cache. The trusted warmer populates build tools before collecting test imports, including the same seven Control UI seed files on Node and the pinned Bun fork in both Linux cache backends; ordinary CI remains restore-only.
In-process Gateway test configs use exclusive plan admission within existing packed jobs.
Changed-extension PR jobs use measured fallback rates and a 300-second packing budget within the landed 90-row compact, 130-row PR and 70-row push caps.
Compact planning reserves the actual appended plugin rows before applying those Node matrix caps, allowing existing hosted tooling compaction to use the remaining capacity.
Roomy serial Blacksmith Node jobs use measured Vitest worker sizing, with existing hosted, frozen-target, and overlapping-plan limits.
Source-only Linux Node shards can reuse content-validated compiled workers from the protected warmer; fixed preparation costs remain separate from test execution and runner capacity.
Vitest transform-cache fingerprints exclude the generated .ci-harness checkout so CI consumers and the protected warmer hash the same source inputs. Node bytecode caching remains enabled for ordinary Vitest runs; Vitest owns the worker-level coverage safeguard described in local testing.
Transform keys also include each project's dependency optimizer directory. This prevents cached UI imports from mixing separate projects' Lit instances when a focused run and a full run share the persistent cache.
Linux PR tests use Bun for the measured compatible unit lanes and Control UI Vitest job, with a targeted CSS-tokenizer optimizer workaround. Full Release Validation keeps their Node coverage and runs them on Bun too; see test runtime selection.
Full Release Validation's exact-target UI job retains the current three native shards for both runtimes. Historical compatibility targets keep their original unsharded package command; see UI job budgets.
Auto-reply reply tests run files in parallel with two workers per compact group. Their planner uses separate parallel timing identities; until those have measurements, serial group costs are divided by the effective worker count, with single-file groups retaining their full cost.
The measured Gateway isolated/database-worker cohort uses at most eight workers on those hosts with at least 28 GiB total memory; other packed groups retain their existing caps.
Commands tests share the existing worker budget across independent files. The Doctor session SQLite cases are split by operation while preserving the complete repair and recovery coverage; see shard weights.
The complete startup corpus uses eight state test files so existing workers can share its release/config matrix. Its explicit fallback prepares the runtime once and uses up to four workers, capped by available CPU parallelism; historical frozen targets retain their legacy process layout with CPU-bounded admission.
| Page | Read it when |
|---|---|
| CI pipeline jobs | The job table, the fail-fast order, and the Control UI size budgets. |
| Watch a CI run | Wait on one pull request head, recover a stuck run, and pass the evidence gate. |
| CI checkout ownership | Shared checkout anchors, fetch retry budgets, and trusted action policy. |
| CI scope and routing | Why a job did or did not run: changed-scope detection and manual dispatch. |
| CI runner classes | Trust-based runner routing, preflight queue recovery, Blacksmith classes, and runner backend modes. |
| CI capacity and shard weights | The runner registration budget and the measured timings behind shard packing. |
| Release validation workflows | Full Release Validation, live and E2E shards, Package Acceptance, install smoke, Docker E2E, and Plugin Prerelease. |
| Scheduled and maintenance workflows | OpenClaw Performance, QA Lab, CodeQL, the maintenance jobs, and ClawSweeper activity forwarding. |
| Local checks and Testbox | Reproduce a lane locally, keep the shrink-only ratchets, and run Crabbox or Testbox proof. |
Where each section moved
Every section heading from the previous single-page version keeps its anchor here, so an existing link such as /ci#pipeline-overview still resolves. Each entry points at the page that now holds the content.
- Pipeline overview
- Fail-fast order
- Control UI size budgets
- Watching pull request CI
- Recover an existing PR run first
- PR context and evidence
- Checkout ownership
- Scope and routing
- Measured shard weights
- ClawSweeper activity forwarding
- Manual dispatches
- Windows Testbox Probe
- Runners
- Blacksmith runner capacity
- Runner backend modes
- Runner registration budget
- Surface ratchets
- Local equivalents
- OpenClaw Performance
- Vitest paired benchmark
- Full Release Validation
- Live and E2E shards
- Package Acceptance
- Jobs
- Candidate sources
- Suite profiles
- Legacy compatibility windows
- Examples
- Install smoke
- Local Docker E2E
- Tunables
- Reusable live/E2E workflow
- Release-path chunks
- Plugin Prerelease
- QA Lab
- CodeQL
- Security categories
- Platform-specific security shards
- Critical Quality categories
- Maintenance workflows
- Dependency Audit
- Docs Agent
- Duplicate PRs After Merge
- Local check gates and changed routing
- Config baseline count ratchet
- Testbox validation