# Anti Slop: a GitHub Action that closes low quality pull requests before review

> Anti Slop is a GitHub Action that scores pull requests against 34 rules covering branch, size, title, description, template, commits, files, user signals and contributor history, then closes the ones that fail too many checks. It runs in under fifteen seconds, is language agnostic, and exempts owners, members and collaborators by default.

**peakoss/anti-slop** — A GitHub action that detects and automatically closes low-quality and AI slop PRs.

- Repository: https://github.com/peakoss/anti-slop
- Stars: 847 · Forks: 23
- Language: TypeScript
- License: AGPL-3.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/peakoss-anti-slop

## The workflow file is the whole product

Anti Slop is a GitHub Action that detects and automatically closes low quality and AI generated pull requests. Adding it is a matter of creating a workflow file at .github/workflows/pr-quality.yaml:

```yaml
name: PR Quality

permissions:
  contents: read
  issues: read
  pull-requests: write

on:
  pull_request_target:
    types: [opened, reopened]
```

and adding a step that runs the action with a threshold:

```yaml
jobs:
  anti-slop:
    runs-on: ubuntu-latest
    steps:
      - uses: peakoss/anti-slop@v0
        with:
          max-failures: 4
```

Two details in that snippet are decisions rather than boilerplate. The trigger is pull_request_target with the opened and reopened types, which fires in the context of the base repository so the workflow has the permissions it needs to comment and close. And the trigger list is limited to those two events, so the action does not run on every push to a pull request branch.

The permissions block is also deliberate: contents read, issues read and pull-requests write. The action needs to read pull request and issue content to run its checks, and the write permission on pull requests is what lets it close them. The documentation notes that additional configured options, such as commenting or adding and removing labels, can require more permissions than this default set.

The project states that the entire action runs in under fifteen seconds, which is the point of doing this in a workflow rather than in a reviewer's head.

## What the 34 rules actually look at

The rules are grouped by the part of the pull request they examine, and the full example workflow file lists every option with its default value.

The branch checks restrict where a pull request can come from and go to, with allowed and blocked lists for both target and source branches, and the default blocked source branches are main and master, so a pull request that proposes merging main into a feature branch is rejected on sight.

The size checks cap the blast radius, with a maximum of 50 changed files and 10000 changed lines by default. The quality checks cap negative reactions at zero and require that maintainers can modify the contribution by default. Title and description checks cover conventional commit style on the title, whether a description exists, a description length limit of 2500 characters, a maximum of two emoji, a maximum of five code references, and an optional linked issue requirement. There is also a blocked terms list and a blocked issue numbers list.

The template checks verify that the pull request template was filled in, with options for strict sections, optional sections and a maximum of additional sections. The commit message checks cap message length at 500, optionally require conventional commits, and by default require the commit author to match the pull request author, with a list of blocked authors on top.

The file checks restrict what may be touched, with allowed extensions, allowed paths and blocked paths, where the default blocked paths are README.md, SECURITY.md, LICENSE and CODE_OF_CONDUCT.md. They also require a final newline and cap added comments at ten.

The user checks look at the contributor, with spam username detection, a minimum account age of 30 days, a maximum of six daily forks, a requirement for a public profile and a minimum profile completeness. The merge checks look at the contributor's track record, with minimum merged pull requests, a minimum repository merge ratio, and a minimum global merge ratio of 30 percent.

## Closing is the default action, not the only one

The failure actions are a list of things the action can do, and the one that surprises people is that closing a pull request is the default rather than an optional extra. In the full example, close-pr is true and lock-pr is false.

Alongside closing, the action can add labels on success, remove labels on failure, remove all labels, add a failure message to the pull request, and lock the pull request. The success action set is smaller, with just the ability to add labels to a pull request that passed.

The threshold that decides whether any of that happens is max-failures. The README explains the trade-off directly: the higher the number, the less likely a legitimate contributor is flagged, because more checks have to fail before the action takes action. The default in the example is 4, and the quick start uses the same value. With 34 rules available, a threshold of 4 out of 34 is a fairly permissive setting, and a maintainer seeing false positives would raise it.

There is also a separate axis for spam detection, which the README lists as anti-spam rather than only anti-slop. The merge ratio checks and the account age and daily fork limits are the parts of the rule set aimed at accounts created to post promotional pull requests, and they are the checks most likely to trip a legitimate first-time contributor who has not yet merged anything anywhere.

## Exemptions are the part that decides whether a repository keeps it

The exemption list is long and it is where a maintainer tunes the action to their repository. Draft pull requests can be exempt, and the default is false, so an in-progress draft gets judged. Bots can be exempt, with a default list of actions-user, autofix-ci, dependabot, renovate and github-actions. Individual users can be listed. Author associations can be exempted, and the default is OWNER, MEMBER, COLLABORATOR, which is what the README means by zero-configuration exemptions for owners, members and collaborators.

Labels work as an exemption too, with exempt-label and exempt-pr-label, and there is a separate exempt-pr-label for the labels a pull request itself carries. Milestones can be exempted wholesale or per milestone, and there are both all-milestones and per-pull-request-milestone variants.

The interesting one is exempt-all-pr-milestones set to false by default. With that off, a pull request linked to a milestone is judged like any other. With it on, anything with a milestone attached skips the checks, which is a reasonable arrangement for a repository where a milestone means a human already triaged the work.

