fix(plugins): reject incompatible package plugin API installs#87477
Conversation
|
Codex review: needs changes before merge. Reviewed May 28, 2026, 3:11 PM ET / 19:11 UTC. Summary PR surface: Source +227, Tests +454, Docs +18. Total +699 across 17 files. Reproducibility: yes. by source and supplied proof: current main only enforces Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Land the compatibility gate only after clearing stale fallback metadata, keeping the documented package contract/tests aligned, and having maintainers explicitly accept the fail-closed behavior while compatible-version selection remains future work. Do we have a high-confidence way to reproduce the issue? Yes, by source and supplied proof: current main only enforces Is this the best way to solve the issue? No, not yet. The package API contract is a narrow maintainable first step, but the stale fallback metadata defect needs a focused fix and maintainers still need to accept the fail-closed rollout before compatible-version selection exists. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against a0fcb9167012. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +227, Tests +454, Docs +18. Total +699 across 17 files. View PR surface stats
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
ClawSweeper PR egg: ✨ hatched 🌱 uncommon Frosted Patch Peep. Rarity: 🌱 uncommon. Trait: collects tiny proofs. DetailsShare on X: post this hatch
About:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 43ddf3c809
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const OPENCLAW_CALVER_STABLE_CORRECTION_PATTERN = | ||
| /^[vV]?(\d{4}\.\d{1,2}\.\d{1,2})(?:-\d+|-(?:alpha|beta|rc)\.\d+)$/i; |
There was a problem hiding this comment.
Preserve prerelease floors in plugin API checks
When a package declares a prerelease API floor, e.g. the documented openclaw.compat.pluginApi: ">=2026.3.24-beta.2" in docs/plugins/building-plugins.md:69, this pattern now normalizes a 2026.3.24-beta.1 host to stable 2026.3.24 before range comparison. That makes satisfiesPluginApiRange("2026.3.24-beta.1", ">=2026.3.24-beta.2") pass even though the host predates the required SDK/API cut, so the new install-time guard can still persist plugins on older prerelease runtimes that may be missing the required API.
Useful? React with 👍 / 👎.
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
a182df6 to
f4e47f9
Compare
a71361c to
ddb9458
Compare
…aw#87477) * fix(plugins): enforce package plugin API compatibility * fix(plugins): preserve plugin API prerelease floors * fix(plugins): gate persisted plugin api compatibility * fix(plugins): skip incompatible package discovery * fix(plugins): check api compatibility before package shape * fix(plugins): gate bundle package api compatibility * docs(plugins): clarify plugin API release sync * test(agents): keep dynamic live model unit test runtime-free * fix(plugins): normalize correction plugin api floors * test(agents): align dynamic normalizer expectation * fix(plugins): reject malformed plugin api metadata --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(plugins): enforce package plugin API compatibility * fix(plugins): preserve plugin API prerelease floors * fix(plugins): gate persisted plugin api compatibility * fix(plugins): skip incompatible package discovery * fix(plugins): check api compatibility before package shape * fix(plugins): gate bundle package api compatibility * docs(plugins): clarify plugin API release sync * test(agents): keep dynamic live model unit test runtime-free * fix(plugins): normalize correction plugin api floors * test(agents): align dynamic normalizer expectation * fix(plugins): reject malformed plugin api metadata --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary
package.json#openclaw.compat.pluginApirequires a newer OpenClaw runtime than the current hostopenclaw.compat.pluginApipackage metadata instead of treating it as absentopenclaw.compat.pluginApino longer matches the current hostbeta.1does not satisfy abeta.2plugin API requirementopenclaw.compat.pluginApias the OpenClaw-owned install compatibility contract and release-sync processFixes #85869
Compatibility model
This PR uses
openclaw.compat.pluginApias the contract that answers whether a given OpenClaw runtime can safely install and load a plugin package. The host exposes a compatibility API version, and the plugin package declares the supported range. If the range does not include the host version, OpenClaw now fails before install mutation, dependency linking, package copying, or later runtime load.This is intentionally separate from package version equality. OpenClaw and official plugins usually share CalVer release numbers, but version numbers alone are not enough: a plugin can be newer than the installed host, prerelease floors need exact SemVer-style ordering, and package metadata is the place where the plugin can say which OpenClaw plugin API it needs.
openclaw.install.minHostVersionremains a separate install UX floor, whilepeerDependencies.openclawremains npm metadata and is not the OpenClaw install blocker.Malformed present
openclaw.compat.pluginApimetadata now fails closed. A missing field means no package API floor; a present non-string or empty value is invalid package metadata and is rejected/skipped at install, discovery, and manifest-registry load boundaries.Selection behavior
This PR does not yet implement best-compatible plugin version selection. For an npm spec such as
npm:@openclaw/whatsapp, the resolver can still pick the registry's latest package; this patch makes that resolved package fail closed if itsopenclaw.compat.pluginApiis too new. That is the safe first step because it prevents older hosts from persisting a package that will crash later during plugin load.The follow-up that makes most sense is a compatibility-aware resolver:
openclaw.compat.pluginApimetadata.openclaw.build.openclawVersioncan remain provenance/debug metadata, not the primary compatibility contract.Release sync
The docs now describe the existing release-sync process:
plugins:syncupdates official plugin package versions and bumps existingopenclaw.compat.pluginApifloors to the OpenClaw release version by default. Plugin-only releases can intentionally keep a lower API floor when the package still supports older OpenClaw hosts, but that lower floor needs explicit proof. This avoids a separate release process while making the compatibility contract explicit.Real behavior proof
Behavior addressed: Direct package installs, npm package installs, bundle package installs, persisted external discovery, and manifest-registry load now fail closed when package plugin API metadata is incompatible or malformed.
Real environment tested: Local source checkout on macOS, Blacksmith Testbox-through-Crabbox Linux proof, and AWS Crabbox Linux live proof against the real npm registry.
Exact steps or command run after this patch:
Evidence after fix: AWS Crabbox run
run_e0c2d1ab3025downloaded the current@openclaw/whatsapp@2026.5.27package from npm and rejected it on the older host before persistence:Focused regression proof passed locally: plugin install/discovery/registry/clawhub tests passed with 313 tests across 6 files,
install.npm-specpassed 39 tests, core tsgo passed, docs checks passed, and final autoreview reported no accepted/actionable findings. Blacksmith Testbox-through-Crabbox prooftbx_01ksqz9p7n2s8g06f4s21c87r9verified the Linux Node 24.16 plugin SDK guard test after the main rebase.Observed result after fix: Older hosts now get an actionable compatibility error instead of persisting a package that can fail later during plugin load. Incompatible npm updates leave an existing package directory and managed-root dependency unchanged, persisted non-bundled plugins with incompatible or malformed package API metadata are skipped before package entry validation, and bundle-style package installs with future
openclaw.compat.pluginApimetadata fail before copying.What was not tested: A clean same-floor live registry install was not claimed; same-floor acceptance is covered by fixture proof. The full test suite was not run.
User-visible behavior
Operators get a clear install-time compatibility error that suggests upgrading OpenClaw or installing a compatible plugin version. Existing persisted plugins with incompatible or malformed package API metadata are skipped at load instead of failing later inside runtime code.