DEV Community

Joan Winter
Joan Winter

Posted on

Stop prompting, start encoding: turning engineering discipline into Claude Code skills

Claude Code is remarkably capable. But out of the box it does what you prompt — and most prompts quietly skip the checks a senior engineer would never skip. Ask it to "fix the slow endpoint" and it will happily eager-load a relation and call it done, without ever proving the slowness was an N+1 or measuring the result. The capability is there. The discipline is not — because you did not ask for it.

The fix is not a bigger prompt. It is encoding the workflow as a skill.

What a skill actually is

A Claude Code skill is a Markdown file (SKILL.md) with a little frontmatter and a body of instructions. The frontmatter is what makes it discoverable:

---
name: n-plus-one-hunter
description: "Find and fix N+1 query problems and hot-path database waste. Use when pages are slow, DB CPU is high, or before traffic events."
---
Enter fullscreen mode Exit fullscreen mode

That description is load-bearing: it is how Claude decides when to reach for the skill. Write it as "use when X" and the model matches it to the situation on its own.

The body is where discipline lives. The difference between a skill that works and one that produces confident nonsense comes down to one principle.

Verification gates beat goal descriptions

Compare two ways of writing the same step.

Goal description: "Remove dead code carefully."

Verification gate: "A symbol is provably dead only if ALL hold: no references in code, templates, configs, or string literals (grep with and without word boundaries — dynamic languages call things by string); not part of any public API surface; not framework-magic (signals, fixtures, tasks); and the test suite passes with it removed. Anything failing a criterion is quarantined, not deleted."

The first is a vibe. The second is a checklist the model cannot skip without noticing. Same goal — wildly different reliability, especially on the tenth run when the novelty has worn off.

A worked example

Here is the spine of an N+1 hunting skill, compressed:

  1. Locate suspects statically. Identify the ORM and its lazy-loading idioms; grep for relation access inside loops, .map, and template iteration.
  2. Confirm with query counts — never fix an unconfirmed suspect. Set up query counting (assertNumQueries, an engine event listener, Prisma $on('query')). Exercise the endpoint at realistic N (20+, not 2). A real N+1 shows the query count scaling with N. Record: endpoint, N, count, statement.
  3. Fix in preference order: eager-load, then annotate/aggregate in the DB, then restructure, then cache (last resort — and say so, because it hides the problem).
  4. Prove it. Re-run the counter, record before/after in the commit ("queries: 142 → 4 at N=50"), run the full suite (eager loading changes queryset semantics — a test change is a red flag, not a rubber stamp).

Notice step 2. Without the "confirm before fixing" gate, an eager assistant optimizes things that were never slow and never measures whether it helped. The gate is the whole ballgame.

Try it

I packaged two of these as a free repo you can drop into any project:

  • readme-refresh — treat every claim in a README as something to verify against the code
  • pr-description — write the PR description from the actual diff, not from memory

https://github.com/joanwinter333-rgb/claude-code-skills-free

Install is a copy into .claude/skills/, then type / in Claude Code.

If they are useful, there is a full set of 10 (legacy audit, migration safety, security sweep, perf baseline, incident postmortem, and more) here: https://winterjoy1.gumroad.com/l/qnrbr

Honest note: these skill docs were authored with AI assistance and shaped by real production experience maintaining live systems. Every workflow was tested in Claude Code before release.

Top comments (0)