Skip to main content

doc-ai-slopcheck

PyPI Python Tests License: MIT Rules

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

Digitalist fork of ai-slopcheck by Euraika, which is no longer published.

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

Category Rules Examples
AI Detection 16 Stub functions, instruction comments, plan/task IDs in comments, conversational bleed, identity refusals
Security 7 Hardcoded secrets, SQL injection, XSS, weak hashing, obfuscated code
JavaScript / Node 11 await-in-loop, unguarded JSON.parse, loose equality, React antipatterns
Go 3 Ignored errors, missing defer, wrong error wrapping
PHP / Drupal 2 Stub functions, raw $_GET/$_POST into eval/shell/SQL/echo; plus PHP support in debug (incl. devel dpm), SQL, obfuscation, empty catch, large functions, duplication
Python 1 Mutable default arguments
Cross-Language 17 Debug code, unreachable code, deep inheritance, dangerous shell in markdown
Data-Flow 4 Contradictory null checks, lock safety, IDOR risk, thread-unsafe globals
Quality 9 Large functions (>150 lines), copy-pasted code across files, plus opt-in deep nesting
API Contract 1 Removed routes, deprecated endpoints
Repo-Specific 1 Import boundary violations
Meta 1 Unused suppression directives

Features

  • 75 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
  • 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@v4
      - uses: actions/setup-python@v5
        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@v3
        with: { sarif_file: results.sarif }
      - if: always()
        uses: actions/upload-artifact@v4
        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 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/**"

# 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                 — 7 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/
│   ├── generic/           — 73 cross-repo rules
│   └── repo/              — 1 architecture rule
├── 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.

Metadata

Release files for doc-ai-slopcheck 1.2.3

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.3
File Size Uploaded
doc_ai_slopcheck-1.2.3.tar.gz 97.0 kB Details

Built distribution (wheel)

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

Total release size: 257.3 kB

Release files / doc_ai_slopcheck-1.2.3.tar.gz

Download URL doc_ai_slopcheck-1.2.3.tar.gz
Size 97.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2d4adde90e45af165f43ea348116d20a49e22e0d517a0e5193f7d57d52109796
BLAKE2b-256 checksum
How to use checksums
9d84c32bcc004aec9004f15a8d259383426533711ead53ecd6426413751b644c
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.3-py3-none-any.whl

Download URL doc_ai_slopcheck-1.2.3-py3-none-any.whl
Size 160.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
79ce560cf14d5a9e1484f4f2accff17aa459051c9ce03f4b2dda314b563d0e96
BLAKE2b-256 checksum
How to use checksums
03718e39595a6e138dcb801a7d4f5c8bac4f4f46d73624c9e68504f819c01047
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

1.2.6

2 release files

1.2.5

2 release files

1.2.4

2 release files

This release

1.2.3 This release

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