Catch the shortcuts agents take before the work reaches you.
A test skipped to get green, an error swallowed, a stub left in, a type check silenced. Anti-slop checks every change an agent makes for these and sends it back to the developer agent with each finding.
- Test skippedsrc/checkout/coupon.test.ts:88
it.skip('rejects an expired coupon', …) - Error swallowedsrc/checkout/apply-coupon.ts:41
} catch {}
- FixedTest skippedAnti-slop
- FixedError swallowedAnti-slop
The task view is a recreation of the Coroid portal. The task, files and findings in it are illustrative.
- Rules
- 106
- Families
- 13
- Rules that block by default
- 44
- Existing findings that block a change
- 0
What it looks for
Rules come in families. Each rule blocks, advises or only records, and an owner can change that for the organization or for one project.
- Tests
- Focused or skipped tests, deleted tests, assertions removed or weakened, tests that cannot fail, and retries that hide a flaky test.
.only.skipexpect(true).toBe(true)
- Suppressions
- New lint disables, ignored type errors, casts to any, and code excluded from coverage.
@ts-ignoreas anyeslint-disable
- Build and CI
- Test steps removed or allowed to fail, coverage thresholds lowered, test runs that pass with no tests, skipped commit hooks, and build output committed.
continue-on-error: true--passWithNoTests
- Test evidence
- A test run that ran nothing, fewer tests than the last green run, a partial run reported as complete, and cached results passed off as a new run.
Tests: 0 total--onlyChanged
- Production code
- Placeholder implementations, debugging code, notes such as “in a real implementation”, instructions meant for a person, mock data, and production code that imports test code.
throw new Error('Not implemented')debugger;
- Error handling
- Errors swallowed or hidden behind a default value, permission checks that allow access when they fail, and retries without a limit.
except: pass.catch(() => {})
- Security
- Hard-coded secrets, TLS verification turned off, authentication guards removed, wildcard CORS with credentials, and SQL built from strings.
rejectUnauthorized: falseverify=False
- Architecture
- New import cycles, imports across boundaries you declared, duplicated blocks, code the change left unused, and new copies of patterns you retired.
- Dependencies
- A manifest change without its lockfile, a second library for a job one already does, unpinned versions, and upgrades the specification did not ask for.
"latest"
- Caching
- Cache keys without the tenant, in-memory caches that never expire, and build-time values that should be read when the code runs.
- Comments
- Comments that repeat the next line, describe the edit, hedge, or contradict the code beside them.
// Updated to// should work
- Change scope
- Files outside what the specification touches, formatting-only changes, and renames the task did not need.
- Agent trail
- What the agent did on the way, such as deleting the test it was failing or changing an expected value to whatever the failing run printed.
Only what the change introduced blocks
Most repositories already contain some of these patterns. Anti-slop sorts every finding by where it came from, so existing debt never holds up unrelated work.
- Introduced
- New in this change. A finding from a blocking rule sends the change back to the developer agent.
- Touched
- Already there, on a line or in a function the change edits. It is recorded, and fixed when your change discipline asks for it.
- Existing
- Elsewhere in the repository. It is recorded as debt in Factory, where you can file a task to fix one rule’s findings.
Moving code does not count as introducing it. Copying it does.
You decide how far a change may reach
The change discipline tells the developer agent what it may clean up while it works.
- SurgicalOnly what the specification needs. Other problems are reported, not fixed.
- BalancedDefaultAlso fixes small problems on lines the change touches anyway.
- RestorativeAlso cleans up findings inside the functions the change edits.
The developer agent works to the same rules
Anti-slop is not only a verdict at the end. The agent gets the rules while it writes the change, and it cannot overrule them.
- The agent starts with your change discipline and the patterns you quarantined, each with the replacement to use instead.
- It sees the fast rules after every edit, and gets one chance to fix blocking findings before QA runs.
- Agents cannot accept their own findings. When an agent says a test was wrong and changes it, a reviewer must approve that change.
- A repository file,
.coroid/anti-slop.yml, can add rules and exclude generated paths. It is read from the base of the change, so a change cannot loosen its own rules.
Hold the agents you already run to the same rules
Engineers who work with their own coding agents can use your organization’s rules too.
- AGENTS.md snippet
- Download a section for your agents’ instructions with the project’s change discipline, quarantined patterns and most important rules.
- Coroid MCP server
anti_slop_rulesdescribes your published policy, andanti_slop_scanscans a branch of a synced project. Both are read-only.- Coroid Check on pull requests
- With pull request checks switched on, the same check runs on GitHub pull requests your developers open and marks each finding on its line.
Tested on our own code first
Coroid is built by one person and a hundred agents, so anti-slop ran on Coroid’s own repository before it ran on anyone else’s.
A scan of every source file
We scanned all 11,536 source files in Coroid’s repository as if an agent had just written them. The scan found 6 patterns the rules flagged wrongly. We fixed them, and blocking findings fell from 5,366 to 2,253.
What still blocks is what the rules are meant to find, such as a note left in our notification code: “In a real implementation, you would fetch the user’s FCM token.”
Rules a model judges
Two rules ask a model about one line at a time: a defensive check for something the code already rules out, and a comment that contradicts the code beside it. They only advise. Out of 600 candidate lines from real merged changes, they flagged none wrongly, and they cost at most $0.0015 per scan.
Switch it on in Quality Control
Owners and admins switch on anti-slop for the organization default or for one project. The next run of that project includes it.
- Open Quality Control and choose the organization default or a project.
- Switch on Anti-slop. It adds five expectations to the policy.
- Choose the change discipline and which groups block. Switching it off keeps these settings for the next time.
The five expectations it adds
- Tests still prove the change
- Nothing unfinished or test-only ships
- No new structural debt
- The change stays in scope and reads like this codebase
- New dependencies are real and reputable
- Organization default3 projects follow it2 of 5
- StorefrontOwn setup4 of 5
- Docs siteFollows default2 of 5
- Billing APIFollows default2 of 5
- Mobile appFollows default2 of 5
- Anti-slopSends a change back when it weakens tests, swallows errors, ships placeholders or adds structural debt.
- Unit testsFinds and runs the repository's unit tests on every change.
- Browser tests2 of 3differs from defaultRuns your browser journeys against the change.
- Translationsdiffers from defaultChecks that changed strings are translated and that their placeholders and plural forms match.
- Repository checksRuns your own commands, such as formatting, file size, migrations, integration tests and security scans.
- Thorough QAThoroughQA collects live evidence and screenshots against the Specification. When it is off, work gets Standard QA.