---
name: engineering-roast
description: Roasts a codebase the way a static analyzer would — SonarQube-style sweep over bugs, vulnerabilities and hotspots, code smells, duplication, complexity, and test coverage — with every finding backed by a receipt (file:line), a severity, a one-line roast, and a concrete minimal fix. Use when the user asks to roast, audit, or critique code honestly, asks "what's wrong with this codebase", or wants findings a quality-gate tool would raise.
category: implementation
keywords: critique, roast, anti-patterns, over-engineering, code-smells, duplication, complexity, technical-debt, coverage, security-hotspots
---

# Engineering Roast

A roast is a finding with a receipt, a severity, and a fix. Without the receipt it's an opinion; without the severity it can't be ranked; without the fix it's just mean. Every roast in this skill carries all three, or it doesn't ship.

## When to apply

Use when the user asks for an honest, unsparing take on a codebase, module, or process — "roast this", "audit this like SonarQube", "what's the crap here", "review it like a quality gate". The target is *practices*, never people: you roast the ceremony, not the engineer.

## The mechanical sweep

Quantitative gates first — these are the axes a static analyzer grades. Defaults below are starting points; tune per repo. Every breach is a finding with a receipt.

- **Bugs (reliability)** — swallowed exceptions, ignored return values, null/undefined derefs on optional fields, resource leaks (unclosed handles/connections), `==` vs `===`-class mistakes, race conditions on shared state, unreachable code.
- **Vulnerabilities & hotspots (security)** — hardcoded secrets or keys, SQL/command injection surfaces, weak or homegrown crypto, unsafe deserialization, permissive CORS, auth checks done in the UI only. A *hotspot* is suspicious-but-unconfirmed: flag it, ask the one question that confirms or clears it, don't assume.
- **Code smells (maintainability)** — functions over ~60 lines, files over ~500, more than ~4 parameters, nesting deeper than 3, boolean-flag parameters doing two jobs, comments narrating bad code instead of fixing it.
- **Duplication** — the same block (≥ ~10 lines) appearing in two-plus places; near-duplicates differing by one literal. The fix is usually one extraction, not a framework.
- **Complexity** — cyclomatic > 10 or cognitive > 15 in one function; the function is a state machine pretending to be a script. Split on the domain seams, not the line count.
- **Coverage & test honesty** — critical paths with no test, assertions removed to make tests pass, snapshots asserted against whatever the code currently does, "temporary" `skip`s older than a sprint.
- **Dead code & debt markers** — commented-out blocks, unused exports and flags, TODO/FIXME/HACK counts and their age. Old markers are sediment: date them, schedule them, or delete them.

## The classic hits

Qualitative sins the mechanical sweep can't see — hunt these on the second pass:

- **Speculative generality** — an interface with one implementation, a factory producing one product, config flags nobody sets. Built for reuse that never got reused.
- **Resume-driven development** — microservices for a team of two, a message queue where a function call would do, the shiny framework adopted last quarter and abandoned by module three.
- **Abstraction theater** — three layers of indirection to call one SQL query.
- **Ceremony theater** — a 40-item PR checklist nobody reads, a design doc for a bug fix, a weekly "sync" that is a status read-out.
- **God modules & cycles** — one file importing everything, knowing everything, tested by nothing; packages that import each other in circles.
- **Metric worship** — coverage gamed with snapshot tests, "velocity" points argued like scripture, dashboards nobody actions.

## Workflow

1. **Collect receipts** — sweep the mechanical axes, then hunt the classic hits. Log concrete evidence: `file:line`, a diff stat, a CI log line. No receipt, no roast. This is the legwork; do it before writing a single joke.
2. **Name the sin** — match each receipt to an axis or a classic hit. One sentence of diagnosis: *what* the pattern is and *why* it costs money.
3. **Assign severity** — on the analyzer's ladder: **blocker** (data loss, security hole, prod breakage), **critical** (bug likely in real use, secret on disk), **major** (smell actively costing time — duplication, god module), **minor** (size/complexity breaches, dead code), **info** (hotspots to review, style debt).
4. **Land the joke** — one line, dry, aimed at the practice. Humor is seasoning; the diagnosis is the meal. If the joke needs three lines, it's a lecture — cut it.
5. **Prescribe the fix** — one concrete, minimal action per finding: delete it, inline it, extract once, add the missing test. Link the relevant skill when one exists (see Related skills). "Rewrite it all" is not a fix, it's a fantasy.
6. **Deliver the roast** — findings ranked by severity (most expensive first, never funniest first), then a scorecard closing the loop like a quality gate:

   ```
   ## <severity>: <sin name>
   **Receipt:** file:line — what's there
   **The crime:** one-sentence diagnosis
   **The roast:** one-line joke
   **The fix:** minimal concrete action (link skill if applicable)

   ## Scorecard
   | Axis            | Grade | Open findings |
   |-----------------|-------|---------------|
   | Reliability     | B     | 2             |
   | Security        | C     | 1 blocker     |
   | Maintainability | D     | 7             |
   | Coverage        | D     | 3             |
   | Duplication     | B     | 2             |

   Grades: A clean · B minor debt · C real pain · D costing daily · E stop shipping
   ```

7. **Stop at the top three** — deliver the highest-severity findings and the scorecard, offer the rest on request. A roast list as long as the codebase is a filing cabinet, not a critique.

## Rules

- Every finding carries a receipt — no vibes-based critiques.
- Every finding carries a severity and a fix — cruelty without remedy is just noise.
- Gates are defaults, not gospel — a breach with a reason is a conversation; a breach without one is a finding.
- Punch at practices, not people — no names, no blame, no "who wrote this garbage".
- Fix beats lecture — if the fix is a one-line deletion, say "delete it" and stop.

## Related skills

- [lean-implementation](/skills/lean-implementation) — The discipline most of these fixes boil down to.
- [minimal-fix](/skills/minimal-fix) — How to shape each prescribed fix.
- [domain-modularization](/skills/domain-modularization) — The remedy for god modules and abstraction theater.
