fix(cli): read the scanned package coordinate from its manifest (COD2-1058) - #73
Merged
Merged
Conversation
…-1058) `sentinel scan` derived the package name from the tarball's filename and hardcoded version: "local", even though the real manifest sits right inside the tarball being extracted. npm pack names tarballs <name>-<version>.tgz, so the derived "name" carried the version and could essentially never match a real package name in typosquat detection, policy.deny, or waiver matching. Add packageCoordinateFromTarball, which reuses runAudit's existing extraction to read name/version from package/package.json and refuses a tarball whose manifest is missing or malformed instead of guessing. Wire it into the scan command in place of the filename split.
Sentinel dependency audit — WARN · ✓ ok144 allow · 5 warn · 0 block · 0 error
▶ Run Sentinel · 149 packages audited · 2026-09-05T05:45:22.801Z · SBOM uploaded as a build artifact |
runAudit's requirePackageManifest branch and the CLI's new scan coordinate reader each located package/package.json, rejected duplicate or missing entries, parsed JSON, and validated name/version — independently, and the two copies had already drifted on error wording (a combined "requires string name and version" versus two separate "declares no name"/"declares no version" messages). Factor the shared read into readPackageManifest(extracted), exported from @git-agentic/sentinel-core. runAudit now calls it and layers its own publish-target identity check on top; scan-coordinate.ts calls it directly. Kept the more specific per-field wording (declares no name / declares no version) since nothing asserts on the old combined message. Add packages/core/test/manifest.test.ts covering the two paths that had no coverage before (duplicate manifest entries, invalid JSON) alongside the existing missing-manifest and missing-name/version cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sentinel scanderived the package name from the tarball's filename and hardcodedversion: "local", even though the real coordinate sits inside the tarball being extracted (package/package.json). Sincenpm packwrites tarballs as<name>-<version>.tgz, the derived name carried the version suffix and could essentially never match a real package name — so typosquat detection,policy.deny, waiver matching, and the exit code were all keyed on a value that was close to inert. The first test added here reproduces that: with the old filename-derivation code temporarily restored, scanning a tarball built from{name: "lodash", version: "4.17.21"}reportsmeta.name: "lodash-4.17.21", notlodash— confirmed by running the CLI directly, not just reasoned about.packageCoordinateFromTarball(packages/cli/src/scan-coordinate.ts), which reusesextractTarball(the same extractionrunAuditalready performs) to readname/versionfrompackage/package.json, and refuses rather than guesses when the manifest is missing, duplicated, unparseable, or missing a string name/version.scancommand inpackages/cli/src/index.tsin place of the filename split.packages/cli/test/scan.test.tsand a smallpackages/cli/test/helpers/make-tarball.tsfixture builder (no existing helper in this repo builds a tarball with an overridable manifest).Test plan
node --import tsx --test packages/cli/test/scan.test.ts— both new cases passnpm test— 1007 tests, 1004 pass, 3 skipped (unchanged skip count), 0 failnpm run typecheck(tsc --build --noEmit false) — cleanscancode and ran it against alodash-4.17.21.tgzbuilt from a{name: "lodash", version: "4.17.21"}manifest — it reportedmeta.name: "lodash-4.17.21". Reverted.Note: this repo's tests run on
node:test+tsx(seeCLAUDE.md/package.json), not vitest — vitest is not a dependency here, so the test file and gate commands above use the repo's actual toolchain rather than vitest.