Skip to content

fix: bypass npm freshness for managed installs#83761

Merged
steipete merged 5 commits into
mainfrom
josh/fix-npm-freshness-bypass
May 18, 2026
Merged

fix: bypass npm freshness for managed installs#83761
steipete merged 5 commits into
mainfrom
josh/fix-npm-freshness-bypass

Conversation

@jalehman

@jalehman jalehman commented May 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bypass npm freshness filters for OpenClaw-managed package/plugin installs so freshly published release plugins remain installable.
  • Preserve npm's before/min-release-age exclusivity by choosing --before for existing before policies and --min-release-age=0 for release-age policies.
  • Add npm config path expansion coverage for userconfig values like ~/.npmrc and ${HOME}/.npmrc.

Verification

  • npm 11.14.1 source/docs checked locally: before and min-release-age are mutually exclusive, and min-release-age=0 is the effective release-age bypass.
  • pnpm test src/infra/npm-install-env.test.ts -- --reporter=verbose: 15 tests passed.
  • AUTOREVIEW_AUTO_TESTS=0 .agents/skills/autoreview/scripts/autoreview --mode branch --reviewer codex --fallback-reviewer none: clean, no accepted/actionable findings reported.

Real behavior proof

Behavior addressed: OpenClaw-managed npm installs bypass user npm freshness filters without triggering npm's before/min-release-age conflict.
Real environment tested: macOS local checkout, Node 26.0.0, npm 11.14.1, pnpm 11.1.0.
Exact steps or command run after this patch: pnpm test src/infra/npm-install-env.test.ts -- --reporter=verbose
Evidence after fix: npm-install-env covered before policy, min-release-age policy, project/global/userconfig scanning, and expanded ~/.npmrc/${HOME}/.npmrc userconfig paths.
Observed result after fix: 15 tests passed; npm reports effective min-release-age as 0 for the release-age bypass case.
What was not tested: full release install/update flow against the public npm registry; CI covers the changed lanes before merge.

@openclaw-barnacle openclaw-barnacle Bot added size: M maintainer Maintainer-authored PR labels May 18, 2026
@clawsweeper

clawsweeper Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge.

Workflow note: Future ClawSweeper reviews update this same comment in place.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

Summary
The PR adjusts npm install/update helpers to choose and propagate freshness-bypass config for managed OpenClaw package and plugin installs, adds regression tests, and records a changelog fix.

Reproducibility: yes. from source and the npm 11 contract. npm exits when before and min-release-age are both present, and the PR can route different bypass modes into the same staged global update command.

PR rating
Overall: 🧂 unranked krab
Proof: 🦞 diamond lobster
Patch quality: 🧂 unranked krab
Summary: The proof is strong, but the patch has a blocking compatibility bug in the global update path.

Rank-up moves:

  • Align the env and argv freshness bypass mode for staged global updates.
  • Add focused regression coverage for a stale before config plus staged install prefix.
  • Rerun exact-head npm install/update proof after the fix.
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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.

PR egg
🔥 Warming up: proof, findings, or rank-up moves are still in progress.

       .-.
    .-'   '-.
   /  _   _  \
  |  (_) (_)  |
   \   ___   /
    '.___._.'
What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • How to hatch it: reach status: 👀 ready for maintainer look or status: 🚀 automerge armed; that usually means sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

Real behavior proof
Sufficient (live_output): The PR body includes after-fix local macOS and Docker npm 11 proof for freshness-policy package installs, though it does not cover the staged global update mismatch called out in review.

Risk before merge
Why this matters: - Merging as-is can still break npm global update or staged install for users whose real npm config uses before, because the env can carry npm_config_before while argv adds --min-release-age=0.

  • The changed surface is package-manager install/update compatibility, so exact-head proof should cover both user/global before and min-release-age configs after the scope mismatch is fixed.

