Skip to content
Development
Skill

/ai-slop-cleaner

Post-implementation cleanup that removes AI-generated bloat while preserving functionality. Runs pass-by-pass with test verification after each pass. Activate after kraken/spark complete a feature, or when a codebase needs hygiene work.

From plugin
vibecosystem
532200 skills138 agents7 hooks
Install
$ npx -y skills add vibeeval/vibecosystem --skill ai-slop-cleaner --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/ai-slop-cleaner

Context preview

The summary Claude sees to decide when to auto-load this skill.

Post-implementation cleanup that removes AI-generated bloat while preserving functionality. Runs pass-by-pass with test verification after each pass. Activate after kraken/spark complete a feature, or when a codebase needs hygiene work.

SKILL.md

ai-slop-cleaner.SKILL.md
name: ai-slop-cleaner
description: Post-implementation cleanup that removes AI-generated bloat while preserving functionality. Runs pass-by-pass with test verification after each pass. Activate after kraken/spark complete a feature, or when a codebase needs hygiene work.

AI Slop Cleaner

AI code generation produces working code. It also produces unnecessary code alongside it. This skill removes the unnecessary parts while keeping everything that matters.

What Is "AI Slop"?

AI slop is code that:

  • Works, but shouldn't exist
  • Adds complexity without adding value
  • Was clearly generated to pad a response rather than solve a problem
  • Suggests the author wasn't thinking, just generating

Common slop categories and their signals:

| Category | Signal | |----------|--------| | Dead imports | Imported but never referenced in the file | | Unused variables | Declared, never read | | Commented-out code | Blocks of `// old code` or `/* removed */` | | Debug remnants | `console.log`, `print()`, `debugger`, `fmt.Println` | | Obvious comments | `// increment counter` above `count++` | | Redundant JSDoc | `@param name - the name` above `name: string` | | Premature abstractions | A factory that creates exactly one thing | | One-use helpers | Private function called exactly once, trivially inlinable | | Overly generic types | `<T extends object>` when `T` is always `User` | | Over-parameterized | `fn(a, b, c, d, e)` where 4 params never vary | | Unreachable branches | `if (false)` or `if (isLoggedIn && !isLoggedIn)` | | Speculative features | Code paths for requirements that don't exist | | Copy-paste duplication | Two blocks identical except one variable name | | Placeholder remnants | `TODO: implement`, lorem ipsum, example data in prod |

The Prime Directive

**Tests are sacred. Never clean test files.**

Tests exist to protect behavior. Any cleanup that breaks a test reveals that the "slop" was actually load-bearing. That is good information. The test wins.

Regression-Safe Workflow (Non-Negotiable)

BEFORE ANYTHING: Run full test suite → all tests must pass (baseline)

FOR EACH PASS:
  1. Identify targets for this pass category
  2. Apply cleanup
  3. Run tests
  4. If tests pass: keep cleanup, continue
  5. If tests fail: git checkout -- . (revert), skip this pass category
  6. Log what was reverted and why

AFTER ALL PASSES: Run full test suite → confirm all tests still pass
Report: lines removed, files touched, passes skipped, reason for each skip

Never batch multiple pass categories together. If combined changes break a test, you cannot know which change caused it.

The 7 Cleaning Passes

Pass 1: Dead Imports and Unused Variables

**Risk: Very Low**

What to remove:

  • Import statements where the imported name never appears in the file body
  • Variables declared with `let`/`const`/`var` that are never read after assignment
  • Function parameters that are never referenced inside the function body (TypeScript: prefix with `_`)

Before:

import { useState, useEffect, useCallback, useMemo } from 'react'
import { formatDate } from '@/lib/utils'
import { ApiClient } from '@/lib/api'

export function UserCard({ user }) {
  const [count, setCount] = useState(0)
  const formatted = formatDate(user.createdAt)

  return <div>{user.name}</div>
}

After:

import { useState } from 'react'
import { formatDate } from '@/lib/utils'

export function UserCard({ user }) {
  const [count, setCount] = useState(0)
  const formatted = formatDate(user.createdAt)

  return <div>{user.name}</div>
}

Note: `count`, `setCount`, and `formatted` are still present because they may be used elsewhere in a larger component. Pass 1 only removes imports.

Pass 2: Commented-Out Code and Debug Statements

**Risk: Very Low**

What to remove:

  • Any block of commented-out code that is not an active TODO or architectural note
  • `console.log`, `console.debug`, `console.warn` (unless it is a legitimate error logger)
  • `debugger` statements
  • `print()` in Python when not serving as actual program output
  • `fmt.Println` in Go debug instrumentation

Before:

async function processOrder(orderId: string) {
  console.log('processing order', orderId)
  const order = await db.orders.findById(orderId)
  // const cached = await cache.get(orderId)
  // if (cached) return cached
  console.log('order fetched:', order)

  const result = await payments.charge(order)
  // TODO: add retry logic here
  // console.log('charge result', result)

  return result
}

After:

async function processOrder(orderId: string) {
  const order = await db.orders.findById(orderId)

  const result = await payments.charge(order)
  // TODO: add retry logic here

  return result
}

Rule: `// TODO:` comments are preserved. They are documentation of known gaps, not slop.

Pass 3: Obvious Comments and Redundant Documentation

**Risk: Low**

What to remove:

  • Comments that restate the code in plain English without adding context
  • JSDoc `@param` blocks that just repeat the parameter name and type (TypeScript already says this)
  • Section dividers that add no structure (`// ===== COMPONENT =====`)
  • End-of-block comments (`} // end if`, `} // end for`)

Before:

/**
 * Gets a user by ID.
 * @param id - the user ID
 * @param db - the database instance
 * @returns the user object
 */
async function getUserById(id: string, db: Database): Promise<User> {
  // Query the database for the user
  const user = await db.users.findById(id)

  // Return the user
  return user
} // end getUserById

After:

async function getUserById(id: string, db: Database): Promise<User> {
  return db.users.findById(id)
}

Keep comments that explain WHY (business rules, performance choices, known gotchas). Remove comments that explain WHAT (the code already says what).

Pass 4: Dead Code (Unreachable Branches)

**Risk: Medium — Run tests immediately after**

What

Read more
Ships withvibecosystem

Your AI software team. Built on Claude Code. vibecosystem turns Claude Code into a full AI software team — 138 specialized agents that plan, build, review, test, and learn from every mistake. No configuration needed — just install and code.

Get the whole plugin

Other skills on vibecosystem.