Repository navigation
Warn when deno.lock keeps installing an npm package (#406) - #1711
Mikola Lysenko (mikolalysenko) wants to merge 4 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
In a Deno project that also keeps an npm-family lock, `deno install` installs the npm dependencies from deno.lock and never reads the lock socket-patch rewires. Hosted and vendored runs reported a clean success anyway, so Deno users believed the dependency was patched while Deno kept installing the registry copy. Hosted scans now warn `redirect_npm_deno_lock` and vendored runs `vendor_npm_deno_lock` when deno.lock locks the same name@version, naming the agent-mode remedy. The deno.lock npm-section reader is shared with VEX discovery, which already omits such pins. Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Claude Code:claude-opus-5-5
The in-memory engine (hosted bundle, Node addon) never fetched deno.lock, so it could not warn about it. Fetch it as an advisory file. Read a deno.lock without a `version` key the same way VEX discovery does, so the warning names exactly the pins `vex` leaves out. Reword the warning so it is also accurate for vlt and shrinkwrap-only projects. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review 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 c300a1f. Configure here.
|
Labeled Ready for review by the burn-down agent.
Generated by Claude Code |
|
Final review brief (for the human approver) What it does. In a project that has both Risk: low. The change is additive and only produces warnings. The new code is an advisory read: an unreadable or non-JSON Look here
Verified
Changes I made. None. Open questions. None. Auto-merge is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #406
Summary
In a Deno project that also commits an npm-family lock (package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml, yarn.lock, bun.lock, vlt-lock.json),
deno installinstalls the npm dependencies fromdeno.lockand never reads the lock socket-patch rewires. Hosted and vendored runs used to report a clean success with no warning, so Deno users thought the package was patched while Deno kept installing the registry copy.Now:
scan --mode hosted/get --mode hostedwarnredirect_npm_deno_lockonce, naming every redirected npmname@versionthat the rootdeno.lockalso locks. This covers this run's pins and earlier runs' pins, and repeats on the idempotent re-run.deno.lockis never written.vendor/scan --mode vendoredwarnvendor_npm_deno_lockfor every npm lockfile flavor, including the in-sync re-run.deno install, thensocket-patch scan --mode agent).deno.lockas an advisory file, so both the warning and the VEX omission work there too.Root cause
The VEX half of #406 was already on
main:vex/discover/deno.rsreadsdeno.lock's npm section andvexomits such pins (vex_deno_lock_copy). The writers never looked atdeno.lock, though. The hosted engine doesn't even pass it to the rewriters, and the npm vendored router didn't check it. So the run's success summary contradicted whatvexwould say.Changes
crawlers/deno_crawler.rs:lock_npm_packages/lock_text_npm_packagesis now the one reader ofdeno.lock's npm keys (lockfile v2–v5, Deno peer suffix dropped). It is shared by VEX discovery and both warnings, so they agree on which pins count, including a lock with noversionkey.hosted/engine.rs:npm_deno_lockchecks the confirmed npm pins againstdeno.lockand adds the warning tonpm_warnings.vendor/npm_flavor.rs:vendor_npm_anywarns after any flavor's successful vendor.patch/redirect/mod.rs: sharednpm_deno_lock_detailand theDENO_LOCKconstant.hosted/memory/select.rs:deno.lockis added to the advisory text files.Test evidence
Red → green: with the two warning call sites disabled, both new core tests fail (
issue_406_a_deno_lock_of_the_redirected_version_is_saidpanics at engine.rs:4206,a_deno_lock_of_the_vendored_version_is_saidat npm_flavor.rs:1893). With the fix they pass.hosted::engine::tests::issue_406_a_deno_lock_of_the_redirected_version_is_said--vexomits (vex_deno_lock_copy,no_applicable_patches); another version attestsscansuitehosted_failure_paths::deno_lock_of_the_redirected_version_warns_and_vex_omits_itvendor::npm_flavor::tests::a_deno_lock_of_the_vendored_version_is_saidvex::discover::deno::tests::deno_npm_keys_cover_every_lock_versionhosted::memory::select::tests::selects_root_candidates_onlyLocal runs (container is root):
cargo fmt --all -- --checkandcargo clippy --workspace --all-features -- -D warnings: clean.cargo test -p socket-patch-core --all-features --lib: 6727 passed, 4 failed. The 4 are permission tests that chmod a directory 0555 and expect a write to fail, which can't happen as root (copy_tree::relax_loop_must_not_traverse_symlinked_root,vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry,pypi_poetry::wire_write_failure_maps_error_and_leaves_lock_untouched,pypi_requirements::wire_failure_rolls_back_already_written_files). All are in files this PR doesn't touch, and CI runs them as non-root.cargo test -p socket-patch-cli --all-features --test scan(246 ok),--test hosted_memory_engine(48 ok),--test in_process_vendor(144 ok).cargo test --workspace --all-featuresran out of the container's disk while linking every test binary, so the PR CI run is the full-suite record.Review notes (
/code-review high)Fixed: the in-memory selector didn't fetch
deno.lock; the warning reader requiredversionwhere discovery didn't; the wording was wrong for vlt and shrinkwrap-only projects;npm_deno_lockwas simplified. Not changed, with reasons:DenoLockmarks. The warning and discovery already share one reader (lock_npm_packages), so they can't drift on parsing. Wiring the warning through the attribution-gate discovery would couplenpm_warningsto an optional, origin-dependent value (final_discoveryisNonein several paths).allow_file_refusal/allow_scripts_lostre-read.npmrc/package.jsonper package. Not worth the extra plumbing.No wrapper changes are needed: the npm/pypi/gem wrappers only dispatch to the binary.
https://claude.ai/code/session_01RLbCDwFEoz96G2kBAq53Fk
Generated by Claude Code