Maintainer options:

  1. Align argv and env bypass scope (recommended)
    Fix the global update path so createGlobalInstallEnv and globalInstallArgs derive freshness bypass mode from the same config scope, then add a regression for staged-prefix installs with a real before config.
  2. Accept only with exact-head update proof
    Maintainers could land only after exact-head package-update proof shows stale before and min-release-age configs both succeed through the staged global update path.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Update the PR so global install env and global install argv derive the npm freshness bypass mode from the same config scope, including staged-prefix update installs; add regression coverage that combines a real/global `before` config with a staged install prefix and proves npm does not receive both `before` and `min-release-age`.

Next step before merge
The remaining blocker is a narrow freshness-mode mismatch between global install argv and env that can be repaired with focused tests.

Security
Cleared: The diff changes npm child-process config handling but does not add dependencies, scripts, artifact downloads, secret handling, or new supply-chain execution surfaces beyond the existing managed install path.

Review findings

  • [P1] Keep install args and env freshness mode aligned — src/infra/update-global.ts:796-798
Review details

Best possible solution:

Compute one freshness-bypass mode per npm command/env pair, thread the same config scope through both env and argv, and add staged global-update coverage for real user/global freshness config.

Do we have a high-confidence way to reproduce the issue?

Yes, from source and the npm 11 contract. npm exits when before and min-release-age are both present, and the PR can route different bypass modes into the same staged global update command.

Is this the best way to solve the issue?

No. The fix should compute or carry one scoped bypass decision through both the npm environment and command args instead of recomputing them from different config roots.

Label justifications:

  • P1: This is an urgent install/update regression path for freshly released OpenClaw packages and plugins under common npm freshness policies.
  • merge-risk: 🚨 compatibility: The PR changes npm config handling for existing managed install/update workflows and can still fail existing user setups when env and argv freshness modes diverge.

Full review comments:

  • [P1] Keep install args and env freshness mode aligned — src/infra/update-global.ts:796-798
    This recomputes the npm freshness bypass mode from the temporary install prefix, but the command env still comes from createGlobalInstallEnv() without that scope. When the user's real config has before and the staged prefix has no .npmrc, the env can supply npm_config_before=<now> while argv adds --min-release-age=0; npm 11 rejects that combination before config resolving, so the global update path can still fail under the freshness policy this PR is trying to fix. The fallback args have the same issue.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.88

Acceptance criteria:

  • node scripts/run-vitest.mjs src/infra/npm-install-env.test.ts src/infra/update-global.test.ts src/infra/update-runner.test.ts src/infra/package-update-steps.test.ts
  • Exact-head npm install/update proof for stale before, user min-release-age, project/global min-release-age, project/global before, and parent-env freshness scenarios

What I checked:

  • PR head recomputes argv freshness mode from installPrefix: At the PR head, global npm install args pass npmConfigPrefix: installPrefix into createNpmFreshnessBypassArgs, while createGlobalInstallEnv still calls applyNpmFreshnessBypassEnv(merged) without the same staged-prefix scope. (src/infra/update-global.ts:796, 37c473ac9ecb)
  • Global update combines generated argv with caller env: The package update step builds argv with globalInstallArgs(..., installLocation) and then passes params.env into the same command, so a mode mismatch between argv and env reaches npm as one invocation. (src/infra/package-update-steps.ts:391, d124c5aa2005)
  • npm 11 rejects combined before and min-release-age: npm 11 exits before config resolving when before and min-release-age are both supplied, matching the dependency contract that these config keys are exclusive.
  • npm source marks the configs mutually exclusive: The installed npm 11 source defines before as exclusive with min-release-age and min-release-age as exclusive with before; min-release-age also flattens into before internally. (/opt/hostedtoolcache/node/24.15.0/x64/lib/node_modules/npm/node_modules/@npmcli/config/lib/definitions/definitions.js:245)
  • Current helper provenance: Current main’s npm install env helper and freshness bypass functions trace to commit 1912be8 in the local history. (src/infra/npm-install-env.ts:84, 1912be8619fb)

