Defend developers and AI coding agents against slopsquatting (hallucinated package names).
Project description
SlopGuard
Slopsquatting is what happens when an LLM hallucinates a plausible-sounding
package name that does not exist on the public registry — and then an attacker
registers that exact name with malware so the next developer (or AI agent)
who follows the suggestion installs it. SlopGuard scans your project's
dependencies, flags entries that are either known LLM hallucinations or that
show the behavioural fingerprint of a slopsquat, and exits non-zero so CI
fails the build before the malware reaches node_modules or site-packages.
SlopGuard stops AI coding agents from installing packages that LLMs hallucinated.
Install
pip install slopguard-cli
# Homebrew formula ships in a later release:
# brew install slopguard
The PyPI distribution name is
slopguard-cli(the nameslopguardoverlapped with an unrelated existing package on PyPI). The installed command, the Python import, and everything else staysslopguard.
Python 3.11+ is required.
Usage
1. Scan the current directory
slopguard scan
SlopGuard auto-discovers package.json, package-lock.json,
requirements.txt, pyproject.toml, and Pipfile (up to two levels deep),
probes each name against the public registry, and prints a Rich table:
SlopGuard v0.1.0 — scanning /home/dev/myproj
Detected manifests:
• package.json (npm, 32 deps)
• requirements.txt (pypi, 15 deps)
Scanned 47 dependencies in 3.1s.
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Package ┃ Risk ┃ Reason ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ react-codeshift │ HALLUCIN. │ Matched seed DB entry; recurrence 0.71. │
│ langchain-helpers │ SUSPICIOUS │ Created 14 days ago, 48 downloads, new auth. │
│ openai-utils │ SUSPICIOUS │ Levenshtein 2 from popular package 'openai'. │
│ requests │ CLEAN │ Established package. │
└────────────────────┴────────────┴──────────────────────────────────────────────┘
Summary: 1 hallucinated, 2 suspicious, 44 clean, 0 error(s).
Exit code: 1
2. Scan a specific path
slopguard scan ./mono/services/api
3. CI mode — JSON output, strict failure threshold
slopguard scan --format json --output report.json --fail-on hallucinated
See .github/workflows/slopguard.yml.example
for a drop-in GitHub Actions workflow and docs/ci-integration.md
for details on other CI providers.
How it works
For every dependency, SlopGuard computes a small set of independent signals
and combines them into a single risk score in [0.0, 1.0]:
- Hallucination-DB hit (weight 0.90) — exact match in an embedded seed database of names known to be hallucinated by major LLMs.
- Registry not found (0.85) — the registry returns 404 for the name. The most common slopsquat shape: a name that doesn't exist yet.
- Very recently / recently published (0.35 / 0.20) — first release < 7 days / < 30 days old.
- Low downloads (0.15) — < 100 downloads in the last month (npm) or last week (PyPI).
- New publisher (0.20) and single-release new account (0.30) — a brand-new account whose only release is the package you're about to install.
- Levenshtein typo (0.25) — name is 1–2 edits away from a top-1000 popular package (likely a typosquat).
- Suspicious name pattern (0.10) — matches a classic LLM-hallucination
shape like
<stem>-helpers,<stem>-utils,<stem>-async,<stem>-pro.
The default cutoffs map scores ≥ 0.85 → hallucinated, ≥ 0.40 →
suspicious, else clean. Both thresholds are tunable in
.slopguard.yaml. See docs/detection.md for the full
table, the order of operations, and edge cases.
Configuration
.slopguard.yaml, picked up automatically from the scan target or any
ancestor (up to 3 levels):
ignore:
packages: ["internal-tool"]
patterns: ["^@mycompany/"]
fail_on: suspicious # any | hallucinated | suspicious | none
network:
enabled: true
timeout_seconds: 5
concurrency: 16
scoring:
suspicious_min_score: 0.4
hallucinated_min_score: 0.85
CLI flags override the file. See docs/usage.md for the full
reference.
What it does NOT do
- No dashboard, no auth, no accounts, no billing, no telemetry. The
CLI is fully offline-capable;
slopguard updateis the only outbound call beyond the npm + PyPI registry probes, and it just fetches a static JSON file from GitHub Pages. - No defensive package registration / tarpit.
- No Cursor / Claude Code / Copilot IDE plugins.
- No support for crates.io, pkg.go.dev, Maven Central, RubyGems, NuGet — Python and JavaScript only.
- No license scanning, no CVE matching, no SBOM generation.
Everything is MIT, free forever. Fork it.
Privacy & trust
SlopGuard makes only the network calls you opt into (the public registry
probes against registry.npmjs.org and pypi.org). No analytics, no
ping-home, no telemetry. The trust model is the moat: run --no-network if
you want to be sure.
Contributing
See CONTRIBUTING.md. PRs welcome — especially curated additions to the hallucination database.
License
MIT. Copyright © 2026 SlopGuard. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file slopguard_cli-0.3.0.tar.gz.
File metadata
- Download URL: slopguard_cli-0.3.0.tar.gz
- Upload date:
- Size: 63.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0fb09719617ea559a62d390a1c1ee851eb7b463dc77b9bf4a354fb5f39e76b4d
|
|
| MD5 |
dc26e259d3af376cd25f6cbff5af7556
|
|
| BLAKE2b-256 |
cf02789bb482c0c278fa5338cfddb881f0fa42e7ae56e4fdc18827f861b7f3ab
|
Provenance
The following attestation bundles were made for slopguard_cli-0.3.0.tar.gz:
Publisher:
release.yml on hariomunknownslab/slopguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slopguard_cli-0.3.0.tar.gz -
Subject digest:
0fb09719617ea559a62d390a1c1ee851eb7b463dc77b9bf4a354fb5f39e76b4d - Sigstore transparency entry: 1620629605
- Sigstore integration time:
-
Permalink:
hariomunknownslab/slopguard@7fa2be34a46b1ae6e8718993a55c77d0c6b8698d -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/hariomunknownslab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7fa2be34a46b1ae6e8718993a55c77d0c6b8698d -
Trigger Event:
release
-
Statement type:
File details
Details for the file slopguard_cli-0.3.0-py3-none-any.whl.
File metadata
- Download URL: slopguard_cli-0.3.0-py3-none-any.whl
- Upload date:
- Size: 51.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a549884a41aed5c131afb9222d16d9c56824b83966b3c7d0bf6645e0b9efdeab
|
|
| MD5 |
065c2813098aaf0e025bcf5a25ea29e2
|
|
| BLAKE2b-256 |
6dc63147b1b72a9c76702f45c387f75b662ceb6940dabfca619a477fd8d28fc0
|
Provenance
The following attestation bundles were made for slopguard_cli-0.3.0-py3-none-any.whl:
Publisher:
release.yml on hariomunknownslab/slopguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slopguard_cli-0.3.0-py3-none-any.whl -
Subject digest:
a549884a41aed5c131afb9222d16d9c56824b83966b3c7d0bf6645e0b9efdeab - Sigstore transparency entry: 1620629755
- Sigstore integration time:
-
Permalink:
hariomunknownslab/slopguard@7fa2be34a46b1ae6e8718993a55c77d0c6b8698d -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/hariomunknownslab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7fa2be34a46b1ae6e8718993a55c77d0c6b8698d -
Trigger Event:
release
-
Statement type: