code-slop
Detect AI-generated code patterns ("slop") in PHP/Laravel and TypeScript/React source — comment narration, generic naming, premature interfaces, defensive overdose, mock-everything tests, and the absence of human "scars". Use when reviewing AI-assisted PRs, auditing code for taste/quality (not metrics — that's technical-debt), or hardening a code-review checklist. Triggers on "review for AI slop", "find AI patterns", "check code feels human", "audit code-quality taste".
What this skill does
# Code Slop Detection
Taste-level review of code for AI-generated patterns. Contains 24 rules across 6 categories covering comments, naming, over-engineering, defensive overdose, test slop, and style fingerprints. Where [`technical-debt`](../technical-debt) measures *quantitative* code debt (complexity, duplication, CVEs), this skill measures the *qualitative* failure mode: code that passes every metric but reads like a tutorial blog post, not like a human wrote it.
## Metadata
- **Version:** 1.0.0
- **Scope:** PHP / Laravel + TypeScript / React (Node)
- **Rule Count:** 24 rules across 6 categories
- **License:** MIT
## Why this skill exists
Industry data on AI-assisted code (GitClear 2025, cURL bug-bounty shutdown 2025, arXiv 2510.03029):
- **Refactoring collapsed** from 25% to <10% of changes
- **Copy-paste surged** 8.3% → 12.3%; code duplication rose ~8x
- **Code-smell rates +42–85%** over human baselines
- **82% of AI PRs** use generic catch blocks that don't distinguish error types
- **76% miss timeouts** on external calls
None of this fails a typical CI lint. It just makes the codebase slowly unmaintainable. This skill is the lens for catching it before it ships.
The core insight: **reading cost > writing cost now**. The cost of writing code collapsed; the cost of reading it didn't. Code you can't quickly understand is slop, even if it works.
## How to Audit
When the user asks "review for AI slop", "audit code-quality taste", or "find AI patterns" — run through this skill's rules as a checklist against the changed files (PR diff) or full repo.
### Audit Step 1: Determine Scope
- If a PR diff is provided: audit only files changed in the diff
- If files are named: audit those
- If no scope: audit the whole repo, prioritized by recently-touched files (most likely AI output)
### Audit Step 2: Detect Stack
| Signal | Stack |
|--------|-------|
| `composer.json` + `artisan` | PHP / Laravel |
| `package.json` (with TypeScript/React deps) | Node / TypeScript / React |
| Both present | Laravel + Inertia + React |
### Audit Step 3: Run the Slop Checklist
For each item below, output:
- **CLEAN** — pattern not present (brief confirmation)
- **SUSPICIOUS** — present in small amounts; flag and discuss
- **INFLATED** — present extensively; verbose-but-functional; remediation recommended
- **CRITICAL** — extensive AI-fingerprint presence; full review needed before merge
#### Comments
- [ ] No comments that just narrate the code (`// create user` above `User::create(...)`)
- [ ] No empty docblocks (`/** Get user */` above `getUser()`)
- [ ] No placeholder comments left in (`// TODO: implement`, `// your code here`, `// implementation`)
- [ ] No closing-brace labels (`} // end function`, `} // end if block`)
#### Naming
- [ ] No generic placeholder names (`data`, `result`, `info`, `temp`, `helper`)
- [ ] No over-descriptive run-on names (`theUserWhoIsCurrentlyLoggedIn`)
- [ ] No suffix abuse (`*Helper` / `*Manager` / `*Util` / `*Wrapper` overused without justification)
- [ ] No type-in-name patterns (`userObject`, `resultArray`, `stringData`)
#### Over-engineering
- [ ] No interfaces with exactly one implementation (and no plan for a second)
- [ ] No single-method classes that should be top-level functions
- [ ] No wrapper functions called once that just delegate
- [ ] No new dependency added when an existing one does the same job
#### Defensive overdose
- [ ] No generic `catch (e) { console.error(...) }` blocks around code that can't throw
- [ ] No null checks for impossible nulls (after non-null assertions / type-guaranteed values)
- [ ] Real defensive concerns (timeouts on external calls, rate limits) ARE present
#### Test slop
- [ ] No tests that mock every dependency with no real behavioural assertion
- [ ] No "doesn't throw" tests that just call and check for exceptions
- [ ] No tests that mirror the implementation's logic (re-encoding rather than verifying)
- [ ] No snapshot tests standing in for behavioural assertions
#### Style fingerprints
- [ ] Some formatting drift exists (no codebase looks like every file ran through the most aggressive linter)
- [ ] No `as any` / `@ts-ignore` / `@ts-expect-error` sprinkled where inference is hard
- [ ] Repo has some `// HACK:` / `// XXX:` / 2am comments somewhere — codebases without scars are suspect
- [ ] No debug artifacts (`console.log`, `var_dump`, `dd()`, `dump()`) left in production code
- [ ] No `if (x) return true; else return false` / redundant type annotations on obvious literals
### Audit Step 4: Build the Slop Ledger
End the audit with a verdict table:
```
## Code Slop Ledger
| File | Verdict | Top findings | Suggested action |
|------|---------|--------------|------------------|
| app/Services/UserExportService.php | INFLATED | 12 narration comments; 3 closing-brace labels; `*Helper` overuse | Strip comments; rename Helper → split into functions |
| resources/js/Pages/Orders/Show.tsx | CRITICAL | 4 `as any`; mock-everything tests; useless wrapper; impossible null checks | Rewrite section; remove tests; revisit type model |
| app/Models/Order.php | CLEAN | — | — |
## Summary
- CLEAN: X files
- SUSPICIOUS: Y files
- INFLATED: Z files (top priority: …)
- CRITICAL: N files (rewrite before merge)
```
## When to Apply
Reference this skill when:
- Reviewing an AI-assisted PR before merge
- Auditing a repo that has accepted heavy AI-assisted contributions
- Onboarding a codebase and assessing whether it reads as human-maintained
- Hardening a team's code-review checklist against AI slop
- After a "vibe coding" sprint, before declaring features done
- Setting up CI gates for AI-output quality
## Step 1: Detect Project Stack
Most rules are stack-agnostic in concept, but examples and detection commands differ between PHP and TypeScript.
| Signal | Stack | Tooling |
|--------|-------|---------|
| `composer.json` | PHP / Laravel | `phpstan`, `phpcs`, `phpmd`, manual grep |
| `package.json` | Node / TS / React | `eslint`, `tsc --noEmit`, `knip`, manual grep |
## Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|----------|----------|--------|--------|
| 1 | Comments | CRITICAL | `comments-` |
| 2 | Naming | CRITICAL | `naming-` |
| 3 | Over-engineering | HIGH | `over-eng-` |
| 4 | Defensive overdose | HIGH | `defensive-` |
| 5 | Test slop | HIGH | `test-` |
| 6 | Style fingerprints | MEDIUM | `style-` |
## Quick Reference
### 1. Comments (CRITICAL)
- `comments-narration` — Comments that just restate the code on the next line
- `comments-empty-docblocks` — Generic `/** Get the user */` over a typed `getUser()` signature
- `comments-placeholder` — `// TODO: implement`, `// your code here`, `// implementation`, `// helper function`
- `comments-closing-brace-labels` — `} // end function` / `} // end if block`
### 2. Naming (CRITICAL)
- `naming-generic-placeholders` — `data`, `result`, `info`, `temp`, `helper`, `value`
- `naming-over-descriptive` — `theUserWhoIsCurrentlyLoggedIn`, `calculateTotalAmountFromItemsList`
- `naming-suffix-abuse` — `*Helper` / `*Manager` / `*Util` / `*Wrapper` / `*Processor` overused
- `naming-type-in-name` — `userObject`, `resultArray`, `stringData`, `listOfItems`
### 3. Over-engineering (HIGH)
- `over-eng-premature-interface` — Interface with exactly one implementation and no second on the roadmap
- `over-eng-single-method-class` — Classes that exist solely to wrap one function
- `over-eng-useless-wrapper` — Wrapper called from exactly one place, just delegating
- `over-eng-dependency-creep` — New library when an existing dep already does the job
### 4. Defensive overdose (HIGH)
- `defensive-generic-catch` — `try { ... } catch (e) { console.error("error") }` everywhere
- `defensive-impossible-null` — Null checks after non-null assertions / type-guaranteed values
- `defensive-missing-real` — Defensive in the wrong places; missing timeouts/rate-limits where it matters
### 5. Test slop (HIGH)
- `test-mock-everything` — Mock forRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.