Skip to main content

doc-ai-slopcheck

PyPI Python Tests License: MIT Rules

Deterministic scanner for AI-style code failures. 81 rules. No LLM. No backend.

Digitalist Open Cloud fork of ai-slopcheck by Euraika, which is no longer public.

Catches the mistakes AI coding assistants leave behind — stub functions, silent error handling, copy-pasted code, plan/ticket IDs in comments, hallucinated placeholders, hardcoded secrets, and more across Python, JS/TS, PHP (incl. Drupal), Go, C/C++, SQL, and Markdown.


Install

From PyPI (Python 3.12+):

pip install doc-ai-slopcheck
# or as an isolated command-line tool
pipx install doc-ai-slopcheck

Quick Start

# Scan a project (findings go to findings.json by default)
doc-ai-slopcheck scan . --output findings.json --fail-on warning

# Read the results
doc-ai-slopcheck summary findings.json            # Markdown summary
doc-ai-slopcheck html findings.json > report.html  # shareable HTML report

# GitHub Security tab (SARIF)
doc-ai-slopcheck sarif findings.json > results.sarif

# Only scan changed files (CI)
doc-ai-slopcheck scan . --changed-files git --fail-on warning

Scanning a directory other than the current one works as expected: when you pass exactly one directory and no --repo-root, that directory becomes the repository root (paths and .slopcheck.yaml are resolved from there). Paths outside the repository root are rejected with an error instead of being silently skipped.

What It Catches

Rules live in seven groups (doc-ai-slopcheck rules lists them all, with on/off):

Group Rules Examples
ai_slop 21 Stub functions (Python/JS/Go/PHP), tests that cannot fail, chat bleed and emoji, identity refusals, plan/task IDs and history narrated in comments, comment essays, placeholders, hallucinated values, debug code left in
security 11 Hardcoded secrets, SQL built from strings, XSS (dangerouslySetInnerHTML, dynamic innerHTML), raw $_GET/$_POST into eval/shell/SQL/echo, obfuscation, weak hashing, ReDoS
error_handling 11 Empty catch/except, ignored Go errors, unhandled promises, unguarded JSON.parse, contradictory null checks, unreachable code
concurrency 6 Locks without release, thread-unsafe globals, missing defer, timers without cleanup, use-after-free
maintainability 18 Large functions (>150 lines), copy-pasted code across files, deep nesting, too many positional args, oversized classes, opt-in pass-through wrappers
idioms 10 Dependencies or hacks where a built-in exists (moment, uuid, JSON.parse(JSON.stringify()), pytz, six), mutable defaults, == and React antipatterns, any / as unknown as / @ts-ignore, SELECT *
project 4 Import boundaries, API contract breaks, undeclared imports, unused suppressions

Features

  • 81 deterministic rules — no LLM, no network, no randomness
  • 7 languages — Python, JS/TS, PHP (incl. Drupal .module/.inc/.install/.theme), Go, C/C++, SQL, Markdown
  • Cross-file duplication — finds copy-pasted blocks within and across files, one finding per file pair
  • Prose slop — comment essays, history narrated in comments, plan/ticket IDs, emoji in comments and logs
  • Code-aware — rules about code skip comments and docstrings; rules about comments (TODOs, plan IDs, chat bleed) read them
  • Test code weighs less — findings in tests, mocks and fixtures drop one severity level
  • HTML report — standalone, shareable page that opens with a "Where to start" ranking of the files with the most kinds of problem
  • Inline suppression — # slopcheck: ignore[rule_id], or # slopcheck: ignore-next[duplicate_code] above a copied block
  • SARIF output — integrates with GitHub Security tab
  • Diff-only mode — scan only changed files (--changed-files git)
  • Baselines — suppress existing findings, fail only on new ones
  • API snapshots — detect removed API routes
  • Threaded — multi-core scanning (--jobs N)
  • Confidence filtering — --min-confidence medium for high-signal-only mode

