Anti-Slop: Polyglot Code Quality Audit
Detect and fix patterns that make code look machine-generated, over-abstracted, unnecessarily verbose, or fluently wrong. The goal is code that reads like a competent human wrote it - minimal, intentional, grounded, and clear.
This skill covers: TypeScript/JavaScript, Python, Bash/Shell, Rust, Docker/Containers, and Infrastructure as Code (Terraform, Ansible, Helm, Kubernetes manifests). The universal patterns apply everywhere; language-specific sections add targeted checks.
When to use
- Reviewing code that feels machine-generated, bloated, or oddly generic
- Simplifying code after an AI-heavy implementation pass
- Auditing comment noise, naming quality, over-abstraction, and dependency creep
- Looking for "ugly but technically works" code that still hurts readability or maintainability
- Looking for AI-native tells: hallucinated APIs, schema drift, fallback laundering, and tests that only ratify the implementation
The Three Axes of Slop
Every finding falls into one of three categories:
- Noise - bulk without value (redundant comments, boilerplate, unnecessary types/annotations)
- Lies - subtly wrong or outdated (hallucinated APIs, deprecated patterns, stale deps)
- Soul - lacks taste (over-abstraction, generic names, defensive overkill)
When NOT to use
- Correctness, logic, or race-condition bugs - use code-review
- Security vulnerabilities, secret scanning, or auth review - use security-audit
- One-off prompt authoring or prompt templates - use prompt-generator
- Session-end documentation maintenance - use update-docs
- Prose audit of docs, READMEs, wikis, emails, or creative writing - use anti-ai-prose
- Safe-deletion or LOC-slimming requests (removing dead code, shrinking file count) - use code-slimming
AI Self-Check
Before returning any anti-slop audit, verify:
- Rewrites compile/parse: every "after" code snippet is syntactically valid in the target language
- Security patterns not flagged: auth, CORS, input validation, rate limiting, TLS - these are correct even if verbose (check the "What NOT to Flag" list)
- Framework idioms respected: what looks like over-abstraction might be the framework's expected pattern (e.g., Next.js layouts, Django class-based views, Terraform module structure)
- Existing project conventions preserved: the repo's naming style, comment density, and abstraction level take precedence over generic "clean code" preferences
- Severity is honest: don't inflate P3 findings to P2 to pad the report
- No hallucinated replacements: verify that suggested modern alternatives actually exist in the target language version (e.g.,
matchrequires Python 3.10+,LazyLockrequires Rust 1.80+) - Test theater distinguished from correctness: implementation-mirroring tests, mock-heavy ceremony, and snapshots with no semantic assertions belong here; actual failing behavior still belongs to code-review
- Structural duplication sweep done: compare same-role modules/classes across sibling dirs (
providers,targets,sources,clients,registry) and either report near-twins or note why the duplication is intentional - Current source checked: dated versions, CLI flags, API names, and support windows are verified against primary docs before repeating them
- Hidden state identified: local config, credentials, caches, contexts, branches, cluster targets, or previous runs are made explicit before acting
- Verification is real: final checks exercise the actual runtime, parser, service, or integration point instead of only linting prose or happy paths
- Routing overlap checked: overlapping skills, trigger terms, and "When NOT to use" boundaries are checked before returning guidance
- Spec claims verified: claims about tool behavior, output contracts, or repo conventions are checked against current docs, scripts, or skill files
- API/grounding verified: suspicious helpers, flags, imports, config keys, and schema claims are checked against local types, generated schema, lockfiles,
--helpoutput, or official docs before being called hallucinations - Test theater separated: tests that assert mocks or snapshots only are distinguished from tests proving behavior
Performance
- Focus review on changed files and shared abstractions before scanning unrelated code.
- Collapse repeated slop patterns into one finding with examples, not one finding per occurrence.
- Use cheap static checks first, then run expensive tests only where they can confirm a real risk.
Best Practices
- Prefer deleting unnecessary abstraction over adding a new abstraction to hide it.
- Treat duplicate code as a finding only when it creates real divergence or maintenance risk.
- Require concrete failure modes; style dislike is not slop.
Workflow
Step 1: Scope the audit
Default scope based on context:
- If invoked right after writing code in this session -> self-check (review what you just wrote)
- If there are uncommitted changes (
git diff --name-only) -> recent changes - Otherwise -> ask the user
Available scopes:
- Full codebase audit - scan everything, report by category
- Recent changes - check git diff or recent commits
- Specific files/dirs - targeted review
- Self-check - review code you just wrote in this session
Step 2: Detect languages
Scan the project to determine which languages are present. Apply the universal patterns to everything, then layer on language-specific checks. Don't apply TS checks to Python code or vice versa.
Step 3: Run mechanical linters first (if available)
Before scanning for slop, run standard linters to clear the low-hanging fruit:
- Shell:
shellcheck - Python:
ruff check/mypy - TypeScript:
eslint/tsc --noEmit - Terraform:
terraform validate/tflint - IaC schema tools:
ansible-lint,helm lint,kubectl apply --dry-run=client,kubeconformwhen available - Structural patterns:
ast-grep(tree-sitter powered AST search - write rules to catch restating comments, dead code, hallucinated imports across languages. Install:npm i -g @ast-grep/cli. If your tool ecosystem providesast-grephelper skills or templates, use them.)
Linters handle syntax issues, unused imports, and known anti-patterns mechanically. This skill focuses on what linters can't catch: taste, over-abstraction, naming quality, unnecessary complexity, and stale idioms. Don't duplicate what a linter already covers.
Per-project tools (eslint, tsc, vitest, prettier) are project devDeps, not system tools. If they're not in the project's package.json/devDependencies, mention to the user what's missing and let them decide whether to install. Don't run linters that aren't set up.
Step 4: Scan for patterns
Use Grep, Glob, and Read. Read files before flagging - context matters. A pattern that looks like slop in isolation might be justified.
Before finalizing, do one explicit structural pass:
- Compare same-role files across sibling directories (
foo/emby.tsvsfoo/jellyfin.ts, multipleregistry.tsfiles, provider adapters, target wrappers) - Look for near-twin modules/classes with the same method set and only renamed nouns, IDs, or client types
- If you find a repeated pattern across many files, report one representative example and mention the spread instead of silently dropping it
Classify each finding by axis (Noise/Lies/Soul - see above), action, and severity:
Action:
- Fix - clearly wrong or wasteful, should change
- Consider - judgment call, present it and let the user decide
- Fine - looks like slop but is justified (note why and move on)
Severity (determines report ordering - high first):
- P1 - strongly suggests fabricated or ungrounded code (hallucinated APIs, schema drift