On this page
On this page
Plugin internals
Plugin compatibility
OpenClaw keeps older plugin contracts wired through named compatibility adapters before removing them. This protects existing bundled and external plugins while the SDK, manifest, setup, config, and agent runtime contracts evolve.
All plugin APIs are experimental. Plugin authors should pin and test supported OpenClaw host versions. This stability designation does not cancel existing deprecation windows, compatibility adapters, or supported-upgrade migrations described below.
Compatibility registry
Plugin compatibility contracts are tracked in the core registry at
src/plugins/compat/registry.ts. Each record has:
- a stable compatibility code
- status:
active,deprecated,removal-pending, orremoved - owner:
sdk,config,setup,channel,provider,plugin-execution,agent-runtime, orcore - deprecation and warning start dates when applicable
- an exact
removeAfterdate or namedremovalGateonce the owning maintainer approves it; a record with neither remains ineligible for removal - replacement guidance
- docs and diagnostic references for the old and new behavior
The registry is the source for maintainer planning and deprecated SDK import notices. If a plugin-facing behavior changes, add or update the compatibility record in the same change that adds the adapter.
Doctor repair and migration compatibility is tracked separately at
src/commands/doctor/shared/deprecation-compat.ts. Those records cover old
config shapes, install-ledger layouts, and repair shims that may need to
stay available after the runtime compatibility path is removed.
Every doctor compatibility record declares introduced and removeAfter.
The pnpm check:doctor-deprecation-registry guard fails when a record is still
deprecated on or after removeAfter; maintainers must either remove it after
supported-upgrade proof or move it to removal-pending with a documented
blocker. removal-pending records do not fail the date guard, but remain in the
explicit review queue until their upgrade conditions are met.
A maintainer-approved doctor deadline renewal preserves the original date as
previousRemoveAfter, records the approval date as renewedAt, and sets a new
removeAfter no more than three months later. Renewal changes review timing
only; it does not change runtime compatibility, config handling, migration
behavior, or lifecycle status. On August 29, 2026, all 44 current doctor
records were renewed through November 29, 2026.
Release sweeps should check both registries. Do not delete a doctor migration just because the matching runtime or config compatibility record expired; first verify there is no supported upgrade path that still needs the repair. Revalidate each replacement annotation during release planning too, since plugin ownership and config footprint can change as providers and channels move out of core.
Observed SDK usage
OpenClaw records deprecated SDK subpaths when a plugin imports them and deprecated members when the plugin calls them. Importing a supported module does not flag its unused deprecated members. Observations stay in memory, once per plugin and API per Gateway process; they do not add database work.
The Control UI plugin list shows an informational row with the announced retirement date, when available, and a link to the migration guide. Plugin details list the observed APIs and their replacements. The notice does not change plugin health or prevent the plugin from running. Existing plugin inspection, Doctor, status, and setup compatibility reports also include observations made in their process.
This is usage detection, not an exhaustive source audit: unexecuted imports and calls are not reported. After updating a plugin, restart the Gateway to clear previous observations and collect its current usage.
Deprecation policy
OpenClaw should not remove a documented plugin contract in the same release that introduces its replacement. Migration sequence:
- Add the new contract.
- Keep the old behavior wired through a named compatibility adapter.
- Emit diagnostics or warnings when plugin authors can act.
- Document the replacement and timeline.
- Test both old and new paths.
- Wait through the announced migration window.
- Remove only with explicit maintainer approval for a later ordinary stable release.
Deprecated records must include a warning start date, replacement, docs link,
and either a final removal date or an explicitly approved removal gate.
The stable-deprecation-period gate records preparation for removal in a later
ordinary stable release. It does not set a deadline or authorize removal.
Once the owner approves a window, replace that gate with the final compatibility
day in removeAfter. Beta releases do not satisfy the shipped replacement or
deprecation requirement.
Deprecated synchronous SQLite-backed Plugin SDK members remain compatible
through December 31, 2026 (removeAfter: 2026-12-31). Removal ships in the
first January 2027 stable release, without an SDK major. The next stable
release announces this window with actionable warnings and the
complete async migration guide.
This preparation removes no public member. Existing asynchronous APIs, prepared
SQL-free overloads, worker-local SQLite primitives, and explicit offline
maintenance contracts remain supported.
The announced warning-to-removal window should be no more than three months.
That bound is not an automatic expiry: a source annotation, elapsed registry
date, or undated gate cannot substitute for shipped diagnostics, migration
instructions, supported-reader checks, and the announced window. The
removal timeline describes the
additional shipped-surface gate. Other compatibility families retain their own
dates or ordinary stable release gates; the SQLite cutoff does not reschedule
them. Do not add an
open-ended removal window without an approved gate unless maintainers explicitly
decide it is permanent compatibility and mark it active instead.
Current compatibility areas
The July 2026 sweep removed the expired root SDK, manifest, provider, runtime, registry-flag, and plugin-owned web-config aliases. Doctor migrations remain separately tracked so supported upgrade paths can still repair old config.
The remaining dated compatibility areas are:
- the renewed October 1 SDK subpath window listed in the migration guide
- the shipped agent-harness SDK aliases, whose removal is pending a new externally documented migration decision
- the October 2026 SDK annotation families listed below
Active, undated registry records cover supported behavior rather than removal debt, including activation hints, plugin capture, bundled plugin enablement, and the generated channel-config fallback.
The annotation-only compatibility audit added these dated records. Their
removeAfter date is an earliest review date, not permission to remove a
surface while its stated reader or migration condition remains unmet. The ten
October 1 annotation families are now removal-pending, with the original dates
and the per-family removal conditions below preserved in the review queue.
This does not authorize removal or claim a completed published-reader sweep.
| Compatibility code | Removal condition | removeAfter |
|---|---|---|
plugin-sdk-channel-setup-input-fields |
Repeat the published-plugin artifact sweep and remove only fields with no reader. | 2026-10-01 |
plugin-sdk-broad-runtime-barrels |
Move bundled and indexed external consumers to focused SDK subpaths. | 2026-10-01 |
plugin-sdk-provider-owned-helper-shims |
Move each deprecated provider helper to its provider-local API and prove no published reader remains. | 2026-10-01 |
message-presentation-legacy-bridges |
Move reply producers and official channel packages to MessagePresentation. |
2026-10-01 |
plugin-sdk-focused-compat-aliases |
Prove every enumerated alias has no bundled or published reader. | 2026-10-01 |
agent-harness-terminal-result-aliases |
Move harnesses to terminal and visibleReplies, then prove the legacy result fields are unread. |
2026-10-01 |
official-plugin-export-aliases |
Move channel presentation and Discord timeout consumers to primary APIs and clear published readers. | 2026-10-01 |
memory-host-compatibility-aliases |
Verify current memory tables and preserved legacy data before retiring overrides. | 2026-10-01 |
plugin-runtime-api-compat-aliases |
Move flat plugin registration/runtime calls to their namespaced or focused replacements. | 2026-10-01 |
plugin-provider-manifest-compat-aliases |
Move kind/setup/catalog ownership to manifests and model-catalog registration. | 2026-10-01 |
plugin-sdk-session-agent-resolution-aliases |
Move published plugins to strict session-agent resolution with an explicit or prepared owner. | 2026-11-29 |
pnpm plugins:boundary-report reports removal-pending records separately
from deprecated records. A due removal-pending record remains blocked until
its reported migration condition is satisfied and its reader references are
cleared; the existing --fail-on-eligible-compat gate continues to apply only
to dated deprecated records. Reader references are surface-token matches for
triage; use the published-artifact sweep before authorizing removal.
The deprecated sourceVisibleReplies harness field remains supported because
July 2026 releases of @openclaw/codex still produce it. Use
deliveryDefaults.visibleReplies
in new plugins. Terminal-result aliases also remain supported for published
producers, including openclaw-deepseek-harness@0.2.0.
Session-store bridge retirement
The SDK owner approved retiring deprecated-session-store-beta5-api on
September 30, 2026, replacing its former October 12 compatibility deadline.
The supported-plugin cutoff excludes v2026.7.1-beta.5 and any other plugin
release that imports the retired whole-store or transcript-path bridge.
Upgrade those plugins to versions using scoped row operations and
identity-backed transcript APIs before upgrading the host.
The published @openclaw/codex@2026.9.7 and @openclaw/feishu@2026.9.7
packages have migrated off the retired imports. Their 2026.7.1-beta.5
packages still use the bridge; a newer version number alone does not prove
migration for other releases or plugins.
openclaw/plugin-sdk/session-store-runtime and resolveStorePath(...) remain
supported. The removed exports, option types, and package-root aliases are
listed in the session API migration guide.
This retirement changes the supported SDK surface; SQLite storage
and legacy-state import and Doctor migrations remain unchanged.
Synchronous plugin state
plugin-state-sync-keyed-store names the existing synchronous keyed-store adapter.
Its September 11, 2026 deprecation now has the final compatibility day
December 31, 2026. Removal ships in the first January 2027 stable release.
Actual legacy calls emit one diagnostic per plugin and capability family per
Gateway process; module imports remain silent.
Existing synchronous methods, plugin trust eligibility, and transactional callback
semantics remain unchanged. Migrate to data-only openKeyedStoreV2 operations using
the state-store migration guide.
The window also covers V1 update and deleteIf callbacks. Their Promise return
does not move the transaction off the Gateway thread; use V2 observe and
compareAndApply, or a worker operation, instead. Bundled first-party plugins
support the current host and use V2 directly, without older-host fallbacks.
Session agent resolution aliases
New plugins should use resolveSessionAgentIdsStrict or
resolveSessionAgentIdStrict and supply an explicit agent, an agent-scoped
session key, a prepared fallback agent, or a persisted fixed-store owner.
The older resolveSessionAgentIds and resolveSessionAgentId Plugin SDK
exports preserve ambient system-agent fallback only when strict resolution
fails because no owner was supplied. These aliases treat empty or whitespace-only
agent IDs as omitted; strict resolvers reject supplied blank IDs. They do not override explicit,
agent-scoped, persisted, conflicting, or retired owner outcomes. These aliases
are deprecated as of August 29, 2026, and remain available through November 29, 2026. Removal also requires a published-plugin reader sweep and explicit
breaking-release approval.
Auth profile cooldown classifications
AuthProfileStore.usageStats[*].cooldownReason remains the closed
AuthProfileFailureReason union. Host policy records WHAM HTTP 401 as auth
and HTTP 403 as auth_permanent.
cooldownClassification is an optional additive host diagnostic. Its current
values are wham_token_expired and wham_account_dead. Plugins that display
this field must keep a default or fallback for future optional classifications.
Host failover uses resolveProfilesUnavailableReason; the diagnostic is
presentation state only and must never be used as authorization.
Channel prompt-context identifier aliases
New channel plugins should use MsgContext.ChannelPromptContext,
MsgContext.ChannelStructuredContext, ChannelStructuredContextEntry, and
SupplementalContextFacts.channelStructuredContext. The older
UntrustedContext, UntrustedStructuredContext,
UntrustedStructuredContextEntry, and supplemental untrustedContext names
remain as deprecated SDK aliases. Their 2026-09-08 removal review date is
unchanged, but registry record sdk-untrusted-context-identifier-aliases is now
removal-pending: removal still requires verified migration of published plugin
readers and explicit breaking-release approval. Inbound finalization folds those
deprecated fields into the channel-named fields and removes the old keys from
runtime context.
The security runtime similarly exports buildChannelMetadata; the deprecated
buildUntrustedChannelMetadata alias remains available under the same pending
removal conditions.
WhatsApp inbound callback retirement
The August 2026 WhatsApp callback compatibility window is closed. Runtime
callbacks now accept only WebInboundCallbackMessage: nested event,
payload, quote, group, and platform contexts plus the required public
admission envelope. Flat callback fields and top-level admission aliases are
no longer accepted.
payload.channelStructuredContext is extracted from inbound provider payloads.
Plugins should inspect label, source, and type before treating its
payload as authoritative.
Plugin inspector package
The plugin inspector should live outside the core OpenClaw repo as a separate package/repository backed by the versioned compatibility and manifest contracts. The day-one CLI should be:
It should emit manifest/schema validation, the contract compatibility
version being checked, install/source metadata checks, cold-path import
checks, and deprecation/compatibility warnings. Use --json for stable
machine-readable output in CI annotations. OpenClaw core should expose
contracts and fixtures the inspector can consume, but should not publish the
inspector binary from the main openclaw package.
Maintainer acceptance lane
Use Crabbox-backed Blacksmith Testbox for the installable-package acceptance lane when validating the external inspector against OpenClaw plugin packages. Run it from a clean OpenClaw checkout after the package is built:
Keep this lane opt-in for maintainers, since it installs an external npm package and may inspect plugin packages cloned outside the repo. The local repo guards cover the SDK export map, compatibility registry metadata, deprecated SDK-import burn-down, and bundled extension import boundaries; Testbox inspector proof covers the package as external plugin authors consume it.
Release notes
Release notes should include upcoming plugin deprecations with target dates
and links to migration docs, before a compatibility path moves to
removal-pending or removed.