Severity

Findings are error, warning or note. --fail-on (default error) sets the level that makes scan exit with status 1.

Findings in test and mock code (tests/, mocks/, fixtures/, test_*.py, *.test.ts, *Test.php, …) are lowered one level — error to warning, warning to note — and tagged test-code. Set test_paths: [] in the config to treat test code like production code.

SQL built from strings is an error when a value is spliced in, and a warning when only a table or column name is (FROM $table … WHERE id = ?), since names can't be bound as parameters.

PHP and Drupal

.php files and Drupal's .module, .inc, .install, .theme, .profile and .engine files are scanned. Only the project's own code is scanned by default: vendor/, Drupal core (web/core, docroot/core, html/core), contrib modules/themes/profiles, libraries/, sites/*/files, scaffold copies (default.settings.php, .ht.router.php, web/index.php, …) and generated files (.phpstorm.meta.php, sites/simpletest) are ignored.

PHP comments, docblocks, #[Attributes], heredocs and inline HTML outside <?php ?> are told apart, so rules don't fire on documentation or templates.

GitHub Actions

name: slopcheck
on: [pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-python@v7
        with: { python-version: '3.12' }
      - run: pip install doc-ai-slopcheck
      - run: doc-ai-slopcheck scan . --output findings.json --fail-on warning
      - if: always()
        run: |
          doc-ai-slopcheck github-annotations findings.json
          doc-ai-slopcheck sarif findings.json > results.sarif
          doc-ai-slopcheck html findings.json > slopcheck-report.html
      - if: always()
        uses: github/codeql-action/upload-sarif@v4
        with: { sarif_file: results.sarif }
      - if: always()
        uses: actions/upload-artifact@v7
        with: { name: slopcheck-report, path: slopcheck-report.html }

Baselines (Incremental Adoption)

# First run: baseline existing findings
doc-ai-slopcheck scan . --output findings.json --fail-on none
doc-ai-slopcheck create-baseline findings.json

# CI: only fail on NEW findings
doc-ai-slopcheck scan . --baseline .slopcheck/baseline.json --fail-on warning

CLI Reference

Command Purpose
doc-ai-slopcheck scan [paths] Scan files, write findings JSON
doc-ai-slopcheck rules List rule IDs, on/off (with the project config) and what each checks
doc-ai-slopcheck summary <file> Markdown summary
doc-ai-slopcheck github-annotations <file> GitHub workflow annotations
doc-ai-slopcheck sarif <file> SARIF v2.1.0 output
doc-ai-slopcheck html <file> > report.html Standalone HTML report
doc-ai-slopcheck create-baseline <file> Create fingerprint baseline
doc-ai-slopcheck api-snapshot Snapshot API routes for contract checks

Key scan Options

Option Default Description
--output findings.json Findings JSON file; - for stdout
--repo-root scanned dir, else . Root for relative paths and config lookup
--config .slopcheck/config.yaml, .slopcheck.yaml or .slopcheck.yml Config file
--fail-on error Exit 1 at severity: none / note / warning / error
--min-confidence low Filter: low / medium / high
--baseline — Suppress fingerprints from baseline file
--changed-files — git or @file.txt for diff-only mode
--jobs auto Thread count (0=auto, 1=sequential)
--api-baseline — API snapshot for contract comparison

Configuration

Create .slopcheck/config.yaml (or .slopcheck.yaml) in the repository root:

# Replaces the default list, so keep the defaults you still want
# (vendor, node_modules, Drupal core/contrib, ...).
ignored_paths:
  - "vendor/**"
  - "**/node_modules/**"
  - "services/legacy-api/**"

# Generated files (header says @generated, DO NOT EDIT or auto-generated) and
# bundled third-party files (first line is a /*! license banner) are skipped;
# set false to scan them.
skip_generated: true

# Paths treated as test code (findings drop one severity level); [] disables.
test_paths: ["*/tests/*", "*/mocks/*", "*Test.php", "test_*.py"]

rules:
  # Disable a rule
  js_loose_equality:
    enabled: false

  # Tune thresholds
  large_function:
    max_lines: 150
  duplicate_code:
    min_lines: 10        # normalised lines (blank and comment lines excluded)

  # Enable an opt-in rule with custom threshold
  deep_nesting:
    enabled: true
    max_depth: 5

  # Plan/ticket IDs in comments: add your own ID formats, e.g. decision records
  plan_reference_comment:
    patterns:
      - '\b(?:Task|Phase|Milestone|Sprint)\s+#?\d+\b'
      - '\bD-\d+\b'

  # One class per file is enforced for JS/TS; opt in for Python
  multiple_classes_per_file:
    python: true

  hallucinated_placeholder:
    allowed_domains: ["example.com", "localhost"]

Project Layout

doc_ai_slopcheck/
├── cli.py                 — CLI commands
├── config.py              — Pydantic config models
├── models.py              — Finding, ScanResult (stable contract)
├── engine/
│   ├── scanner.py         — Threaded orchestrator, comment and test-code filters
│   ├── duplication.py     — Cross-file copy-paste detector
│   ├── context_filter.py  — Comment/docstring/string detection (Python, C-style, PHP)
│   ├── repo_files.py      — File discovery and ignore patterns
│   ├── suppression.py     — Inline ignore parser
│   └── api_routes.py      — Route extraction for API snapshots
├── rules/                 — one folder per group; base.py, registry.py
│   ├── ai_slop/
│   ├── security/
│   ├── error_handling/
│   ├── concurrency/
│   ├── maintainability/
│   ├── idioms/
│   └── project/
├── output/
│   ├── html_report.py     — Standalone HTML report with hotspot ranking
│   ├── sarif.py           — SARIF v2.1.0
│   ├── annotations.py     — GitHub annotations
│   └── markdown_summary.py
└── state/
    └── store.py           — Baseline persistence

Development

Requires Python 3.12+ and Poetry 2.x.

poetry install
poetry run pytest
poetry run ruff check .
poetry build

Tests and ruff run on GitHub Actions for every push and pull request, on Python 3.12 and 3.13 (.github/workflows/tests.yml).

License

MIT — Euraika 2026. Fork maintained by Digitalist Open Cloud.

Metadata

Release files for doc-ai-slopcheck 1.2.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for doc-ai-slopcheck 1.2.6
File Size Uploaded
doc_ai_slopcheck-1.2.6.tar.gz 106.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for doc-ai-slopcheck 1.2.6
File Interpreter ABI Platform
doc_ai_slopcheck-1.2.6-py3-none-any.whl Python 3 none any Details

Total release size: 282.3 kB

Release files / doc_ai_slopcheck-1.2.6.tar.gz

Download URL doc_ai_slopcheck-1.2.6.tar.gz
Size 106.0 kB
Tags Source
SHA-256 checksum
How to use checksums
9a9c3d0522f8bb22494dcef8263384411d33dce232714707e7d0aca4ed680b8c
BLAKE2b-256 checksum
How to use checksums
da8ff7e4896d4332560b537a97f2395fecd14bfe23e698cba3f20a77d0cf27e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.3.4 CPython/3.13.4 Darwin/25.5.0

Release files / doc_ai_slopcheck-1.2.6-py3-none-any.whl

Download URL doc_ai_slopcheck-1.2.6-py3-none-any.whl
Size 176.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a87156fe8516f36f5cf93311dcec452cadf06cd566898464f2d7be430e61d81b
BLAKE2b-256 checksum
How to use checksums
a29caa54b8f9a4cfa0b0f5a3c0bc89c0a61db67a9af8aea6b9deefb3b7d58e92
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.3.4 CPython/3.13.4 Darwin/25.5.0

Release history Release notifications | RSS feed

1.2.7

2 release files

This release

1.2.6 This release

2 release files

1.2.5

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page