Likely related people:

  • steipete: History shows repeated recent work across update and plugin install surfaces, including release preparation and global update/plugin install refactors touching the affected files. (role: recent area contributor; confidence: high; commits: 50a2481652b6, b40d4b63f602, 03c6946125eb; files: src/infra/update-global.ts, src/plugins/install.ts, src/infra/package-update-steps.ts)
  • Krzysztof Probola: git blame points the current npm freshness helper and related install/update helper lines to commit 1912be8. (role: introduced current helper; confidence: medium; commits: 1912be8619fb; files: src/infra/npm-install-env.ts, src/infra/update-global.ts, src/plugins/install.ts)
  • vincentkoc: Recent history includes package-manager install support and update hardening in the same update/plugin install area. (role: adjacent update/plugin contributor; confidence: medium; commits: 5a7aba94a2bf, 7f35f7691464, 3ce5a8366a67; files: src/infra/update-global.ts, src/plugins/install.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against d124c5aa2005.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels May 18, 2026
@steipete steipete self-assigned this May 18, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels May 18, 2026
@steipete steipete force-pushed the josh/fix-npm-freshness-bypass branch from 891349a to 84b5731 Compare May 18, 2026 22:22
@steipete steipete merged commit 85a3d53 into main May 18, 2026
99 checks passed
@steipete steipete deleted the josh/fix-npm-freshness-bypass branch May 18, 2026 22:31
@TeodoroRodrigo

Copy link
Copy Markdown
Contributor

Additional stable-runtime validation from 2026.5.18:

I hit a related plugin-update path today on stable 2026.5.18 (50a2481) while updating the global plugins that serve Codex/Discord/WhatsApp turns. This appears to be covered by the later merged follow-up in #83761, but I wanted to leave redacted field evidence here because v2026.5.18 was published before #83761 merged.

Environment, redacted:

  • OpenClaw: 2026.5.18 (50a2481)
  • OS: macOS/Darwin arm64
  • Node: v26.0.0
  • npm: 11.12.1
  • Install shape: package install with global OpenClaw plugins under ~/.openclaw/npm
  • Private usernames, local absolute paths, hostnames, auth profiles, tokens, emails, channel IDs, and account IDs omitted.

Reproduction on stable 2026.5.18:

openclaw plugins update codex --dry-run
openclaw plugins update discord --dry-run

Both failed before registry/package resolution with:

Failed to check codex: npm view failed: Exit prior to config file resolving
cause
--min-release-age cannot be provided when using --before

Failed to check discord: npm view failed: Exit prior to config file resolving
cause
--min-release-age cannot be provided when using --before

The local npm config exposed an effective before cutoff while npm config get min-release-age returned null, which matches the npm 11 behavior discussed in this issue/PR thread.

Control check:

When I reran the dry-run with both user and global npm config isolated to empty temporary npmrc files, the same command got past the config conflict. With network access:

codex is up to date (2026.5.18).

So the local failure was not package availability; it was inherited npm freshness config reaching the managed plugin-update npm view path.

Local workaround used:

I installed the exact plugin versions directly and pinned them:

@openclaw/codex@2026.5.18
@openclaw/discord@2026.5.18
@openclaw/whatsapp@2026.5.18
@openclaw/acpx@2026.5.18
@openclaw/brave-plugin@2026.5.18
@openclaw/diffs@2026.5.18

Post-update validation:

openclaw config validate                         # valid
openclaw plugins doctor                          # no plugin issues
openclaw gateway status --json --require-rpc     # rpc.ok true
openclaw plugins list --json                     # all six plugins loaded/global/enabled at 2026.5.18

Interpretation:

SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 24, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
galiniliev pushed a commit to galiniliev/openclaw that referenced this pull request May 25, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
SebTardif pushed a commit to SebTardif/openclaw that referenced this pull request May 26, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
SYU8384 pushed a commit to SYU8384/openclaw that referenced this pull request Jun 3, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
* fix: bypass npm freshness for managed installs

* test: tolerate npm config json differences

* test: align npm freshness bypass expectation

* fix: resolve npm config path expansions

* test: tolerate npm zero config encoding

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: L status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants