TL;DR — I read someone else's skill library, went back to my own 32 skills, and found every one of them was a tutorial. They all explained how to begin a task. Not one explained how to know you were finished, or what a wrong turn looks like on the way. Claude Toolkit 2.5.0 adds three sections — Common Rationalizations, Red Flags, Verification — to the nine skills where being wrong is expensive.
The gap
A skill file for a coding agent is a strange document. It's not documentation, because nobody reads it for reference. It's not a prompt, because it's loaded conditionally. It's closest to a playbook you hand a competent contractor on their first day: here's how we do this, here's what we care about, here's what will get you a phone call.
Mine were only ever the first third of that. Take the deploy skill before this release. It knew the deploy command, the SSH flow, the order of operations, how to run migrations. Everything about starting.
It said nothing about the moment that actually matters, which is when the agent — or a tired human — decides the deploy is done. bin/deploy exited 0. Is that success? The skill had no opinion. So the answer became whatever the model felt like, which on a good day is thorough and on a bad day is "the command exited 0, deploy complete."
That's not a model problem. That's a missing section.
Three sections, and why each exists
I added the same three headings to nine skills. Each one targets a different way work goes wrong, and the order matters — they run at different moments.
## Common Rationalizations — the arguments you'll make to yourself
A table. Left column: the excuse. Right column: what's actually true.
This is the one I expected to feel patronising and it's turned out to be the most useful. Bad engineering decisions are rarely made in ignorance. They're made with a reason — a sentence that sounds fine when you say it in your head at 6pm. Writing the sentence down next to its rebuttal takes away the "well, in this case…" move, because the case is right there in the table.
From the code-quality skill:
| Rationalization | Reality |
|---|---|
| "Just baseline it, it's legacy code" | A baseline entry is a permanent, invisible ignore. Baseline to unblock CI, then file the issue — a baseline that only ever grows is a broken quality gate. |
| "Level 5 is good enough for now" | Levels only ever ratchet up when someone forces them. "For now" has been the level for two years in most codebases. |
| "Pint fixed it, so the code is reviewed" | Pint fixes spacing and ordering. It has no opinion on the god class it just reformatted. |
"Adding @var fixed the error" |
It silenced the error by lying to the analyser. If the annotation is wrong, you have made the codebase less safe, not more. |
That first row cost me a real bug this week, in a different repo. Static analysis had flagged two classes as used zero times. Someone baselined the warning rather than deleting the files — and one of those "unused" classes was supposed to be doing PII redaction. The baseline hid it for months.
The rebuttal has to be specific and mechanical, not moral. "Don't be lazy" changes nothing. "A baseline that only ever grows is a broken quality gate" is an argument.
## Red Flags — signals visible during the work
A flat list of observable things. Not principles — sightings. If you can see it in a diff, a terminal, or a PR, it belongs here.
From the debugging skill:
-
sleep()or--retryadded to make a test pass - The same bug fixed in three different callers in one PR
- A
->skip()or->markTestIncomplete()added during a bug fix -
dd(),dump(),ray()orLog::debug('here')left in the diff - A diff that touches files unrelated to the reported failure
- Blaming the framework, the database or the browser before reading your own stack trace
And from deploy-app, where the stakes are higher:
- Deploying without a fresh, size-checked backup
-
migrate:fresh,db:wipe, or--seedtyped against a production host - New
.envkeys added to the repo but never set on the host - A deploy that also contains a refactor
-
APP_KEYin the diff
Notice the second entry in the debugging list. "The same bug fixed in three different callers" is not a style complaint — it's near-proof that the fix is at the wrong layer. That's the value of the format: a red flag encodes a diagnosis, compressed into something you can spot rather than something you have to reason about.
## Verification — the exit gate
A checkbox list run before the work is called done. Not a summary of the skill; a set of conditions that can each be false.
## Verification
Before calling a bug fixed:
- [ ] The original failure reproduces on demand (or its impossibility is documented)
- [ ] The root cause is stated in one sentence, and it is a cause, not a symptom
- [ ] Every caller of the changed function was checked, not just the reported path
- [ ] A regression test exists, and it fails when the fix is reverted
- [ ] The full test suite passes, not just the new test
- [ ] No debug output (`dd`, `dump`, `ray`, `Log::debug`) remains in the diff
- [ ] The diff contains the fix and its test — nothing else
- [ ] If the bug reached production, the blast radius is stated: who was affected, what data, over what window
"A regression test exists, and it fails when the fix is reverted." If I could keep one line out of this entire release, it'd be that one. A test that passes both with and against your fix is a test of something else. Almost nobody checks, because checking means deliberately breaking working code, and it feels like a waste of ninety seconds. It's the only thing that distinguishes a guard from a decoration.
Same energy in the last box. "The blast radius is stated" is not a coding task at all — it's the part of incident work that gets skipped because the code is already fixed and the adrenaline is gone.
Why the end of the file, not the top
The obvious objection: an agent reads the whole skill, so why does placement matter?
It matters because the failure isn't at the entry, it's at the exit. Instructions at the top of the file compete with the user's actual request and lose. A checklist under a ## Verification heading is a thing you can be asked to run — "run the verification section" — and the answer is auditable, box by box. It's a different mode: not guidance, but a gate.
That's the reframe I'd offer anyone writing skills for a coding agent:
A skill is a policy document, not a tutorial. The tutorial part is the cheap part — the model mostly knows the framework. What it doesn't know is your organisation's definition of done, and which shortcuts you've been burned by.
The happy path is where the model is already strong. The failure modes are where it needs you.
Coverage, hygiene, and the boring half
Three other things landed in 2.5.0, and two of them are only interesting as process lessons.
Two agents had no backing skill. The role personas — code reviewer, QA engineer, DevOps engineer and so on — load skills as their playbook. Two were pointing at nothing. So the release adds:
-
debugging— the five-step triage (reproduce, localise, reduce, fix at the root, guard), a table of Laravel-specific traps (N+1 masked as a timeout, queue jobs failing silently on the wrong connection, config cache serving stale values, Livewire state desync), flaky-test diagnosis, and two reference files. -
security-hardening— defensive OWASP-in-Laravel, authorization coverage auditing, uploads, secrets, production config, CI/CD hardening. It's the proactive counterpart to the reactive soc-analyst and log-monitor pair I already had.
Step 1 of that triage is blunter than I'd usually write:
You have not started debugging until the failure happens on demand. … If you cannot reproduce it, say so plainly and stop. A fix for a bug you never saw fail is a guess wearing a diff.
My own convention file was being violated by my own skills. The repo's CLAUDE.md says every skill ships a references/ directory and a Reference Files table. Two skills had neither, and both were orphaned — no agent loaded them. Fixed, and both are now wired to an agent.
That's the unglamorous lesson and it applies well beyond agent skills: a convention nobody checks is a preference. Mine had drifted in the exact way today's other repo drifted, where a hand-maintained SECURITY.md mirroring composer.json had gone wrong in every single entry.
Companions, installed not vendored. Two external tools are now referenced from the skills that benefit — a codebase knowledge-graph tool for research and architecture work, and a minimalism-ladder plugin for the code-review and refactoring skills. Both are installed from upstream, never copied into the repo. Both are optional: the installer reports a skip when prerequisites are missing, and every referencing skill states its fallback, so a missing companion degrades the skill rather than breaking it. New --no-companions flag for anyone who'd rather not.
Copying someone else's tool into your repo is how you end up maintaining a fork of it by accident.
And a smaller thing that changed every response
The default output format is now TLDR + tables, written as a delimited managed block into ~/.claude/CLAUDE.md so it applies to every prompt. Replaced — never duplicated — on reinstall, and the user's own instructions are untouched.
A new /output command switches mode per session: tldr, table, verbose, bullets, narrative, json, raw. Three rules keep it from becoming a footgun:
- A one-off instruction in the prompt always beats the session mode. "explain in detail" wins for that reply, then the mode returns.
-
Never drop required content to satisfy a format. A safety caveat, a failing test, an unmet requirement or a stated assumption gets reported in every mode —
tldrandjsonincluded. tldris not permission to omit;verboseis not permission to pad.
That middle rule is the same idea as the verification section, honestly. A format is allowed to shape the prose. It is not allowed to quietly delete the bad news.
Takeaway
If you're writing skills, playbooks, or CLAUDE.md files for a coding agent, the highest-leverage paragraph you can add isn't another example of the happy path. It's the answer to two questions:
- What excuse will be made for cutting this corner, and what's the rebuttal?
- What has to be true before this is done — as boxes that can each be false?
The model already knows the framework better than your docs do. What it can't know is which shortcut burned you in March.
34 skills, 20 agents, 12 commands. MIT, and it's all at github.com/nasrulhazim/claude.
Next on the list: making the nine verification sections runnable as an actual gate rather than a prompt the agent is trusted to honour. A checklist you can skip is, by today's standard, a decoration.
Top comments (0)