All skills
asyrafhussin avatar

/code-slop

@346603c

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".

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/code-slop

This session only. Nothing lands on disk.

rulesstyle-debug-artifacts.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Debug Artifacts Left in Production Code

Impact: HIGH (console.log, dd(), dump(), var_dump — AI's exploratory leftovers ship to production)

console.log("here"), console.log("got user", user), dd($order), dump($result), var_dump($payload), print_r($data), echo $error — these are the breadcrumbs left from when the developer (or AI) was debugging. They ship to production and:

  • Leak sensitive data into stdout / log aggregators (PII, tokens)
  • Bloat production logs to the point you can't grep for real signal
  • dd() literally halts execution — if it reaches prod, your endpoint returns "1" + var_dump output instead of JSON

AI is particularly bad about this because the model tends to add console.log("got result", x) "to help with debugging" and rarely removes it before "finalising" the function.

Incorrect

// ❌ Debug artifacts left in

async function processPayment(order: Order, token: string): Promise<Charge> {
  console.log('processPayment start', order.id);                  // shipped
  console.log('token', token);                                    // SHIPS THE TOKEN
  const charge = await stripe.charges.create({ /* ... */ });
  console.log('got charge', charge);                              // shipped
  return charge;
}
// ❌ Same in PHP
public function processWebhook(Request $request): JsonResponse
{
    $payload = $request->json()->all();
    dd($payload);                                                 // halts execution; returns a debug page
    // …rest never runs
}

public function calculateTax(Order $order): Money
{
    dump($order);                                                 // prints to stdout in production
    print_r($order->items);
    $taxRate = 0.06;
    var_dump($taxRate);
    return $order->subtotal->multiplied($taxRate);
}

Why it's slop:

  • dd() in a controller is an outage — the request never completes
  • console.log('token', token) is a credentials leak; on serverless logs, every Stripe call ships the token to CloudWatch
  • dump() / var_dump() show up in HTTP responses if not in a CLI context (especially during artisan tinker or test failures)
  • A repo with 50+ stray console.log in production paths signals nobody is reading their own code before merging

Correct

// ✅ No debug; if logging matters, use the proper logger with context
import { logger } from '@/lib/logger';

async function processPayment(order: Order, token: string): Promise<Charge> {
  // Real logger — structured, redacts secrets, levels enforced
  const log = logger.child({ orderId: order.id });
  log.info('payment.start');

  const charge = await stripe.charges.create({ /* ... */ });

  log.info('payment.success', { chargeId: charge.id, amountCents: charge.amount });
  return charge;
}
// ✅ Structured logging at the boundary; no debug() calls

public function processWebhook(Request $request): JsonResponse
{
    Log::withContext([
        'webhook_id' => $request->header('Stripe-Webhook-Id'),
        'event_type' => $request->json('type'),
    ])->info('webhook.received');

    // … actual handling …

    return response()->json(['ok' => true]);
}

Why it reads human:

  • A logger with structured fields and levels (info/warn/error) — not stdout spam
  • Tokens / secrets get redacted by the logger (or not logged at all)
  • The log lines are intentional, useful for production debugging, and won't break the response

When debug calls in production code ARE warranted

Rare. Usually zero. Specific cases:

  • Logs in well-defined CLI scripts that are meant to be verbose: a one-off data migration script can use echo / console.log freely
  • Test-only files (*.test.ts, *Test.php) — fine to keep debug there during development
  • Explicit if (DEBUG_MODE) console.log(...) wrapped behind a feature flag — fine, but rare in practice

Production controllers, services, jobs, listeners, middleware: zero raw debug calls.

Detection

# JavaScript / TypeScript — console.log in production code
grep -rEn '\bconsole\.(log|debug|info|warn)\(' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' \
  src/ resources/js/ 2>/dev/null \
  | grep -v -E '\.test\.|\.spec\.|/__tests__/|/scripts/'

# PHP — debug helpers
grep -rEn '\b(dd|dump|var_dump|print_r|var_export)\s*\(' --include='*.php' \
  app/ 2>/dev/null

# CI gate — block PRs that introduce debug artifacts
NEW_DEBUG=$(git diff --diff-filter=ACM origin/main...HEAD -- 'app/**/*.php' 'src/**/*.ts' \
  | grep -E '^\+.*\b(console\.log|dd\(|dump\(|var_dump\(|print_r\()')
test -z "$NEW_DEBUG" || { echo "Debug artifacts in PR:"; echo "$NEW_DEBUG"; exit 1; }

ESLint rules:

{
  "rules": {
    "no-console": ["error", { "allow": ["warn", "error"] }]
  }
}

PHPStan + a custom rule can flag dd/dump similarly. PHP-CS-Fixer has a no_debug_print rule.

Reference: Laravel Logging docs · ESLint no-console · Pino structured logging

Source: SKILL.md on GitHub

No alerts16d3 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides heuristics for auditing code quality in PHP and TypeScript projects and is generally safe. It contains a low-severity risk of indirect prompt injection because it processes untrusted source code and PR diffs using shell-based analysis tools without defining boundary markers or sanitization procedures.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

Signed by skilld at 346603c. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 5 months ago
metadata
{
  "author": "agent-skills",
  "version": "1.0.0"
}

README badge

README badge for asyrafhussin/agent-skills/code-slop