Skip to content

feat(cli): make the lockfile prune resilient to slow registries [RED-930] [ship] - #1471

Merged
sorccu merged 3 commits into
mainfrom
simo/red-930-pnpm-prune-prefer-offline
Sep 4, 2026
Merged

feat(cli): make the lockfile prune resilient to slow registries [RED-930] [ship]#1471
sorccu merged 3 commits into
mainfrom
simo/red-930-pnpm-prune-prefer-offline

Conversation

@sorccu

@sorccu sorccu commented Sep 4, 2026

Copy link
Copy Markdown
Member

Linear: RED-930

The lockfile pruner runs the package manager's lockfile-only install against manifests that deliberately differ from the lockfile, so pnpm re-resolves and needs registry metadata for anything it cannot serve from the store. On pnpm 10, range and catalog specs and optional dependencies are re-fetched on every prune unless prefer-offline is set. Behind a slow or intercepting proxy a single stalled request exceeds the 30 s prune budget, the pruner falls back to shipping the original lockfile next to faux manifests, and the runner install fails with ERR_PNPM_OUTDATED_LOCKFILE.

Changes

  • --prefer-offline on the pnpm and npm lockfile-only commands. pnpm and npm then use cached metadata for any spec type and only contact the registry for misses. The soft flag is deliberate: a cold cache is a legitimate first-prune state, and --offline would turn it into a guaranteed fallback. A stale cache can only change a fresh resolution, which the pruner's subset verification rejects, so the worst case stays a fallback. Verified on pnpm 10.33.4 and 11.22.0 that the flag is not recorded in the lockfile's settings section. Yarn and bun are unchanged.
  • Partial child output on timeout. A timed-out prune now logs the redacted tail (8 KB) of the child's stdout and stderr on the checkly:cli:services:check-parser:lockfile-pruner debug channel, for both the yarn version probe and the install. Redaction reuses the existing by-construction redactUrl (every URL collapses to scheme and host), and the user-facing failure reason now shares that redaction.
  • CHECKLY_LOCKFILE_PRUNE_TIMEOUT. Overrides the hardcoded 30 s budget, in whole seconds (0 disables the timeout). Unusable values are ignored and noted on the debug channel. The timeout failure reasons name the variable, so the bundler's fallback warning shows the remedy.

Other changes

  • The --config. comment in PNpmDetector.lockfileOnlyInstallCommand() claimed the pruner compares the lockfile settings section. It does not; the comment now states the actual hazard (a recorded setting ships to the runner unchecked).
  • captureStderr moved from materializer.spec.ts to src/testing/capture-stderr.ts so both specs share it.

🤖 Generated with Claude Code

sorccu and others added 3 commits September 4, 2026 19:59
The lockfile pruner regenerates the lockfile against manifests that
deliberately differ from it, so pnpm never takes its resolution-skipped
fast path and needs registry metadata for anything it cannot serve from
the store. Without the flag, range and catalog specs and optional
dependencies are re-fetched on every prune; behind a slow or intercepting
proxy one stalled request exceeds the prune budget and the fallback ships
a stale lockfile that fails on the runner.

With --prefer-offline, pnpm and npm use cached metadata for any spec type
and only contact the registry for misses. A stale cache can only change a
fresh resolution, which the pruner's subset verification rejects, so the
worst case remains a fallback. Verified on pnpm 10 and 11 that the flag
is not recorded in the lockfile's settings section.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…out [RED-930]

When the lockfile prune's package manager child timed out, its output was
discarded, which made a stalled registry request impossible to diagnose.
The redacted tail of the child's stdout and stderr is now logged on the
pruner's debug channel for both the yarn version probe and the install.

Redaction follows the by-construction rule already used for embedded
packages, collapsing every URL to scheme and host via redactUrl, since
registry tokens travel in userinfo, query strings and path segments
alike. The user-facing failure reason shares the same redaction.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e prune timeout [RED-930]

The lockfile prune's 30 s budget was hardcoded, so a machine with a cold
metadata cache behind a slow registry had no way to let the prune finish
short of disabling pruning altogether. The variable takes whole seconds
(0 disables the timeout); unusable values are ignored and noted on the
debug channel. The timeout failure reasons now name the variable, so the
bundler's fallback warning shows the remedy where the timeout is reported.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@sorccu
sorccu force-pushed the simo/red-930-pnpm-prune-prefer-offline branch from 4673f83 to b9e0c97 Compare September 4, 2026 10:59
@sorccu sorccu changed the title feat(cli): make the lockfile prune resilient to slow registries [RED-930] feat(cli): make the lockfile prune resilient to slow registries [RED-930] [ship] Sep 4, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved: ship/show PR from a same-repo branch.

@sorccu
sorccu merged commit 6a91c65 into main Sep 4, 2026
17 checks passed
@sorccu
sorccu deleted the simo/red-930-pnpm-prune-prefer-offline branch September 4, 2026 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant