npm.io
0.1.1 • Published yesterdayCLI

@merverli/slopgate

Licence
MIT
Version
0.1.1
Deps
0
Size
85 kB
Vulns
0
Weekly
0

SlopGate

Deterministic AI-slop detector: a 40+ rule pack for code, comments, commit messages, PR descriptions and docs, a 0–100 scorer, a CI entry point, a GitHub Action, and a per-repo trend dashboard.

Slop score is higher = worse. A clean repo scores ~0; a repo saturated with AI-generated habits scores 60–100. CI gates fail when the score exceeds a threshold.

Quick start

# scan a tree
slop scan ./

# score 0-100 with per-rule breakdown
slop score ./ --json

# CI gate: exit 0 if score <= threshold, 1 if above
slop lint ./ --threshold 50

# lint a commit message too
slop lint ./ --threshold 50 --commit-msg "fix typo"

# apply the text rule packs to any blob (commit msg, PR body, docs)
slop check-text --text "As an AI language model, I cannot help with this."

# LLM review layer (bring-your-own-key; disabled without a key — deterministic core always works)
SLOPGATE_LLM_KEY=sk-... slop llm-review --text "wip"

Run from this directory (apps/slopgate) via node --experimental-strip-types src/cli.ts or the slop bin. Node ≥ 22.6 required (type stripping). Zero runtime dependencies.

Rule pack

46 rules across seven categories (see slop rules):

Prefix Category Examples
DEAD-* Dead abstractions unreferenced interfaces, empty interfaces, abstract-without-abstract, empty subclasses, pass-through wrappers
UNUSED-* Unused helpers exported helpers never imported, local functions never called, unused imports/variables, duplicate imports
COMM-* Cargo-cult comments comments that restate code, boilerplate headers, bare TODO/FIXME, placeholders, vacuous comments, commented-out code
NAME-* Generic naming utils.ts, data/tmp/foo, type-suffixed names, cryptic single letters, duplicated words
OVER-* Over-engineering async-without-await, promise anti-pattern, empty catch, stateless singletons, parameterless factories, empty branches
COMMIT-* Boilerplate text "fix typo", "update README", "wip", "cleanup", empty messages, missing PR descriptions
AI-* AI phrasing "As an AI language model", refusal boilerplate, "certainly! here's", "let me know if you have any questions"

Every rule has fixture tests (test/rules.test.ts). Rules are regex/brace-based by design: deterministic, dependency-free, and documented as heuristics.

Scoring

score = min(100, Σ severity weights + density bonus)
Severity Weight
high 10
medium 5
low 2

Files with > 5 findings add a capped density bonus so one giant sloppy file cannot hide in a large repo.

Fixtures

fixtures/ holds three seeded repos used to assert ordering and gating:

Fixture Score What it demonstrates
clean ~0 well-named, fully-used, honest-comment code
mild ~29 a few unused helpers, a generic file name, a bare TODO
heavy ~100 every category of slop, including AI phrasing in the README

Tests assert clean < mild < heavy and that slop lint --threshold 50 fails on heavy while passing on clean.

LLM review layer

slop llm-review runs the deterministic pattern catalog always, then optionally asks an LLM (OpenAI-compatible endpoint) to score prose 0–100 and name the slop type. The LLM pass is disabled by default — no key, no call, no telemetry (DEC-0005).

SLOPGATE_LLM_KEY=sk-... slop llm-review --file docs/architecture.md

Env: SLOPGATE_LLM_KEY (or OPENAI_API_KEY), SLOPGATE_LLM_URL, SLOPGATE_LLM_MODEL.

GitHub Action

See apps/slopgate-action/ — posts a PR comment, writes slopgate.sarif, writes the step summary, and fails CI above threshold when block: true.

Dashboard

See apps/slopgate-dash/ — per-repo score history and a trend line rendered from recorded check artifacts (slopgate-dash/data/history.json).

Ecosystem

SlopGate is the ecosystem's quality gate: SkillHub runs it as the optional verify --quality check (quality score on skill pages), and its GitHub Action (apps/slopgate-action) gates PRs. BenchKit supplies the honest-data culture (DEC-0006) that keeps scoring credible. See apps/README.md for the full map.

Tests & typecheck

npm test            # 80 tests: rules, scanner, scoring, CLI, LLM layer
npx tsc --noEmit    # strict typecheck