Repository navigation
Fix open npm issues - #1008
Fix open npm issues#1008
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On a manifest-less hosted project (the default v5 shape after a bare `scan`), `remove <purl> --preserve-state` routes through `remove_hosted_only`, which restored the pin to upstream but never said so: the "no preservable local state" note existed only on the manifest-backed hosted leg, and neither path put the `hosted_state_not_preservable` code in the JSON envelope's `warnings[]` (only `rollback --preserve-state` did). Share the warning between rollback and remove (`rollback::hosted_state_not_preservable_warning`), and have both remove paths print the `Note:` line in human mode and carry the warning in `--json`. CLI_CONTRACT.md now lists remove as a reporter of the code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
pdm_dir_candidates only reads unix_default on non-macOS Unix, so a macOS build warned about an unused variable, and clippy -D warnings failed on macOS hosts. Widen the existing Windows-only allow(unused_variables) to macOS as well. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
npm >= 8 rewrites the origin of a lock's `resolved` URL to the configured registry when `replace-registry-host` is `always` or equals the URL's hostname. Hosted pins rewritten that way are fetched from `<registry>/patch/npm/...` and every `npm ci` / `npm install` fails E404, yet the hosted scan / get exited 0 with a success summary and no warning (and the "already on hosted patches" re-run stayed silent). socket-patch never read the setting. The npm config layer walk (`resolve_outer_allow_remote`) now also resolves `replace-registry-host` from the env var and the user / global / builtin config files; `effective_replace_registry_host` adds the project `.npmrc` in npm's precedence order and `replace_registry_host_rewrites` matches a pinned host the way @npmcli/arborist does (`always`, or the exact hostname; `npmjs` = registry.npmjs.org). Whenever a root npm lock carries a hosted pin, the engine emits a new `redirect_npm_replace_registry_host` warning naming the layer that sets it and the remedies (`replace-registry-host=npmjs` in the project .npmrc, or vendored mode). The setting is never rewritten and the exit status is unchanged. CLI_CONTRACT.md, docs/ecosystems.md and the npm compatibility suite table describe the new warning. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Closing (burn-down agent): this draft has no changes. Its only commit is an empty placeholder ("Start npm open-issue sweep"), the diff against Generated by Claude Code |
#688) scan_lock_matches returned LockScan::WorkspaceMember as soon as it met any `packages` key outside node_modules/ whose name@version matched the patch, before looking at the other entries. A project with a normal registry install of left-pad@1.3.0 plus an unrelated `file:` directory dependency (or workspace member) whose package.json says left-pad@1.3.0 therefore had the whole package refused with vendor_workspace_member, although the registry copies are fully rewritable (hosted mode already pins them). The namesake local source is now skipped like link / inBundle / non-registry entries, with a vendor_workspace_member_skipped warning naming it, and the refusal fires only when no rewritable instance remains. The same scan feeds sibling-lock wiring and vendor --check's wiring audit, so that audit now also covers the registry copies of such a project instead of skipping the lock entirely. The takeover half of the issue (hosted pin restored before the refusal) was already fixed by #963. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
npm >= 12.1's native `npm patch` records the project's own diff in the
root package.json `patchedDependencies`, adds a `patched: {integrity,
path}` record to the lock entry and writes lockfileVersion 4. Every
install extracts the locked tarball and then applies that diff, failing
EPATCHFAILED when it no longer applies. The hosted npm lock rewriter knew
none of this: it pinned the entry to the hosted tarball, kept the
`patched` record and reported a clean switch, so every later `npm ci` /
`npm install` failed (or, for a non-overlapping diff, installed bytes VEX
can never attest). The vendored backend refused the v4 lock but told the
user to upgrade with npm >= 7, which cannot help.
Hosted: `rewrite_npm_lock` now leaves a dep on its registry entries in
every present npm lock when the root manifest has a `patchedDependencies`
key for `name@version` (or the bare name), or any present lock's matching
`packages` entry carries a non-null `patched` record. It warns
`redirect_npm_patched_dependency_skipped` naming the key or entry and the
remedy, marks the uuid bundled-skipped so the in-run VEX never assumes it,
and records it in a new `refused_npm_uuids` set so the hosted engine never
confirms it from a sibling lock. Other packages in the lock are still
pinned. The entry-identity derivation is factored into
`npm_lock_entry_identity` and shared.
Vendored: the lockfileVersion 4 refusal (same code,
`vendor_lockfile_version_unsupported`) now names `npm patch` /
`patchedDependencies` and the real remedies instead of the npm >= 7
upgrade advice.
CLI_CONTRACT.md and docs/testing/npm-compatibility.md document the new
warning and the v4 refusal.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sues Co-Authored-By: Claude <noreply@anthropic.com>
|
Merged main (03b9418) to clear conflicts; head is now Generated by Claude Code |
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 800fa07. Configure here.
|
[burn-down agent] Labeled Ready for review at
Generated by Claude Code |
#1008 moved the pnpm vendor wiring into an NpmLockBackend impl and the vendor run's closing lines into print_vendor_closing. Re-apply this branch's changes on that structure instead of reverting it: - PnpmBackend::preflight warns vendor_config_dependency_unpatched when the lock's env document also lists the package (#466); - PnpmBackend::wire skips the pnpm-workspace.yaml mirror for a project pinned to pnpm 9.0-10.4 with no workspace file (#734), and writes the env-document prefix back ahead of the project lock (#466); - print_vendor_closing passes whether pnpm-workspace.yaml exists to commit_hint (#734); - engine.rs imports and CLI_CONTRACT.md keep both sides' additions. Co-Authored-By: Claude <noreply@anthropic.com>
…-mode apply.rs: #1008 added mismatch_overwrite_warnings (#1004) inside the block this branch deletes with the diff download path; keep the new function and the deletion. CLI_CONTRACT.md: keep both the "(blob" wording and #1008's agent-mode warnings[] pointer. Co-Authored-By: Claude <noreply@anthropic.com>
engine.rs imports: keep this branch's removal of url_host from the guidance import list and add #1008's NPM_REPLACE_REGISTRY_HOST_CODE. Co-Authored-By: Claude <noreply@anthropic.com>
main (#1008) added Discovery::shadowed for pins withheld over a copy no rewire can reach, and HostedPin::all now includes them so the management commands unwind them. Keep that as is and record the pins withheld over a copy a re-run CAN rewire (an npm: alias, the npm twin lock, another manager's lock, npm 6's legacy mirror, a Bun registry entry) in a separate Discovery::rewirable, which only the rollout's recorded view (HostedPin::recorded) reads. Assisted-by: Claude Code:claude-opus-5-5
Resolve conflicts with #1008, which moved npm-family vendoring into a shared flow: re-apply this PR's bun additions (default-trust warning #371, non-registry tarball warnings and not-rewritable refusal #497, and bun.lockb duplicate-record folding #861) on top of the new backend structure. Co-Authored-By: Claude <noreply@anthropic.com>
Assisted-by: Claude Code:claude-opus-5-5
Fixes every open
pm:npmissue except #933, which #934 already fixed on main. Each fix was written in its own worktree with a regression test, reviewed by a second agent, then cherry-picked here. The three refactors were done after the bug fixes, and the branch is merged with current main.Bug fixes
failed. It no longer prints "Vendored N packages" or "Next steps". A non-pendingvendor_commit_failedgets the same treatment.eject_rolled_backgoes to stderr, and the rolled-back packages are re-taggedskipped, with JSON summary counts kept in step.scan --jsonandget --jsonnow includecontent_mismatch_overwritteninwarnings[]. The nested apply passes it up through a newApplyRunReport.warnings.allow-filesetting from env, project, user, global and builtin config, and applies npm's rule for which packages count as root. When npm would refuse the vendoredfile:wiring, scan warnsvendor_npm_allow_fileandvendor --checkfails.vendor_prebuilt_pendingorvendor_prebuilt_unavailablewarning, while the superseding patch is pending_build, build_failed or not_found. It no longer exits 1.npm-shrinkwrap.json, scans warnredirect_npm_shrinkwrap_only(hosted) orvendor_npm_shrinkwrap_only(vendored). VEX does not attest from that file alone (vex_npm_shrinkwrap_only).dependenciesmirror entry with noresolvedbut the patched integrity no longer counts against the wiredpackagesentry.vexandvendor --checkpass again after npm 7–10 re-saves the lock.Discovery::shadowedlist. VEX still doesn't attest it, but rollback, remove, list and the vendored takeover can now find and undo it.replace-registry-host. Hosted scan and get warn when npm would rewrite the hosted pin to the registry and fail with E404.hasShrinkwrapdependency are not rewritten. Hosted warnsredirect_npm_shrinkwrapped_instance_skipped,vendor --checkfails on such a copy, and VEX does not attest it.patchedDependencies(npm patch) already patches stay on the registry, with a warning. When such a package is already pinned, the message names the rollback.file:dir or workspace member with the same name@version no longer makes vendored refuse the registry copies. It is skipped with avendor_workspace_member_skippedwarning.socket.ymlinclude/ignore paths and the built-in test defaults.remove --preserve-statepaths now print thehosted_state_not_preservablenote and add the code to JSONwarnings[].Performance (#993)
The regression is real. Measured as instructions retired on the bench's 3000-package npm fixture:
2463257a)JSON output is byte-identical across all three. The hosted path no longer runs extra lockfile discoveries when the vendor ledger has no entries, and it parses each npm lock once.
Refactors
npm_lock_entries, now serves inventory, vendored, hosted and restore.VendorEntry::npmandVendorArtifact::{tarball,dir}constructors.NpmLockBackendtrait and a genericvendor_npm_familydriver.vex_consumedis deleted.Known residuals
vexdoes not yet considerallow-file(Vendored npm scan wires file: tarballs that npm ≥ 11.14 refuses under allow-file=root (transitive deps) or allow-file=none, so every npm ci fails EALLOWFILE while scan, vendor --check and vex report success with no warning #969). The issue asked only for the scan warning, thevendor --checkfailure and the doc fix.mode_migration_npm::berry_vendored_then_hosted_takeover_leaves_pure_hostedfails on main too. It is not caused by this branch.Testing
Ran locally:
cargo test --locked --workspace: 11451 passed. 3 failed, none caused by this branch:cargo clippy --workspace --all-features -D warnings: clean.Fixes #1005
Fixes #1004
Fixes #993
Fixes #969
Fixes #954
Fixes #922
Fixes #899
Fixes #898
Fixes #879
Fixes #856
Fixes #828
Fixes #812
Fixes #753
Fixes #711
Fixes #688
Fixes #663
Fixes #554
Fixes #433
Part of #920
🤖 Generated with Claude Code
Note
Medium Risk
Changes lockfile discovery, vendoring commits, and attestation rules across npm installs; behavior is mostly fail-closed with new warnings, but mistakes could affect rollback/VEX correctness on contested or shrinkwrap-only projects.
Overview
This PR tightens npm-family behavior across hosted redirect, vendored wiring, VEX, rollback/remove, and agent scans, and documents the contracts in
CLI_CONTRACT.md.Hosted / lockfile edge cases: Skips or warns when npm's own
patchedDependencies(#711), nestedhasShrinkwrapinstalls (#753), shrinkwrap-only locks (#899), orreplace-registry-hostwould break hosted pins (#812). Contested pins beside bundled/unreachable copies are tracked so lifecycle commands can still unwind them even when VEX won't attest (#828).Vendored mode: Honors npm
allow-filewithvendor_npm_allow_file/--checkfailures (#969); keeps the old vendored patch when a superseding prebuild isn't ready (#954); skips workspacefile:members with a warning (#688); on failed group commits, tears down artifact dirs and reports packages asfailedinstead of success text (#898).Agent / policy: Nested lockfile roots respect
socket.ymlpath policy (#554) withpolicy_shared_copy; agentget/scan --jsonnow surfaces applycontent_mismatch_overwritteninwarnings[](#1004). Eject rollback messaging and per-packageskippedtagging are aligned (#1005, #433).Internals: Shared
npm_lock_entriesparsing and npm-family vendor refactors (#663, #920, #922); hosted scan perf work (#993); VEX npm alias resolution consolidated (#856).Reviewed by Cursor Bugbot for commit 800fa07. Configure here.
Generated by Claude Code