How I work with Claude

The explain-diff review, rendered as an HTML page of file cards

Role

Design engineer

Since

2026

Source

studiokyoung/claude-skills

How I work with Claude

Overview

Claude Code skills I use on my own work. Each one is a working method of mine written out far enough that an agent can run it: what to look at, in what order, what to refuse to do, and what the output has to look like. They started as things I kept repeating in chat, so I moved them into skills and let the review rounds tighten them. These are the ones that survived contact with real projects; more follow as they earn it.

An agent finishes, and 200 lines are waiting for a yes or no

The problem

Reading a diff tells you what changed, but the question in front of you is a different one: why does this hunk exist, and does it deserve to? Some of what came back is the thing you asked for. Some of it is a defensive try/catch nobody wanted, a debug log left behind, a rename that came along for the ride. Approving all of it is how slop enters a codebase, and reading every line yourself is how the speed you gained goes back out the door.

/explain-diff/explain-diff html

the working tree, then the browser view

Why does this hunk exist, and does it deserve to?

Two axes

Provenance. Why this change exists, dug out of the session conversation, the plan or task spec it was following, the commit message, the tests that moved with it, and the repo conventions, in that order. When nothing supports a change, the report says no evidence found rather than inventing a reason. Fabricating a plausible motive is the failure the skill is written hardest against.

Verdict. Whether it has earned its place in the change.

✅ keep
Directly tied to the request, and the evidence is clear.
✂️ cut
Unrelated to the request, or slop. Allowed only when deleting it provably leaves the requested behaviour intact.
🔻 trim
Right direction, too much of it. The smaller form is named in one line.
❓ ask
Confidence is 7 or lower out of 10, so no verdict gets made. One question for you instead.

A row is a logical unit of change, not a physical hunk, so one rename across 12 hunks is one row. Rows that are not keep get a short detail block with the excerpt and the argument for cutting or trimming it. When everything is a keep, the report is the table plus one line saying so.

The explain-diff HTML report: a verdict summary, then one card per file with the reasoning above a side-by-side diff

The html gate view on a synthetic four-file example, one of each verdict.

It reports and stops

Boundaries

Nothing is edited until you say which rows to apply, on the theory that a gate which deletes first is not a gate.

/code-review
is this wrong? Exhaustive correctness bugs.
/simplify
can this be cleaner? Style and structure, applied.
explain-diff
why is this here, and should it be? Report only.

The three do not overlap. If a real bug surfaces while reviewing, it gets listed separately, capped at three, and handed to /code-review, with defects this diff just created ranked ahead of pre-existing ones.

How I use it

In practice

I built this because I was approving agent diffs faster than I was reading them. Now I run it on the working tree before I accept what an agent just wrote, and the html view when the batch is too big for the terminal or when somebody else has to look at it.

The rule that earns its keep is no evidence found. A change nothing in the session asked for is usually the change I would have regretted, and naming that absence out loud is what makes it visible.

It went through its own gate: reviewing the v2 diff caught an untracked-file blind spot and an evidence-ladder fallback that skipped the session docs.

Six moves

How I direct the work

Six moves I make on every piece of AI-directed work. Two of them are checks: the second is the first filter, the sixth is my own final pass on the result.

  1. Lock the invariants, then watch for regressions. The rules that must not move get written down first, and every later pass gets checked against them.
  2. Verify the artifact, not the code. QA is the thing on the screen, on the real device, in the real browser. A green diff is not a result.
  3. Inject the context the model does not have: who the users actually are, what devices they hold, what the product is for. Performance and design calls come from that, not from the test machine.
  4. Decide where the branch lives. Where a fork or a gate goes is an organizational call, and hiding it from the next editor is not allowed.
  5. Delegate the research. Public knowledge is the model's job to fetch; internal contracts and configuration stay with me.
  6. Interrogate the mechanism. When a diff or a behavior looks off, I bring a hypothesis and dig until it is understood. That is the quality gate, and the way I keep learning.

A finding is not a fact. Verification makes it a fact, so findings get verified before they get fixed, and the false alarms are kept on a list so nobody re-fixes them.

One session conducts, workers build

The method

The session I type into does not write code. It holds the judgment: it reads the plan, writes a one-task brief with the exact values a builder needs, and dispatches a fresh worker agent that sees nothing but that brief. A second agent reviews the result against the brief, and the rule that makes reviews worth having is that the reviewer must run things: reproduce the bug, measure the claim, revert the fix and watch the test fail. Reading a diff and nodding is not a review here.

Conflicts do not wait for me. The conducting session decides, and every decision is written into a ledger as a ruling with what it costs if wrong. When a session dies mid-work, the next one reads the ledger and continues instead of re-deriving. Fix rounds are scoped and capped; a reviewer's finding either gets fixed, or gets parked with its ruling on the record.

Behind all of it sits a private knowledge graph the assistant reads before it works: who I am, how I decide, what every past project taught. The public repo carries the method; the graph carries me.

Now they fire on their own

The router

There is also a router: four hooks that make these fire on their own (a commit gate for verify, reminders for reuse-scout, a health check when a session starts or resumes), and a local run record for every invocation so the skills can be tightened from evidence.

/verify
The pre-commit gate as one command: git state, typecheck, tests, and viewport screenshots at 390, 768 and 1440 (a mobile app runs its maestro flows instead), reported as one honest PASS/FAIL table. Never says verified for a step that did not run.
/reuse-scout
A pre-flight scan before building anything: what the repo already has for each capability, which twin is canonical, and where new code is actually justified.
/skill-router
The operator end of the router. Says whether it is installed, which repos the commit gate covers, what the log decided and why a commit was denied, and installs or removes it behind an explicit yes.
/skill-review
The Friday ritual. Proves the router still fires, aggregates the week's run records into one deterministic report, and turns it into proposed edits to the skills and the rule table. Proposes; never edits on its own.

The toolbox has its own page.

/verify/skill-router/skill-review

the gate, the console, the Friday ritual

The loop closed on its first day

Evidence

On a mobile app the UI gate is the repo's maestro flows on a booted simulator, promoted from the first field run the run records captured, with that run's three traps encoded in the skill.

The records argued for the edit; the edit shipped the same day.

It happened again the same week: a run's own annotation said the screenshot tiles had missed the changed region, and the next day the skill gained an anchored tile that pins it. The page you are reading shipped through that gate, was denied once for a stale marker, and passed on a fresh verify.

Where it lives

Install

The skill is public at github.com/studiokyoung/claude-skills (MIT), packaged as a Claude Code plugin.

/plugin marketplace add studiokyoung/claude-skills/plugin install kyoung@studiokyoung

or symlink skills/explain-diff into ~/.claude/skills to keep the bare /explain-diff

node ~/claude-skills/router/install.mjs

adds the four hooks to settings.json, with a backup first; removable with --uninstall

Works