fix(update): fail closed on managed plugin pin conflicts#87304
fix(update): fail closed on managed plugin pin conflicts#87304luoyanglang wants to merge 2 commits into
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 5, 2026, 5:52 AM ET / 09:52 UTC. Summary PR surface: Source +48, Tests +436. Total +484 across 4 files. Reproducibility: yes. from source inspection: current main writes the requested managed dependency spec during update without a preceding newer-pin conflict check, and the PR body includes after-fix real behavior proof for the same shape. I did not run a live update scenario because this review is read-only. 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:
Next step before merge
Security Review detailsBest possible solution: Land the fail-closed guard if maintainers accept that non-interactive updates must stop on newer managed direct pins, and treat any interactive chooser or explicit override path as a separate follow-up. Do we have a high-confidence way to reproduce the issue? Yes from source inspection: current main writes the requested managed dependency spec during update without a preceding newer-pin conflict check, and the PR body includes after-fix real behavior proof for the same shape. I did not run a live update scenario because this review is read-only. Is this the best way to solve the issue? Yes, if the maintainer policy is fail-closed: the check sits in the shared managed npm install path before dry-run and install mutation, which is the narrow owner boundary for this bug. The alternative is an explicit chooser or override path, but that is a product decision rather than a necessary repair in this PR. AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 1a3ce7c2a8da. Label changesLabel justifications:
Evidence reviewedPR surface: Source +48, Tests +436. Total +484 across 4 files. View PR surface stats
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: 🥚 common Clockwork Signal Puff Hatch commandComment Hatchability rules:
Rarity: 🥚 common. What is this egg doing here?
|
|
Addressed the ClawSweeper P2 finding in head 965efbc. The preserved-newer-pin path now re-resolves metadata for the preserved spec when lockfile metadata is missing, so version/integrity/shasum stay aligned instead of carrying stale 0.10.0 metadata into a 0.11.2 install target. Added regression coverage for an existing 0.11.2 managed root pin with missing lockfile metadata, plus current-head mutating managed npm root proof using real npm registry versions for @martian-engineering/lossless-claw 0.10.0 -> 0.11.2. The PR body now includes the redacted proof output. Local validation passed:
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Updated the Real behavior proof section with the required structured fields (behavior, environment, steps, evidence, observedResult, notTested) while preserving the source-level and mutating managed npm root evidence. @clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
|
Adjusted the Real behavior proof to match scripts/github/real-behavior-proof-policy.mjs exactly: one Real behavior proof section with recognized field lines (Behavior or issue addressed, Real environment tested, Exact steps or command run after this patch, Evidence after fix, Observed result after fix, What was not tested). @clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
|
Addressed the latest P2 finding in head 88b1b9f. The preserved-newer-pin path now fails closed if preserved-version npm metadata cannot be resolved, and it only reuses an installed preserved dependency directly when lock metadata includes integrity; otherwise it uses the normal npm install + integrity verification path. Added a regression covering metadata lookup failure with zero npm install calls, reran focused tests, check-changed, and current-head mutating managed npm root proof. @clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
88b1b9f to
5bfdb85
Compare
|
Rebased onto current origin/main (20eab65) and refreshed the current-head managed npm root proof for head 5bfdb85. Targeted plugin and infra tests still pass. One CI guard is currently failing on the upstream shrinkwrap baseline (lru-cache@11.5.1 absent from pnpm-lock.yaml), which reproduces locally via node scripts/generate-npm-shrinkwrap.mjs --all --check and is unrelated to this PR's files. @clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
|
Addressed the ClawSweeper P2 dry-run parity finding in head Change summary:
Verification:
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
796a462 to
cb7aa70
Compare
cb7aa70 to
562a86c
Compare
f7f4fd5 to
c3a909d
Compare
|
@clawsweeper re-review Rebased this PR onto current New head: Conflict/CI notes:
Local validation passed: |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review Refreshed the Real behavior proof for current head Proof rerun summary:
Validation rerun on this head:
|
|
🦞👀 Command router queued. I will update this comment with the next step. Re-review progress:
|
|
@clawsweeper re-review Resolved the current New head: Conflict resolution summary:
Refreshed real behavior proof for the new head:
Validation on the new head:
|
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
openclaw updatecould silently downgrade a user-pinned managed plugin direct dependency. After the maintainer policy note, this PR now implements the conflict/fail-closed behavior instead of preserving the newer pin automatically.Fixes #85184.
Affected surface
src/plugins/install.tsinstallPluginFromManagedNpmRootsrc/infra/npm-managed-root.tsupsertManagedNpmRootDependencysrc/plugins/install.npm-spec.test.tssrc/infra/npm-managed-root.test.tsScope
npm install, including the case where the package payload is missing andresolveEffectiveInstallMode()would otherwise fall back from update to install.Real behavior proof
5f1d39b844b2dbcc03ebbe84bca6ba8599347d82, real OpenClaw source imported withnode --import tsx, real npm metadata lookup for@martian-engineering/lossless-claw@0.11.2, temporary managed npm root outside the repository.package.jsonpinning@martian-engineering/lossless-clawto0.11.3; runinstallPluginFromNpmSpec(..., { spec: "@martian-engineering/lossless-claw@0.11.2", mode: "update" }); verify the result fails closed, the package.json pin remains0.11.3, and no npm install artifacts are created. This refresh uses0.11.2/0.11.3because the older proof spec0.10.0is now rejected earlier by the current runtime plugin API compatibility check, before this managed-root policy branch.{ "proof": "openclaw-pr87304-managed-root-policy", "head": "5f1d39b844b2dbcc03ebbe84bca6ba8599347d82", "packageName": "@martian-engineering/lossless-claw", "requestedUpdateSpec": "@martian-engineering/lossless-claw@0.11.2", "existingPackageJsonPin": "0.11.3", "result": { "ok": false, "error": "Managed plugin dependency conflict for @martian-engineering/lossless-claw: current package.json pin is 0.11.3 but OpenClaw release target is 0.11.2. Non-interactive update is refusing to choose automatically. Use the release-managed version, keep the user pin explicitly, or abort." }, "finalPackageJsonPin": "0.11.3", "npmInstallArtifacts": { "packageLockExists": false, "nodeModulesExists": false }, "npmInstallRan": false, "tempRootKind": "mktemp /tmp/openclaw-pr87304-policy-proof-*" }Local validation after the current-main merge conflict resolution:
Coverage note
This remains the open PR for #85184. Codegraph-reported overlap with #86122, #87477, and #87573 is in the shared plugin install/update functions; the policy behavior above should remain the compatibility point for those edits.