Quality gates for AI-assisted codebases — catch the slop LLMs leave behind.
Project description
🪣 Slop-Mop
Slop-mop steers agents towards choices that maximize long-term repository maintainability and stability by making the easy choices the right choices.
It does not try to turn agents into what they aren't. Rather, slop-mop takes LLMs' strengths and points those assets at their own weaknesses. It does so via greased rails: a path of least resistance toward more maintainable choices. The hard work is already done in the gate creation and orchestration - the agent just has to run the check and do exactly what sm tells it to.
Don't make sloppy choices. Keep moving forward and address debt relentlessly. Resist the urge to side-step the check. Just fix what it flags and keep moving: that is the whole idea.
It is purposefully opinionated, as structure begets adherence to best practices.
Project Status
slop-mop has reached 1.0.0. The current public policy surface for release and stability expectations lives here:
Quick Start
Install it:
pipx install slopmop[all]
Set up a repo:
sm init
Choose a starting point.
For an existing repo, start with refit. It walks the project through a structured cleanup before you enter the day-to-day maintenance loop:
sm refit --start
sm refit --iterate
sm refit --finish
If you cannot do the full refit right now, generate a baseline as a temporary escape hatch. That keeps new failures loud while you come back to the cleanup:
sm status --generate-baseline-snapshot
sm swab --ignore-baseline-failures
Run the normal loop:
sm swab
If it fails, fix what it reported and run sm swab again. When it passes,
commit. Before opening or updating a PR, run the deeper pass:
sm scour
After CI or review feedback lands:
sm buff
If you are not sure what comes next, use the auto-advance command:
sm sail
It reads the current workflow state and runs the next obvious slop-mop verb.
Use with Claude
Slop-mop ships as a Claude plugin: a skill that auto-triggers on remediation
prompts, plus six slash commands (/sm-refit, /sm-sail, /sm-swab,
/sm-scour, /sm-buff, /sm-barnacle). Install once and sm is available in
every repo — no per-repo sm agent install required.
In Claude Code or Cowork:
/plugin marketplace add ScienceIsNeato/slop-mop
/plugin install slopmop
Then ask Claude things like "refit this repo", "sail this repo", "swab my changes before I commit", "buff PR 142", or "file a barnacle for this sm friction". The skill activates on remediation language and runs the right verb.
The CLI itself is still a prerequisite — install it once with
pipx install slopmop[all] and the plugin will call into it.
When sm itself gives invalid guidance or blocks valid work, use
/sm-barnacle or sm barnacle file. That is the preferred internal friction
reporting path; do not file ad hoc gh issue create reports for slop-mop
tooling defects.
Distribution notes, promotion TODOs, and adoption-tracking signals live in DOCS/PENETRATION_EFFORTS.md.
The Loop
Slop-mop has five verbs you will actually use:
| Verb | What it is for | When to run it |
|---|---|---|
sm status |
Workflow state and baseline snapshots | When you need current state or a temporary baseline |
sm swab |
Code-centric local feedback | After meaningful code changes |
sm scour |
Code-centric pre-PR sweep | Before opening or updating a PR |
sm buff |
Process-centric CI and review follow-up | After CI completes or review feedback lands |
sm sail |
Process-centric next-step selection | When you are not sure what to do next |
The boring version:
write code -> sm swab -> commit -> sm scour -> push/open PR -> sm buff
Not sure where you are in that loop? sm sail figures it out for you.
Full state machine: DOCS/WORKFLOW.md.
sm swab view is built for humans: grouped gates,
progress, timings, and a clear final verdict. Agent loops can use
--porcelain when they need terse output instead.
What It Checks
Slop-mop groups gates around four common agent failure modes.
Overconfidence
The code compiles. Tests pass. That's not the same as being tested or covered.
This catches missing tests, coverage gaps, and type-blindness that slips through
because the code runs.
Deceptiveness
Tests pass, but do they actually prove anything? Bogus assertions, tests that
exist to make the coverage report happy, leftover debug traces that signal the
code was never properly cleaned up before shipping. Slop-mop sees through it.
Laziness
Working code rots. Complexity creep, dead code, formatting drift, repeated
logic - these compound quietly until the codebase becomes unnavigable.
Catch them while they're small.
Myopia
Your change looks fine. The repo-wide picture might not be. Duplication,
security gaps, dependency risk - things that only show up when you zoom out
past the file you're in.
The full gate reasoning lives in DOCS/GATE_REASONING.md.
Refit vs Maintenance
New repo or inherited mess? Start with refit. It builds a remediation plan and walks you through gate-by-gate until the codebase is clean enough to enter the maintenance loop:
sm refit --start
sm refit --iterate
sm refit --finish
Once you're in decent shape, maintenance is just the loop:
sm swab
sm scour
sm buff
Don't skip refit to go straight to maintenance on a dirty repo. You'll spend more time fighting the gates than fixing the code. Do the work upfront.
Minimal Install
If you only want the framework without optional gate dependencies:
pipx install slopmop
Minimal install gives you the framework. Gates that need tools like black,
pyright, bandit, or pytest will tell you what is missing.
Developer setup details live in DOCS/DEVELOPING.md.
Configuration
sm init writes .sb_config.json after looking at the repo. It enables gates
that appear relevant and leaves non-applicable gates alone.
Useful commands:
sm config --show
sm config --enable myopia:vulnerability-blindness.py
sm config --disable laziness:complexity-creep.py
Disabling a gate should be temporary. If a gate is wrong, tune it or file the bug. Don't just silence it and move on - that's how slop accumulates.
Migration behavior is documented in DOCS/MIGRATIONS.md.
Baselines
Inherited a mess and can't stop to fix it all right now? Snapshot the current failures. New failures stay loud, old ones get paid down over time:
sm status --generate-baseline-snapshot
sm swab --ignore-baseline-failures
sm scour --ignore-baseline-failures
This isn't a way to hide problems. It's a way to stop old debt from blocking every unrelated change while you work back to a clean state. Don't live in baseline mode - it's a temporary unblocker, not a permanent config.
CI
Run slop-mop in CI the same way you run it locally: install it and run the gate command.
See DOCS/CI.md for a GitHub Actions template.
Agent Setup
Slop-mop can install repo-local agent instructions for common coding agents:
sm agent install
You can target one agent if you prefer:
sm agent install --target copilot
sm agent install --target cursor
sm agent install --target claude
Generated agent files are local workspace configuration. They should stay out
of source control; the reusable source templates live in this repository under
slopmop/agent_install/templates/.
The short version for agents: ride the rail, fix what it reports, do not bypass the gate.
PR Review and Bot Integration
Slop-mop closes the loop on PR feedback too, not just local code quality. Once
a PR is open, review comments accumulate from humans, and bots alike. Left
unaddressed, they block the merge and erode reviewer trust. sm buff
handles this:
sm buff inspect <PR> # triage CI results + fetch all unresolved threads
sm buff resolve <PR> <ID> --scenario fixed_in_code --message "<evidence>"
# post a reply and resolve the thread
sm buff verify <PR> # confirm nothing is still open
sm buff watch <PR> # poll CI until it finishes
The myopia:ignored-feedback gate checks this during sm scour. By default it
warns if unresolved review threads exist; set fail_on_unresolved: true if you
want sm scour to block on them. sm buff runs the same check in blocking
mode, so the post-PR rail won't report a PR as clean while comments remain open.
Review Bots
Copilot code review, Cursor's bugbot and the like catch things slop-mop deliberately doesn't try to own: logic errors in your specific domain, API misuse, smelly design patterns and logical errors. They're trained on human review patterns; slop-mop is optimized for the failure modes unique to agent-generated code.
Run them in parallel, not as alternatives. The combination covers more ground:
- slop-mop: duplication, complexity creep, coverage gaps, unaddressed feedback
- Copilot / bugbot / human reviewers: logic correctness, style conformance, domain-specific hazards
When a bot leaves a comment, treat it like a human reviewer left it. Use
sm buff resolve to reply and close the thread - the same workflow applies
regardless of who opened it.
Custom Gates
Slop-mop's CI framework is well adapted to existing checks that are not covered by built-in gates. Add your own check as a custom gate and manage it like any other slop-mop quality gate.
Start with DOCS/NEW_GATE_PROTOCOL.md.
When To Push Back On The Tool
Sometimes slop-mop is wrong.
That's useful information. Don't route around it with ad-hoc commands and pretend the rail is fine. Fix the gate, tune the config, file the bug. The point isn't obedience - it's making the correct path the path of least resistance.
For slop-mop tooling friction, file a barnacle issue upstream:
sm barnacle file \
--title "short summary of the slop-mop friction" \
--command "sm <verb> [flags]" \
--expected "what should have happened" \
--actual "what happened instead" \
--repro-step "how to reproduce it" \
--tried "what you already tried" \
--workflow swab \
--blocker-type blocking \
--json
Barnacles are for defects in slop-mop itself: invalid guidance, false gate
results, broken rails, confusing output, or install/upgrade/refit friction. They
create structured GitHub issues tagged for maintainer triage. They are not a
local queue and not a replacement for fixing real target-repo failures.
The generated Markdown body is also written to .slopmop/last_barnacle_issue.md
so failed filings are retryable without reconstructing context.
Contributing
For repo conventions, see DOCS/CONVENTIONS.md.
For contribution guidance, see DOCS/CONTRIBUTING.md.
For local development, see DOCS/DEVELOPING.md.
License
Slop-mop uses the Slop-Mop Attribution License v1.0.
If you use it, attribution is required.
Project details
Release history Release notifications | RSS feed
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 slopmop-1.6.0.tar.gz.
File metadata
- Download URL: slopmop-1.6.0.tar.gz
- Upload date:
- Size: 445.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
422dcecc321bbda5ad6e2b37795ca0bcb50c908b0bccdff7a7f68066f50fc2de
|
|
| MD5 |
b079756bb478ed5137f201b00feb00d5
|
|
| BLAKE2b-256 |
ab2d94ec752c8e1cdcd67badaf3a7a496d0327e44ab299e2f0624c821f5d00f4
|
Provenance
The following attestation bundles were made for slopmop-1.6.0.tar.gz:
Publisher:
release.yml on ScienceIsNeato/slop-mop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slopmop-1.6.0.tar.gz -
Subject digest:
422dcecc321bbda5ad6e2b37795ca0bcb50c908b0bccdff7a7f68066f50fc2de - Sigstore transparency entry: 1674516343
- Sigstore integration time:
-
Permalink:
ScienceIsNeato/slop-mop@d8f8215dae3010a3ed8b60721b0c45d5cb1bc605 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ScienceIsNeato
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d8f8215dae3010a3ed8b60721b0c45d5cb1bc605 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file slopmop-1.6.0-py3-none-any.whl.
File metadata
- Download URL: slopmop-1.6.0-py3-none-any.whl
- Upload date:
- Size: 524.1 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 |
9cb4e196d4ec33739f2f1436701b16cc24e9d17114d88f16bb21576a312c78c1
|
|
| MD5 |
107b3943bbeb39f919d5bf3bdb25e28e
|
|
| BLAKE2b-256 |
39cab08091a283a6980df3e9fadebcfcfb73d043fe6ecd2c1a74c0966b50d125
|
Provenance
The following attestation bundles were made for slopmop-1.6.0-py3-none-any.whl:
Publisher:
release.yml on ScienceIsNeato/slop-mop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slopmop-1.6.0-py3-none-any.whl -
Subject digest:
9cb4e196d4ec33739f2f1436701b16cc24e9d17114d88f16bb21576a312c78c1 - Sigstore transparency entry: 1674516369
- Sigstore integration time:
-
Permalink:
ScienceIsNeato/slop-mop@d8f8215dae3010a3ed8b60721b0c45d5cb1bc605 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ScienceIsNeato
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d8f8215dae3010a3ed8b60721b0c45d5cb1bc605 -
Trigger Event:
workflow_dispatch
-
Statement type: