← NPMScanCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to NPMScan
Snapshot Sep 30, 2026 · 22:58 UTC · version 2.0.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "package-trust-check",
"description": "Investigate whether one specific npm package is trustworthy — maintainer/ownership takeover signals, publish-provenance mismatches, and risky install scripts. Use when the user asks if a single named package is safe, compromised, hijacked, suspicious, or \"can I trust this\" — not for auditing a full package.json/lockfile (see dependency-audit) and not for a plain factual question like \"what does X do.\"",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 270
},
{
"relative_path": "references/test-prompts.md",
"size_in_bytes": 6156
}
],
"skill_md_contents": "---\nname: package-trust-check\ndescription: Investigate whether one specific npm package is trustworthy — maintainer/ownership takeover signals, publish-provenance mismatches, and risky install scripts. Use when the user asks if a single named package is safe, compromised, hijacked, suspicious, or \"can I trust this\" — not for auditing a full package.json/lockfile (see dependency-audit) and not for a plain factual question like \"what does X do.\"\n---\n\n# Package trust check\n\nUse this skill when the user names **one specific package** (optionally a\nversion) and asks a trust question about it — \"is X safe to use,\" \"was X\ncompromised,\" \"should I be worried about X,\" \"check X's maintainers.\" This\nis a deep, single-package investigation: it runs checks dependency-audit\ndeliberately skips for every package in a batch because they're too\nexpensive to run at scale.\n\nIf the user instead pastes a `package.json`/lockfile/dependency list or asks\nto audit multiple packages, use the `dependency-audit` skill instead — don't\nrun this skill's checks across a whole inventory. If the question is purely\nfactual with no trust/safety angle (\"what does lodash do,\" \"what's the\nlatest version of express\"), just answer directly with `get_package` — don't\ninvoke the full investigation for that.\n\n## Steps\n\n1. Baseline with `get_package` (or `get_package_version` if the user gave an\n exact version). Pull `deprecated`, `maintenanceSummary`,\n `possibleTyposquatOf`, `isLatestVersionVulnerable`/`highestSeverity`,\n `downloadTrend`, and days-since-last-publish. This alone answers a good\n chunk of \"should I trust this\" and grounds the deeper checks that follow —\n don't skip straight to the maintainer/provenance tools without it.\n2. Call `check_maintainer_changes({ name })`. It reconstructs maintainer\n add/remove history from the npm packument and flags:\n - a maintainer added recently who then published shortly after (the\n account-takeover pattern behind the Sept 2025 chalk/debug \"qix\"\n compromise and ua-parser-js),\n - a full sudden replacement of the maintainer list,\n - a long-standing maintainer quietly dropped,\n - a maintainer-list change on npm not yet tied to any release — flag this\n as the *more* urgent case, since access changed hands but nothing has\n shipped with it yet, so there's no version to warn the user off of.\n Also reports GitHub repository transfer/archival — a transfer isn't\n automatically hostile (e.g. jade → pug was a documented rename), say so\n rather than treating every transfer as a red flag.\n3. Call `check_package_provenance({ name, version })`. Three checks in one\n call: does the Sigstore build attestation's source repo/commit match\n `package.json`'s declared repository; is this version missing provenance\n while its npm-scope or maintainer peers consistently publish with it (a\n real anomaly, not just \"no provenance\" — plenty of legitimate packages\n predate the feature entirely, which this tool already accounts for via\n the peer baseline); and does the tarball's actual install scripts/\n dependencies match what's committed at the attested source commit — a\n script or dependency on npm that was never committed in source is the\n stolen-npm-token publish pattern. This is structural verification, not a\n cryptographic re-check of the Sigstore bundle — say so if the user asks\n how deep it goes.\n4. If `get_package`/`get_package_version` in step 1 showed\n `hasLifecycleScripts`/a `preinstall`/`postinstall`/`prepare` entry, follow\n up with `analyze_install_script({ name, version })`. It fetches the\n published tarball and statically scans the script — and the files it\n references — against npmscan's red-flags rubric (child_process,\n network calls, `.ssh`/`.aws`/`.npmrc`/`*TOKEN`/`*KEY` access,\n obfuscation, remote binaries off untrusted hosts, exfil endpoints,\n eval-on-decoded-content), returning a `totalScore`/`riskTier`. A nonzero\n score isn't automatically malicious — a legitimate binary download (e.g.\n `cypress`) scores nonzero too — so report the actual `findings`, not just\n the score.\n5. If the combined picture ends up genuinely concerning (a maintainer-\n takeover pattern, a provenance mismatch, a `possibleTyposquatOf` hit, or a\n critical install-script finding), offer — don't force —\n `suggest_alternative({ name, reason })` with `reason` set to whichever of\n `\"vulnerable\"`/`\"abandoned\"`/`\"typosquat\"`/`\"general\"` best fits, so the\n user has a next step instead of just a warning.\n6. Produce one findings report, most-concerning signal first:\n - State the verdict per check plainly (e.g. \"no maintainer-change red\n flags in the lookback window,\" not silence-as-clean).\n - Every finding from `check_maintainer_changes`/`check_package_provenance`\n is a hedged signal meant to prompt verification, not proof — say\n \"worth verifying independently,\" matching the tools' own language,\n especially for anything below their `high`/`critical` tiers.\n - Include the `npmscanUrl` so the user can read the full write-up.\n - If nothing turned up anything but a low/none `riskTier` and no maintainer\n or provenance findings, say so plainly — this skill exists to give\n confident \"looks clean\" answers as often as it flags real risk.\n\n## Do not\n\n- Do not run this skill's checks across every package in a list — that's\n `dependency-audit`'s job, and `check_maintainer_changes`/\n `check_package_provenance` are deliberately reserved there for\n already-flagged packages only, not a full inventory.\n- Do not treat a missing `provenance` field, a repository transfer, or a\n single maintainer addition as confirmed compromise on its own — report\n what the tool actually flagged (or didn't) and let the `riskTier`/points\n speak, don't editorialize past it.\n- Do not skip `get_package` and jump straight to the deep checks — the\n baseline (deprecated, popularity/maintenance tiers, typosquat) is cheap\n and often already answers the question.\n- Do not invent a replacement package name yourself — let\n `suggest_alternative` return its own `whySuggested`/`nonPackageAlternatives`\n rather than guessing.\n- Do not silently skip `analyze_install_script` when lifecycle scripts exist\n just because `check_maintainer_changes`/`check_package_provenance` came\n back clean — a legitimate maintainer can still ship a genuinely risky\n script, and vice versa; report all applicable signals, not just whichever\n ran first.\n\n## Tools used\n\n`get_package`, `get_package_version`, `check_maintainer_changes`,\n`check_package_provenance`, `analyze_install_script`, `suggest_alternative`\n— see `agents/openai.yaml` for the MCP server dependency, and\n`references/test-prompts.md` for the test cases to run in ChatGPT Developer\nMode before submitting.\n"
}SHA-256: 4e523827d515f82190f02bf0df5a18b006f9856961847afc619da127639dd1a6