Technical reference for the OpenClaw framework. Real-time synchronization with the official documentation engine.
Use this file to discover all available pages before exploring further.
Release policy
OpenClaw has three public release lanes:
stable: tagged releases that publish to npm
text
beta
by default, or to npm
text
latest
when explicitly requested
beta: prerelease tags that publish to npm
text
beta
dev: the moving head of
text
main
Version naming
Stable release version:
text
YYYY.M.D
Git tag:
text
vYYYY.M.D
Stable correction release version:
text
YYYY.M.D-N
Git tag:
text
vYYYY.M.D-N
Beta prerelease version:
text
YYYY.M.D-beta.N
Git tag:
text
vYYYY.M.D-beta.N
Do not zero-pad month or day
text
latest
means the current promoted stable npm release
text
beta
means the current beta install target
Stable and stable correction releases publish to npm
text
beta
by default; release operators can target
text
latest
explicitly, or promote a vetted beta build later
Every stable OpenClaw release ships the npm package and macOS app together;
beta releases normally validate and publish the npm/package path first, with
mac app build/sign/notarize reserved for stable unless explicitly requested
Release cadence
Releases move beta-first
Stable follows only after the latest beta is validated
Maintainers normally cut releases from a
text
release/YYYY.M.D
branch created
from current
text
main
, so release validation and fixes do not block new
development on
text
main
If a beta tag has been pushed or published and needs a fix, maintainers cut
the next
text
-beta.N
tag instead of deleting or recreating the old beta tag
Detailed release procedure, approvals, credentials, and recovery notes are
maintainer-only
Release operator checklist
This checklist is the public shape of the release flow. Private credentials,
signing, notarization, dist-tag recovery, and emergency rollback details stay in
the maintainer-only release runbook.
Start from current
text
main
: pull latest, confirm the target commit is pushed,
and confirm current
text
main
CI is green enough to branch from it.
Rewrite the top
text
CHANGELOG.md
section from real commit history with
text
/changelog
, keep entries user-facing, commit it, push it, and rebase/pull
once more before branching.
Review release compatibility records in
text
src/plugins/compat/registry.ts
and
text
src/commands/doctor/shared/deprecation-compat.ts
. Remove expired
compatibility only when the upgrade path stays covered, or record why it is
intentionally carried.
Create
text
release/YYYY.M.D
from current
text
main
; do not do normal release work
directly on
text
main
.
Bump every required version location for the intended tag, then run the
local deterministic preflight:
text
pnpm check:test-types
,
text
pnpm check:architecture
,
text
pnpm build && pnpm ui:build
, and
text
pnpm release:check
.
Run
text
OpenClaw NPM Release
with
text
preflight_only=true
. Before a tag exists,
a full 40-character release-branch SHA is allowed for validation-only
preflight. Save the successful
text
preflight_run_id
.
Kick off all pre-release tests with
text
Full Release Validation
for the
release branch, tag, or full commit SHA. This is the one manual entrypoint
for the four big release test boxes: Vitest, Docker, QA Lab, and Package.
If validation fails, fix on the release branch and rerun the smallest failed
file, lane, workflow job, package profile, provider, or model allowlist that
proves the fix. Rerun the full umbrella only when the changed surface makes
prior evidence stale.
For beta, tag
text
vYYYY.M.D-beta.N
, publish with npm dist-tag
text
beta
, then run
post-publish package acceptance against the published
text
openclaw@YYYY.M.D-beta.N
or
text
openclaw@beta
package. If a pushed or published beta needs a fix, cut
the next
text
-beta.N
; do not delete or rewrite the old beta.
For stable, continue only after the vetted beta or release candidate has the
required validation evidence. Stable npm publish reuses the successful
preflight artifact via
text
preflight_run_id
; stable macOS release readiness
also requires the packaged
text
.zip
,
text
.dmg
,
text
.dSYM.zip
, and updated
text
appcast.xml
on
text
main
.
After publish, run the npm post-publish verifier, optional standalone
published-npm Telegram E2E when you need post-publish channel proof,
dist-tag promotion when needed, GitHub release/prerelease notes from the
complete matching
text
CHANGELOG.md
section, and the release announcement
steps.
Release preflight
Run
text
pnpm check:test-types
before release preflight so test TypeScript stays
covered outside the faster local
text
pnpm check
gate
Run
text
pnpm check:architecture
before release preflight so the broader import
cycle and architecture boundary checks are green outside the faster local gate
Run
text
pnpm build && pnpm ui:build
before
text
pnpm release:check
so the expected
text
dist/*
release artifacts and Control UI bundle exist for the pack
validation step
Run the manual
text
Full Release Validation
workflow before release approval to
kick off all pre-release test boxes from one entrypoint. It accepts a branch,
tag, or full commit SHA, dispatches manual
text
CI
, and dispatches
text
OpenClaw Release Checks
for install smoke, package acceptance, Docker
release-path suites, live/E2E, OpenWebUI, QA Lab parity, Matrix, and Telegram
lanes. Provide
text
npm_telegram_package_spec
only after a package has been
published and the post-publish Telegram E2E should run too. Provide
text
evidence_package_spec
when the private evidence report should prove that the
validation matches a published npm package without forcing Telegram E2E.
Example:
text
gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D
Run the manual
text
Package Acceptance
workflow when you want side-channel proof
for a package candidate while release work continues. Use
text
source=npm
for
text
openclaw@beta
,
text
openclaw@latest
, or an exact release version;
text
source=ref
to pack a trusted
text
package_ref
branch/tag/SHA with the current
text
workflow_ref
harness;
text
source=url
for an HTTPS tarball with a required
SHA-256; or
text
source=artifact
for a tarball uploaded by another GitHub
Actions run. The workflow resolves the candidate to
text
package-under-test
, reuses the Docker E2E release scheduler against that
tarball, and can run Telegram QA against the same tarball with
text
telegram_mode=mock-openai
or
text
telegram_mode=live-frontier
. When the
selected Docker lanes include
text
published-upgrade-survivor
, the package
artifact is the candidate and
text
published_upgrade_survivor_baseline
selects
the published baseline.
Example:
text
gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product -f published_upgrade_survivor_baseline=openclaw@2026.4.26 -f telegram_mode=mock-openai
Common profiles:
text
smoke
: install/channel/agent, gateway network, and config reload lanes
text
package
: artifact-native package/update/plugin lanes without OpenWebUI or live ClawHub
text
product
: package profile plus MCP channels, cron/subagent cleanup,
OpenAI web search, and OpenWebUI
text
full
: Docker release-path chunks with OpenWebUI
text
custom
: exact
text
docker_lanes
selection for a focused rerun
Run the manual
text
CI
workflow directly when you only need full normal CI
coverage for the release candidate. Manual CI dispatches bypass changed
scoping and force the Linux Node shards, bundled-plugin shards, channel
contracts, Node 22 compatibility,
text
check
,
text
check-additional
, build smoke,
docs checks, Python skills, Windows, macOS, Android, and Control UI i18n
lanes.
Example:
text
gh workflow run ci.yml --ref release/YYYY.M.D
Run
text
pnpm qa:otel:smoke
when validating release telemetry. It exercises
QA-lab through a local OTLP/HTTP receiver and verifies the exported trace
span names, bounded attributes, and content/identifier redaction without
requiring Opik, Langfuse, or another external collector.
Run
text
pnpm release:check
before every tagged release
Release checks now run in a separate manual workflow:
text
OpenClaw Release Checks
text
OpenClaw Release Checks
also runs the QA Lab mock parity gate plus the fast
live Matrix profile and Telegram QA lane before release approval. The live
lanes use the
text
qa-live-shared
environment; Telegram also uses Convex CI
credential leases. Run the manual
text
QA-Lab - All Lanes
workflow with
text
matrix_profile=all
and
text
matrix_shards=true
when you want full Matrix
transport, media, and E2EE inventory in parallel.
Cross-OS install and upgrade runtime validation is part of public
This split is intentional: keep the real npm release path short,
deterministic, and artifact-focused, while slower live checks stay in their
own lane so they do not stall or block publish
Secret-bearing release checks should be dispatched through
text
Full Release Validation
or from the
text
main
/release workflow ref so workflow logic and
secrets stay controlled
text
OpenClaw Release Checks
accepts a branch, tag, or full commit SHA as long
as the resolved commit is reachable from an OpenClaw branch or release tag
text
OpenClaw NPM Release
validation-only preflight also accepts the current
full 40-character workflow-branch commit SHA without requiring a pushed tag
That SHA path is validation-only and cannot be promoted into a real publish
In SHA mode the workflow synthesizes
text
v<package.json version>
only for the
package metadata check; real publish still requires a real release tag
Both workflows keep the real publish and promotion path on GitHub-hosted
runners, while the non-mutating validation path can use the larger
Blacksmith Linux runners
to verify installed-package onboarding, Telegram setup, and real Telegram E2E
against the published npm package using the shared leased Telegram credential
pool. Local maintainer one-offs may omit the Convex vars and pass the three
text
OPENCLAW_QA_TELEGRAM_*
env credentials directly.
Maintainers can run the same post-publish check from GitHub Actions via the
manual
text
NPM Telegram Beta E2E
workflow. It is intentionally manual-only and
does not run on every merge.
Maintainer release automation now uses preflight-then-promote:
real npm publish must pass a successful npm
text
preflight_run_id
the real npm publish must be dispatched from the same
The workflow resolves the target ref, dispatches manual
text
CI
with
text
target_ref=<release-ref>
, dispatches
text
OpenClaw Release Checks
, and
optionally dispatches standalone post-publish Telegram E2E when
text
npm_telegram_package_spec
is set.
text
OpenClaw Release Checks
then fans out
install smoke, cross-OS release checks, live/E2E Docker release-path coverage,
Package Acceptance with Telegram package QA, QA Lab parity, live Matrix, and
live Telegram. A full run is only acceptable when the
text
Full Release Validation
summary shows
text
normal_ci
and
text
release_checks
as successful, and any optional
text
npm_telegram
child is either successful or intentionally skipped. The final
verifier summary includes slowest-job tables for each child run, so the release
manager can see the current critical path without downloading logs.
See Full release validation for the
complete stage matrix, exact workflow job names, stable versus full profile
differences, artifacts, and focused rerun handles.
Child workflows are dispatched from the trusted ref that runs
text
Full Release Validation
, normally
text
--ref main
, even when the target
text
ref
points at an
older release branch or tag. There is no separate Full Release Validation
workflow-ref input; choose the trusted harness by choosing the workflow run ref.
Use
text
release_profile
to select live/provider breadth:
text
minimum
: fastest release-critical OpenAI/core live and Docker path
text
stable
: minimum plus stable provider/backend coverage for release approval
text
full
: stable plus broad advisory provider/media coverage
text
OpenClaw Release Checks
uses the trusted workflow ref to resolve the target
ref once as
text
release-package-under-test
and reuses that artifact in both
release-path Docker checks and Package Acceptance. This keeps all
package-facing boxes on the same bytes and avoids repeated package builds.
The cross-OS OpenAI install smoke uses
text
OPENCLAW_CROSS_OS_OPENAI_MODEL
when the
repo/org variable is set, otherwise
text
openai/gpt-5.4-mini
, because this lane is
proving package install, onboarding, gateway startup, and one live agent turn
rather than benchmarking the slowest default model. The broader live provider
matrix remains the place for model-specific coverage.
Use these variants depending on release stage:
bash
# Validate an unpublished release candidate branch.
gh workflow run full-release-validation.yml \
--ref main \
-f ref=release/YYYY.M.D \
-f provider=openai \
-f mode=both \
-f release_profile=stable
# Validate an exact pushed commit.
gh workflow run full-release-validation.yml \
--ref main \
-f ref=<40-char-sha> \
-f provider=openai \
-f mode=both
# After publishing a beta, add published-package Telegram E2E.
gh workflow run full-release-validation.yml \
--ref main \
-f ref=release/YYYY.M.D \
-f provider=openai \
-f mode=both \
-f evidence_package_spec=openclaw@YYYY.M.D-beta.N \
-f npm_telegram_package_spec=openclaw@YYYY.M.D-beta.N \
-f npm_telegram_provider_mode=mock-openai
Do not use the full umbrella as the first rerun after a focused fix. If one box
fails, use the failed child workflow, job, Docker lane, package profile, model
provider, or QA lane for the next proof. Run the full umbrella again only when
the fix changed shared release orchestration or made earlier all-box evidence
stale. The umbrella's final verifier re-checks the recorded child workflow run
ids, so after a child workflow is rerun successfully, rerun only the failed
text
Verify full validation
parent job.
For bounded recovery, pass
text
rerun_group
to the umbrella.
text
all
is the real
release-candidate run,
text
ci
runs only the normal CI child,
text
plugin-prerelease
runs only the release-only plugin child,
text
release-checks
runs every release
box, and the narrower release groups are
text
install-smoke
,
text
cross-os
,
text
live-e2e
,
text
package
,
text
qa
,
text
qa-parity
,
text
qa-live
, and
text
npm-telegram
when the
standalone package Telegram lane is supplied.
Vitest
The Vitest box is the manual
text
CI
child workflow. Manual CI intentionally
bypasses changed scoping and forces the normal test graph for the release
candidate: Linux Node shards, bundled-plugin shards, channel contracts, Node 22
compatibility,
text
check
,
text
check-additional
, build smoke, docs checks, Python
skills, Windows, macOS, Android, and Control UI i18n.
Use this box to answer "did the source tree pass the full normal test suite?"
It is not the same as release-path product validation. Evidence to keep:
text
Full Release Validation
summary showing the dispatched
text
CI
run URL
text
CI
run green on the exact target SHA
failed or slow shard names from the CI jobs when investigating regressions
Vitest timing artifacts such as
text
.artifacts/vitest-shard-timings.json
when
a run needs performance analysis
Run manual CI directly only when the release needs deterministic normal CI but
not the Docker, QA Lab, live, cross-OS, or package boxes:
bash
gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D
Docker
The Docker box lives in
text
OpenClaw Release Checks
through
text
openclaw-live-and-e2e-checks-reusable.yml
, plus the release-mode
text
install-smoke
workflow. It validates the release candidate through packaged
Docker environments instead of only source-level tests.
Release Docker coverage includes:
full install smoke with the slow Bun global install smoke enabled
root Dockerfile smoke image preparation/reuse by target SHA, with QR,
root/gateway, and installer/Bun smoke jobs running as separate install-smoke
shards
repository E2E lanes
release-path Docker chunks:
text
core
,
text
package-update-openai
,
text
package-update-anthropic
,
text
package-update-core
,
text
plugins-runtime-plugins
,
text
plugins-runtime-services
,
text
plugins-runtime-install-a
,
text
plugins-runtime-install-b
,
text
plugins-runtime-install-c
,
text
plugins-runtime-install-d
,
text
plugins-runtime-install-e
,
text
plugins-runtime-install-f
,
text
plugins-runtime-install-g
,
text
plugins-runtime-install-h
,
text
bundled-channels-core
,
text
bundled-channels-update-a
,
text
bundled-channels-update-discord
,
text
bundled-channels-update-b
, and
text
bundled-channels-contracts
OpenWebUI coverage inside the
text
plugins-runtime-services
chunk when requested
split bundled-channel dependency lanes across channel-smoke, update-target,
and setup/runtime contract chunks instead of one large bundled-channel job
split bundled plugin install/uninstall lanes
text
bundled-plugin-install-uninstall-0
through
text
bundled-plugin-install-uninstall-23
live/E2E provider suites and Docker live model coverage when release checks
include live suites
Use Docker artifacts before rerunning. The release-path scheduler uploads
text
.artifacts/docker-tests/
with lane logs,
text
summary.json
,
text
failures.json
,
phase timings, scheduler plan JSON, and rerun commands. For focused recovery,
use
text
docker_lanes=<lane[,lane]>
on the reusable live/E2E workflow instead of
rerunning all release chunks. Generated rerun commands include prior
text
package_artifact_run_id
and prepared Docker image inputs when available, so a
failed lane can reuse the same tarball and GHCR images.
QA Lab
The QA Lab box is also part of
text
OpenClaw Release Checks
. It is the agentic
behavior and channel-level release gate, separate from Vitest and Docker
package mechanics.
Release QA Lab coverage includes:
mock parity gate comparing the OpenAI candidate lane against the Opus 4.6
baseline using the agentic parity pack
fast live Matrix QA profile using the
text
qa-live-shared
environment
live Telegram QA lane using Convex CI credential leases
text
pnpm qa:otel:smoke
when release telemetry needs explicit local proof
Use this box to answer "does the release behave correctly in QA scenarios and
live channel flows?" Keep the artifact URLs for parity, Matrix, and Telegram
lanes when approving the release. Full Matrix coverage remains available as a
manual sharded QA-Lab run rather than the default release-critical lane.
Package
The Package box is the installable-product gate. It is backed by
text
Package Acceptance
and the resolver
text
scripts/resolve-openclaw-package-candidate.mjs
. The resolver normalizes a
candidate into the
text
package-under-test
tarball consumed by Docker E2E, validates
the package inventory, records the package version and SHA-256, and keeps the
workflow harness ref separate from the package source ref.
. The release-path Docker chunks cover the
overlapping install, update, and plugin-update lanes; Package Acceptance keeps
artifact-native bundled-channel compat, offline plugin fixtures, and Telegram
package QA against the same resolved tarball. It is the GitHub-native
replacement for most of the package/update coverage that previously required
Parallels. Cross-OS release checks still matter for OS-specific onboarding,
installer, and platform behavior, but package/update product validation should
prefer Package Acceptance.
Legacy package-acceptance leniency is intentionally time boxed. Packages through
text
2026.4.25
may use the compatibility path for metadata gaps already published
to npm: private QA inventory entries missing from the tarball, missing
text
gateway install --wrapper
, missing patch files in the tarball-derived git
fixture, missing persisted
text
update.channel
, legacy plugin install-record
locations, missing marketplace install-record persistence, and config metadata
migration during
text
plugins update
. The published
text
2026.4.26
package may warn
for local build metadata stamp files that were already shipped. Later packages
must satisfy the modern package contracts; those same gaps fail release
validation.
Use broader Package Acceptance profiles when the release question is about an
actual installable package:
: quick package install/channel/agent, gateway network, and config
reload lanes
text
package
: install/update/plugin package contracts without live ClawHub; this is the release-check
default
text
product
:
text
package
plus MCP channels, cron/subagent cleanup, OpenAI web
search, and OpenWebUI
text
full
: Docker release-path chunks with OpenWebUI
text
custom
: exact
text
docker_lanes
list for focused reruns
For package-candidate Telegram proof, enable
text
telegram_mode=mock-openai
or
text
telegram_mode=live-frontier
on Package Acceptance. The workflow passes the
resolved
text
package-under-test
tarball into the Telegram lane; the standalone
Telegram workflow still accepts a published npm spec for post-publish checks.
NPM workflow inputs
text
OpenClaw NPM Release
accepts these operator-controlled inputs:
text
tag
: required release tag such as
text
v2026.4.2
,
text
v2026.4.2-1
, or
text
v2026.4.2-beta.1
; when
text
preflight_only=true
, it may also be the current
full 40-character workflow-branch commit SHA for validation-only preflight
text
preflight_only
:
text
true
for validation/build/package only,
text
false
for the
real publish path
text
preflight_run_id
: required on the real publish path so the workflow reuses
the prepared tarball from the successful preflight run
text
npm_dist_tag
: npm target tag for the publish path; defaults to
text
beta
text
OpenClaw Release Checks
accepts these operator-controlled inputs:
text
ref
: branch, tag, or full commit SHA to validate. Secret-bearing checks
require the resolved commit to be reachable from an OpenClaw branch or
release tag.
Rules:
Stable and correction tags may publish to either
text
beta
or
text
latest
Beta prerelease tags may publish only to
text
beta
For
text
OpenClaw NPM Release
, full commit SHA input is allowed only when
text
preflight_only=true
text
OpenClaw Release Checks
and
text
Full Release Validation
are always
validation-only
The real publish path must use the same
text
npm_dist_tag
used during preflight;
the workflow verifies that metadata before publish continues
Stable npm release sequence
When cutting a stable npm release:
Run
text
OpenClaw NPM Release
with
text
preflight_only=true
Before a tag exists, you may use the current full workflow-branch commit
SHA for a validation-only dry run of the preflight workflow
Choose
text
npm_dist_tag=beta
for the normal beta-first flow, or
text
latest
only
when you intentionally want a direct stable publish
Run
text
Full Release Validation
on the release branch, release tag, or full
commit SHA when you want normal CI plus live prompt cache, Docker, QA Lab,
Matrix, and Telegram coverage from one manual workflow
If you intentionally only need the deterministic normal test graph, run the
manual
If the release intentionally published directly to
text
latest
and
text
beta
should follow the same stable build immediately, use that same private
workflow to point both dist-tags at the stable version, or let its scheduled
self-healing sync move
text
beta
later
The dist-tag mutation lives in the private repo for security because it still
requires
text
NPM_TOKEN
, while the public repo keeps OIDC-only publish.
That keeps the direct publish path and the beta-first promotion path both
documented and operator-visible.
If a maintainer must fall back to local npm authentication, run any 1Password
CLI (
text
op
) commands only inside a dedicated tmux session. Do not call
text
op
directly from the main agent shell; keeping it inside tmux makes prompts,
alerts, and OTP handling observable and prevents repeated host alerts.