← NPMScanCONTENT HISTORY

Update to NPMScan

Snapshot Oct 2, 2026 · 00:16 UTC · version 3.0.0

Collection source: downloaded plugin package. These snapshots do not have a confirmed matching collection source. Differences in file lists alone do not establish changes to the package.

WHAT CHANGED · RULE-BASED ANALYSIS

Instructions updated for package-trust-check

Instruction wording changed from “that.” to “that. If the user is instead choosing”. 3 additional added or edited lines are in the evidence.

Observed in instructions or declared skills. Runtime behavior has not been tested.

Skill instructions

Before

invoke the full investigation for that.

After

invoke the full investigation for that. If the user is instead choosing between candidates for something not yet installed ("should we add X," "X vs Y for this job"), that's a forward-looking pick, not a trust investigation — use the `ne...

Supporting files

Before

[{"relative_path":"agents/openai.yaml","size_in_bytes":270},{"relative_path":"references/test-prompts.md","size_in_bytes":6156}]

After

[{"relative_path":"agents/openai.yaml","size_in_bytes":270},{"relative_path":"references/test-prompts.md","size_in_bytes":8725}]

Compare saved observations

Download comparison JSON
Full technical diff · 2 changed fields

changed /included_files

BEFORE
[
  {
    "relative_path": "agents/openai.yaml",
    "size_in_bytes": 270
  },
  {
    "relative_path": "references/test-prompts.md",
    "size_in_bytes": 6156
  }
]
AFTER
[
  {
    "relative_path": "agents/openai.yaml",
    "size_in_bytes": 270
  },
  {
    "relative_path": "references/test-prompts.md",
    "size_in_bytes": 8725
  }
]

changed /skill_md_contents

BEFORE
"---\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"
AFTER
"---\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. If the user is instead choosing\nbetween candidates for something not yet installed (\"should we add X,\" \"X\nvs Y for this job\"), that's a forward-looking pick, not a trust\ninvestigation — use the `new-dependency-evaluation` skill.\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"

SKILL.md line diff

--- before
+++ after
@@ -17,7 +17,10 @@
 run this skill's checks across a whole inventory. If the question is purely
 factual with no trust/safety angle ("what does lodash do," "what's the
 latest version of express"), just answer directly with `get_package` — don't
-invoke the full investigation for that.
+invoke the full investigation for that. If the user is instead choosing
+between candidates for something not yet installed ("should we add X," "X
+vs Y for this job"), that's a forward-looking pick, not a trust
+investigation — use the `new-dependency-evaluation` skill.
 
 ## Steps
 
Full snapshot data
{
  "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": 8725
    }
  ],
  "name": "package-trust-check",
  "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. If the user is instead choosing\nbetween candidates for something not yet installed (\"should we add X,\" \"X\nvs Y for this job\"), that's a forward-looking pick, not a trust\ninvestigation — use the `new-dependency-evaluation` skill.\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 of public snapshot: 03cd29e6e8966591245895b8c762b0a23cda965b194bfd5955691ada4e844a1d