Two of the defaults are worth arguing with. require-commit-author-match defaults to true, which means a pull request whose commits come from a different person than the pull request author is failed, and that is a common pattern for people who apply patches from another source. require-public-profile also defaults to true, which excludes contributors who keep their profile private for reasons that have nothing to do with the quality of the change.

## A v0 action with a Bun and TypeScript build

The project warns at the top that Anti Slop is currently v0 and subject to breaking changes prior to 1.0.0, and recommends pinning to a specific version or commit SHA if you need stability. It also claims that releases are immutable, so pinning to a version such as v0.2.0 gives the same guarantees as pinning a SHA without the awkwardness, since GitHub guarantees immutability for those tags.

The implementation is TypeScript built with Bun. The package manifest declares Node 24 or newer as the engine requirement, uses the tsdown bundler with a dev mode on watch, and the runtime dependencies are only two: the core actions library and the GitHub actions library. The lint, format and typecheck scripts all run through bunx, and the format script uses a Prettier plugin that sorts imports. There is a tsconfig, an eslint config, a prettier config, a bun lock file and a dist directory checked in, which is what a JavaScript action needs since GitHub runs the committed bundle.

The release history is short: v0.2.0 and v0.2.1 in February 2026 and v0.3.0 on 2026-04-15, which is also the date of the last push to the repository. That is more than six months before today, so this is not a project that is shipping every week, and the v0 warning is best read as a genuine risk rather than a formality.

The licence is AGPL-3.0-only, and the repository carries both a LICENSE file and a SECURITY.md.

## Where Anti Slop is the wrong choice

The first limitation is the false positive cost, and it is not evenly distributed. A repository that closes pull requests automatically is telling a stranger that their contribution was rejected by a machine before a human saw it. The merge ratio checks and the account age check are where that lands hardest, on someone who has contributed to your project before but has never merged anything, or on someone whose first contribution to open source is to you.

The threshold mitigates this, but the mitigation is coarse. Raising max-failures makes the action catch less, and there is no way to say that a specific check should only apply to accounts with some history, since the exemptions are global per repository rather than per rule.

The second limitation is scope. Every rule is a heuristic about the shape of a pull request, and none of them look at whether the change is correct or valuable. A well-formed, well-described, correctly sized pull request that adds a broken feature passes every check. The project is explicit that it is anti-slop rather than anti-AI, and that genuinely good AI-assisted contributions are not penalized, which means the rules are aimed at obvious junk rather than at quality in any real sense.

The comparison to alternatives is worth making honestly. Restricting contributions to members only is the blunt version and it does exclude newcomers, which is the problem Anti Slop is trying to avoid. A pull request template plus a bot that comments rather than closes is the softer version, and it costs you the automation. Review triage by a bot that adds a label such as needs-review is a middle path. What Anti Slop offers is speed and zero reviewer attention, and what it costs is the possibility of turning away a good contribution automatically.

## Conclusion

Anti Slop fits a maintainer of a busy public repository who is losing hours to junk pull requests and wants the filtering to happen automatically before a human looks, and who can live with the rules being adjusted over time. It does not fit a small repository where the volume does not justify a workflow, or a project that wants to reject a specific pull request rather than close it outright. Before adopting it, read the max-failures threshold carefully since it decides how many checks must fail before anything happens, pin the action to a specific version because the project is still v0 and subject to breaking changes, and confirm the exemptions cover your own automation, since dependabot, renovate and github-actions are listed as exempt bots by default while other accounts are not.

## FAQ

### How do I add Anti Slop to a repository?

Create a workflow file at .github/workflows/pr-quality.yaml that triggers on pull_request_target with the opened and reopened types, grants contents read, issues read and pull-requests write, and adds a step using peakoss/anti-slop@v0 with a max-failures value. The action runs in under fifteen seconds.

### What does the max-failures option control?

It is the number of failed checks required before the action takes any action. The higher the number, the less likely a legitimate contributor is flagged. The default in the examples is 4, and the check set spans branches, size, title, description, template, commit messages, files, user signals and contributor history.

### Does Anti Slop close pull requests automatically?

Yes. close-pr defaults to true, and lock-pr defaults to false. The action can also add and remove labels, post a failure message on the pull request, and add labels on success when a pull request passes.

### Who is exempt from the Anti Slop checks by default?

Owners, members and collaborators are exempt with no configuration, through the author association exemption. Bots have their own default list covering actions-user, autofix-ci, dependabot, renovate and github-actions, and draft pull requests, labels and milestones each have their own exemption settings.

### Is Anti Slop safe to use in production workflows?

It is currently v0 and subject to breaking changes prior to 1.0.0, so the project recommends pinning to a specific version or commit SHA. Releases are described as immutable, so a version pin such as v0.2.0 gives the same guarantees as SHA pinning. The licence is AGPL-3.0-only.

## Sources

- [Issues](https://github.com/peakoss/anti-slop/issues)
- [License: AGPL-3.0](https://github.com/peakoss/anti-slop/blob/main/LICENSE)
- [peakoss/anti-slop on GitHub](https://github.com/peakoss/anti-slop)
- [README](https://github.com/peakoss/anti-slop/blob/main/README.md)
- [Releases](https://github.com/peakoss/anti-slop/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/peakoss-anti-slop
