Skip to content

fix(cli): read the scanned package coordinate from its manifest (COD2-1058) - #73

Merged
tonibergholm-codento merged 2 commits into
mainfrom
cod2-1058-scan-coordinate
Sep 5, 2026
Merged

tonibergholm-codento merged 2 commits into
mainfrom
cod2-1058-scan-coordinate

Conversation

@tonibergholm-codento

Copy link
Copy Markdown
Contributor

Summary

sentinel scan derived the package name from the tarball's filename and hardcoded version: "local", even though the real coordinate sits inside the tarball being extracted (package/package.json). Since npm pack writes 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"} reports meta.name: "lodash-4.17.21", not lodash — confirmed by running the CLI directly, not just reasoned about.

  • Add packageCoordinateFromTarball (packages/cli/src/scan-coordinate.ts), which reuses extractTarball (the same extraction runAudit already performs) to read name/version from package/package.json, and refuses rather than guesses when the manifest is missing, duplicated, unparseable, or missing a string name/version.
  • Wire it into the scan command in packages/cli/src/index.ts in place of the filename split.
  • Add packages/cli/test/scan.test.ts and a small packages/cli/test/helpers/make-tarball.ts fixture 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 pass
  • npm test — 1007 tests, 1004 pass, 3 skipped (unchanged skip count), 0 fail
  • npm run typecheck (tsc --build --noEmit false) — clean
  • Confirmed the tests can fail: temporarily restored the old filename-derivation scan code and ran it against a lodash-4.17.21.tgz built from a {name: "lodash", version: "4.17.21"} manifest — it reported meta.name: "lodash-4.17.21". Reverted.

Note: this repo's tests run on node:test + tsx (see CLAUDE.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.

…-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.
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Sentinel dependency audit — WARN · ✓ ok

144 allow · 5 warn · 0 block · 0 error
provenance: 43 verified · 0 invalid · 106 absent · 0 unknown

package verdict score finding how to fix
esbuild@0.28.1 warn 62/100 install.js combines launch + write + read primitives — partial materialization pattern. Review the finding details; approve with a recorded rationale only if you understand and accept the risk.
fast-uri@3.1.5 warn 60/100 Network egress: connects to a hardcoded IP address. Confirm the egress is expected for this package's purpose; if not, remove it or pin to a version without it.
isexe@2.0.0 warn 77/100 test/basic.js combines read + launch + write primitives — partial materialization pattern. Review the finding details; approve with a recorded rationale only if you understand and accept the risk.
tsx@4.22.4 warn 76/100 dist/index-D9F1FXzN.cjs combines read + write primitives — partial materialization pattern. Review the finding details; approve with a recorded rationale only if you understand and accept the risk.
undici-types@7.18.2 warn 64/100 Network egress: imports a raw networking module. Confirm the egress is expected for this package's purpose; if not, remove it or pin to a version without it.

▶ Run sentinel explain <package> <version> for a suggested safe version and a ready waiver.

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.
@tonibergholm-codento
tonibergholm-codento merged commit 5a4d98a into main Sep 5, 2026
6 checks passed
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