What a linter is built to catch
A linter operates on rules: a finite, configured set of patterns it knows to look for. Unused imports, shadowed variables, missing semicolons, a function that's too long by a line-count threshold, a banned API call. Static analyzers go further — tracking types, flagging possible null dereferences, spotting unreachable code — but they're still answering rule-shaped questions with deterministic yes/no answers. That determinism is their strength: a linter never has an opinion, never has a bad day, and runs in milliseconds.
The flip side of determinism is that a linter can only catch what someone encoded as a rule, and most of what makes AI-generated code tedious to review isn't rule-shaped. "This comment restates the code" isn't a syntax error. "This block is the fourth near-copy of the same logic" isn't an unused variable. "This is written like Java in a Python file" doesn't trip a type check. The linter sees valid code and stays silent, because by its definition the code is fine.
Why AI slop slips through the rules
AI tools produce code that is, on the linter's terms, clean — that's part of what makes them feel productive. The model has seen millions of lint-passing examples, so its output passes lints too. What it hasn't reliably learned is taste: when a comment adds nothing, when a copy should have been a function, when the idiomatic move was right there, when a file should have followed the layering the rest of the repo follows. Those are judgment patterns, not rule violations, and they're exactly the slop a reviewer ends up cleaning by hand.
quality·vibes reads diffs for that higher layer. Instead of matching a fixed rule set, it analyzes the changed code for the slop patterns AI tools predictably produce — verbose comments, repetitive or duplicated blocks, non-idiomatic language usage, inconsistent naming, and basic structural or architectural deviations — and surfaces them on the diff where the reviewer is already looking. It's the opinion layer a linter deliberately doesn't have, scoped to the mistakes that matter for AI-generated code.
Run both — they don't overlap
This isn't a replace-your-linter pitch, and a comparison page that pretended otherwise would be lying to you. Keep your linter and static analysis: they're fast, deterministic, free, and they catch a class of real problems quality·vibes doesn't try to. Then add quality·vibes for the slop layer above the rules — the redundancy, duplication, idiom, naming, and structure judgments that a rule engine can't express. One enforces the rules; the other reads for the taste.
There's a workflow boundary worth stating too. A linter runs locally and in CI and gates the merge automatically. quality·vibes runs at the pull-request level and suggests rather than enforces: it flags slop on the diff with accept/dismiss, gives the PR a slop score, and leaves the human in control of every accept — it never auto-merges or auto-applies fixes. And like a linter, it stays out of business-logic correctness; neither tool tells you whether the answer is right, only whether the code that computes it is clean.
Linters / static analysis vs quality·vibes
| Linter / static analysis | quality·vibes | |
|---|---|---|
| What it checks | A fixed catalogue of syntactic rules and smells | Higher-level AI-slop patterns a rule can't express |
| Catches AI slop? | No — slop is lint-clean by construction | Yes — that's the specific job |
| Verbose redundant comments | Passes silently | Flagged on the diff |
| Duplicated / pasted blocks | Limited (line-count smells at best) | Flagged as repetition across the diff |
| Non-idiomatic usage | Passes — it's valid code | Flagged with a suggestion |
| Naming drift / structural deviation | Mostly passes | Flagged against the repo's patterns |
| Where it runs | Local + CI, deterministic, gates merge | Per-PR diff, suggests with accept/dismiss |
| Business-logic correctness | No | No — that stays with human reviewers |
| Verdict | Keep it — fast rule enforcement | Add it — the slop layer above the rules |
frequently asked
Can't I just add custom lint rules to catch this?
For a few narrow cases, sometimes — but most slop resists rule-shaping. "This comment is redundant" and "this is non-idiomatic here" depend on context and judgment that a deterministic rule can't capture without enormous false positives. That's the gap quality·vibes fills: it reads for the patterns rather than matching a fixed expression, which is why it complements your linter instead of duplicating it.
Does quality·vibes replace my static analysis in CI?
No. Static analysis catches a real and different class of problems — type errors, null risks, unreachable code — fast and deterministically, and you should keep it gating your CI. quality·vibes adds the slop layer on top at the pull-request level. The honest recommendation is to run both; they barely overlap.
How is this different from clean·vibes and secure·vibes?
Same family, different scope. clean·vibes scores a whole repo for cleanliness and secure·vibes scores it for security — both are repo-level audits you run on a codebase. quality·vibes works at the PR/diff level on AI-slop specifically, as code is being added. Use clean·vibes or secure·vibes for a standing audit; use quality·vibes as the continuous gate on incoming AI-generated changes.
Will it flood me with false positives like an over-tuned linter?
It's built around accept/dismiss so you stay in control: dismiss what doesn't apply, accept what does, and the slop score reflects the real findings. It suggests rather than blocks, so a noisy flag costs you a click, not a failed build. The aim is a fast triage pass that saves reviewer time, not another wall of warnings to ignore.
Last updated June 19, 2026