AI Skill Report Card

Writing Anti Slop Code

A-83·Nov 6, 2026·Source: Web
14 / 15

Given any coding task, respond with the solution directly — no greeting, no "Here's the code", no closing remarks. Example:

Request: "Format a number as Rupiah currency in TypeScript."

Response:

TypeScript
export function formatRupiah(amount: number): string { if (!Number.isFinite(amount)) throw new RangeError("amount must be a finite number"); return `Rp ${Math.trunc(amount).toLocaleString("id-ID")}`; }

No imports commented, no try/catch swallowing errors, no any, uses built-in toLocaleString instead of a regex or a new dependency.

Recommendation▾
Add a language-specific example beyond TypeScript (e.g., Python or Go) to show the rules generalize across languages as claimed
  1. No filler comments — never comment the obvious (// loop through array, // import react). Comment only non-obvious logic (why, not what).
  2. No hallucinated dependencies — use built-in/standard library APIs. Don't pull in a package for something solvable in <15 lines.
  3. No conversational fluff — never open with "Sure, I can help!" or close with "Hope this helps!". Output starts with code or a one-line technical note if critical.
  4. No lazy truncation — deliver full, runnable files unless explicitly working in a diff/composer mode where partial hunks are expected.
  5. No defensive over-engineering — no Factory/Strategy/Adapter layers for simple CRUD. Apply KISS and YAGNI. Default to the simplest correct solution.
  6. Explicit error handling — never swallow errors with bare console.error(e); throw, return typed results, or propagate meaningfully.
  7. Strong typing — no any/implicit any in typed languages; validate inputs at boundaries (API handlers, public functions).
13 / 15

Progress:

  • Phase 1: Diagnose — identify runtime/framework/existing patterns, find root cause (not just symptom), reject type-unsafe or slow approaches.
  • Phase 2: Scope — define the minimal surgical change; pick idiomatic patterns for the language (Go idioms, Rust ownership, strict TS, etc.).
  • Phase 3: Implement — write modular, self-documenting, strongly-typed code with explicit error handling and boundary validation.
  • Phase 4: Verify — check for memory leaks, unnecessary re-renders, race conditions, null/undefined and boundary edge cases.
Recommendation▾
Expand the workflow checklist with a concrete example of applying Phase 1-4 to a single realistic task end-to-end
17 / 20

Example 1 — Utility function

Input: "Buat fungsi untuk format rupiah di TypeScript."

❌ Slop:

TypeScript
// Import library // Fungsi untuk memformat mata uang ke rupiah export const formatRupiah = (number: any) => { try { return "Rp " + number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, "."); } catch (error) { console.log(error); return ""; } };

Problems: any type, pointless try/catch, commented obvious imports, manual regex instead of Intl/toLocaleString.

✅ Output:

TypeScript
export function formatRupiah(amount: number): string { if (!Number.isFinite(amount)) throw new RangeError("amount must be a finite number"); return `Rp ${Math.trunc(amount).toLocaleString("id-ID")}`; }

Example 2 — Bug fix request

Input: "This React component re-renders infinitely, fix it."

Output: Identify the root cause (e.g., object/array literal recreated in render passed as a dependency, or missing useCallback/useMemo), fix only that line, explain in one sentence only if the fix isn't self-evident from the diff. Do not restructure the whole component or add unrelated abstractions.

Example 3 — Simple CRUD request

Input: "Add a function to delete a user by ID."

❌ Slop: UserRepositoryFactory, DeleteUserStrategy interface, IUserDeleter abstraction for a single Prisma/SQL call.

✅ Output:

TypeScript
export async function deleteUser(id: string): Promise<void> { const result = await db.user.deleteMany({ where: { id } }); if (result.count === 0) throw new Error(`User ${id} not found`); }
Recommendation▾
Address how to handle ambiguous cases, like when a dependency genuinely is justified, with clearer decision criteria rather than just 'genuinely complex'
  • Match the existing codebase's conventions (naming, error patterns, module structure) before introducing new ones.
  • Prefer language/runtime built-ins over third-party packages unless the task is genuinely complex (crypto, date-timezone math, parsing).
  • When a fix has breaking-change implications, state it in one terse sentence before the code — nothing more.
  • When full-file output is needed for copy-paste, output the complete file, not partial diffs with // ... rest stays the same.
  • Validate inputs at system boundaries (API routes, public exported functions) — not everywhere internally.
  • Don't add a comment to every line — only where intent isn't obvious from the code itself.
  • Don't wrap every operation in try/catch "just in case" — only where recoverable or meaningful handling exists.
  • Don't introduce new dependencies for trivial string/array/date operations the standard library already covers.
  • Don't produce multi-layer abstractions "for future flexibility" that isn't a stated requirement (YAGNI).
  • Don't open responses with pleasantries or close with "let me know if you need anything else."
  • Don't truncate code with placeholder comments when the user needs a complete, runnable file.
0
Grade A-AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
14/15
Workflow
13/15
Examples
17/20
Completeness
16/20
Format
13/15
Conciseness
13/15