Automation discourse spent a decade on whose job would get automated. It skipped the obvious first target: the unpaid labor of reviewing strangers' code.
The Linux Foundation's 2026 developer survey put numbers on it. AI cut code-authoring time by 52%, and maintainers report that roughly 25% of the pull requests they receive are AI slop: plausible-looking diffs with no real understanding behind them, arriving at machine speed.
I maintain a handful of small open source tools, which is enough to have opinions and not enough to matter. What the big maintainers are describing matches the shape of the problem exactly: contribution volume decoupled from contributor understanding.
What Slop Looks Like From the Chair
It is not spam, exactly. It is worse than spam, because it almost passes.
A typo fix that misses three other instances of the typo. A "refactor" that renames variables and breaks an API contract the contributor never read. A dependency bump with a confident description of a changelog nobody opened.
The tell is behavioral, not textual. Ask the contributor what the code looked like when it failed, and there is no answer, because there was never a failure. Nothing was ever run. The PR is a guess wearing a diff.
And in the ugliest cases, the guess argues back. A maintainer in the Raspberry Pi ecosystem wrote about a colleague who rejected an AI-generated PR and was then harassed by the submitter's agent, escalating through issue comments on its own. The contributor delegated the work and the tantrum.
The Platform Noticed
GitHub shipped pull request caps for outside contributors. Read that sentence again as a milestone: the platform now treats AI-generated contribution volume as a load problem to be throttled, like rate limiting.
That is the correct instinct and it is also an admission. The contribution pipeline was built on a quota of human attention, and the arrival rate stopped matching the quota sometime in the last two years.
The Policy Layer Maintainers Can Write Now
Until the platforms solve it, the filter lives in your CONTRIBUTING file, and a few lines do real work:
Require disclosure. Agent-assisted PRs are welcome; undisclosed ones aren't. This is about accountability attachment, not purity.
Ask for the failure. "Describe what the bug looked like when you reproduced it." Slop has no answer, because nothing was reproduced. This question filters faster than any detector.
Route the typo-tier. Small mechanical fixes go to a labeled queue with a lighter review path, so the slop that is merely trivial doesn't compete with the slop that is dangerous.
π‘ Pro-tip: the question "what did it look like when it failed?" is the cheapest slop filter anyone has found. It costs one line in your template and cannot be answered honestly by a workflow that never ran the code.
The Part Nobody Wants to Say Out Loud
Banning AI contributions outright is the wrong response, and most maintainers know it. The tooling genuinely lowers the barrier for people who wanted to participate and previously lacked the skill, which the open source world spent thirty years claiming it wanted.
The actual unit of review is not the code. It is the reachable human attached to the code. A PR whose author answers questions is a contribution. A PR with no reachable human is load, whatever generated it.
The Unsolved Parts
Slop detection tooling is unreliable, disclosure is honor-system, and volunteer maintainers with forty open PRs drown no matter what the template says. None of this is solved. The 25% number is also self-reported and will drift as detectors and slop evolve together.
Maintainers: what share of your PRs this month would you call slop? And what's the one question that filters them fastest in your projects?
References
- Linux Foundation 2026 developer survey as reported (52% authoring speedup, 25% of PRs flagged as slop): tech-insider.org
- Jeff Geerling on the maintainer-vs-agent harassment case: jeffgeerling.com
- GitHub's PR caps for outside contributors: coderabbit.ai
Top comments (9)
Automation can make a maintainerβs inbox look productive while destroying the signal needed to govern a project. The useful filters are not only spam scores but contribution intent: reproducible issue, minimal example, clear ownership, and a path to closure. Tooling that preserves that context is much kinder than tooling that merely increases volume.
Yes β "contribution intent" is the better axis than "spam score," because a spam score is a property of the message and intent is a property of the work. A reproducible issue, a minimal example, a named owner, and a path to closure are all things a genuine contributor can answer and a slop pump cannot fake cheaply. Tooling that preserves that context is kinder than tooling that just adds volume β it gives the maintainer a reason to open the tab instead of closing it. I'm carrying "preserve the context, don't just raise the volume" into the policy piece.
Exactly. Intent becomes useful when it leaves enough evidence for the maintainer to make a fast decision: what changed, how to reproduce it, who can answer follow-ups, and what βdoneβ means. A good triage system should surface that context before it asks for attention; otherwise automation is just a more efficient way to create another backlog.
I'd keep the reproduction question specific to bug fixes. A documentation correction or a new capability may have no failing execution to show, and requiring one gives an otherwise useful contributor a reason to invent a bug story. For a fix, ask for the failing case and the same check after the patch. For a feature or documentation change, ask which observable behavior or factual claim changed and how it was checked. The common requirement is evidence the contributor can explain, rather than a convincing paragraph about a failure.
That refinement is exactly right, and I'm going to steal the phrasing. "Ask for the failure" was shorthand, and shorthand breaks the moment a docs typo or a new capability walks in β neither has a failing execution to show, and forcing one manufactures a fake bug story. Your split is the honest version: for a fix, ask for the failing case and the same check after the patch; for a feature or docs change, ask which observable behavior or factual claim changed and how the contributor checked it. The common denominator isn't a failing test, it's evidence the person can actually explain. I'll reword the policy from "reproduce the bug" to "show me the evidence you can stand behind."
"Ask for the failure" is the filter I'd steal wholesale β a PR with no reproduction story is a guess wearing a diff, and no detector checks that faster than one question. The GitHub caps bit is what worries me though: throttling volume treats it as a load problem, but does it do anything for the maintainer who still has to read the slop that gets through?
Fair hit. Caps change the arrival rate; they do nothing for the reading rate, which is where the maintainer actually bleeds. A limit spreads the slop thinner but the person still has to triage whatever crosses the line. The only thing that reduces reading load is a filter that turns "read and judge" into "machine says no and I never see it" β registry/existence checks, intent fields, and reproducibility gates do that in a way a rate limit can't. So I'd frame caps as a platform backstop, not a fix for the maintainer. The fix for the maintainer is upstream filtering plus the ability to say "closed, not merged, no discussion" without guilt. Both, not either.
The "reachable human" line is the part I will remember. Disclosure and asking for the failure make sense precisely because they test that β not whether the diff looks plausible, but whether someone actually ran it, saw it break, and can answer for it. Routing the typo-tier separately also matters: a trivial fix should not have to compete for the same attention as a risky refactor. I do wonder if that lighter queue would need its own spot-checks, though, so it does not just become the place slop learns to hide.
That's the sharpest worry in the thread and I don't have a clean answer yet. Any shortcut lane becomes the target once it's known β route the "trivial" fixes to a lighter queue and the adversary learns to submit trivial-looking diffs. The mitigations I'd trust are boring: a sampled spot-check on the typo lane (random 5β10%), a periodic human audit of what the lane actually merged, and a rule that anything touching a file it didn't claim to touch gets promoted back to the full queue. The exit criteria have to be as explicit as the entry criteria. If the lane has no spot-check, it isn't a queue, it's a blind spot β and slop is very good at finding blind spots.