Happy Path Works
Available now

Free skill audit

Point it at a SKILL.md and it grades the file against seven gates, tells you exactly what is missing on each failure, and returns an exit code you can put in a script. It is free, its source is public, and it applies the same floor every paid skill here has to clear.

What a run looks like

skill_audit — skill-audit SKILL.md scripts: skill_audit.py [D] Upload-safe description PASS description is 698 of 1024 chars and holds no XML-tag shape. [R] References resolve PASS All 1 bundled path(s) resolve. (1 workspace path(s) skipped — not this skill's to resolve) [1] Names the gap PASS A gap/failure-mode statement is present. [2] Deterministic entry PASS A deterministic entry (prefix or unambiguous condition) is present (`audit:`). [3] Enforced hard-fails PASS Hard-fails are present and the skill ships a script (skill_audit.py). [4] Verify before voice PASS A hard constraint is present and a verification step is described. [5] Loud failure, named exit PASS Scope boundaries name an explicit exit (if X, refuse and do Y). [6] No prior-chat references PASS No phrasing that leans on an earlier chat ("as we discussed", "like last time"). [7] Deciding example PASS A worked example is present and shows a catch, not just the happy path. FAIL 0 REVIEW 0 NOT CHECKABLE 0 PASS 9 VERDICT: PASS Every gate came back clean.Not graded: whether the skill works in a fresh session. The lint reads files; only a run shows what a model does with them. -> Open a session where your own project instructions do not load, install the skill from its archive, give it a real task that starts with `audit:`, and check what it does against what the skill promises.

Output captured verbatim from a run of skill_audit.py against its own skill file on 2026-09-13; the path shown is the argument, so you pass your own. exit 0 = pass · exit 2 = review · exit 1 = fail · exit 3 = error, nothing gradable at that path. Put it in a pre-commit hook or a CI step; the code is the interface.

Measured

What it does to work that is already good.

Run against a known-good corpus of thirty-two skills — every skill in Anthropic's official plugin marketplace, plus this one — thirty come back REVIEW, one PASSes, and one FAILs. The PASS is the run printed above. The FAIL is not a false positive: it is a template skill whose description carries an XML-tag shape, which claude.ai refuses at upload — it installs nothing and says why only at that moment. The lint caught a file the platform would have rejected. Nothing else in the corpus is flagged, and that is the intended result: a tool that flags good work is a tool you stop running.

Run against a fixture built to fail — a countable constraint asserted and never counted — it FAILs, names gate 4, and prints the one thing missing. Repair that line and the same skill comes back clean. Six fixtures ship with the tool: that constraint and its repair, a reference that does not resolve and the same skill with it intact, and two descriptions the platform refuses. A test asserts each returns the code it should, on every push, on Python 3.8 and 3.12.

Behind those sits a development gate of twenty-eight probes: every detector must fire on the real anti-pattern and stay quiet on the known-good phrasing that used to trip it by accident. Precision without recall is a tool that says everything is fine.

Corpus measured 2026-09-19, against the marketplace as it stood that day — thirty-one skills. It changes whenever Anthropic ships; the figure is dated rather than maintained.

The seven gates

What a failure looks like.

1
Names the gap
The description explains what the skill does but not what goes wrong without it.
2
Deterministic entry
The trigger is a list of forty keywords and a hope.
3
Enforced hard-fails
The file says "never ship X" and nothing checks for X.
4
Verify before voice
The skill asserts a character count it never counted.
5
Loud failure, named exit
A boundary reads "stay in scope" with no instruction for what to do at the edge.
6
No prior-chat references
The skill leans on a conversation it does not contain — "as we discussed", "like last time". A fresh session never had that conversation, so it quietly does something else.
7
Deciding example
The only example is the obvious case working.

Install

Drop the whole skill-audit folder into your skills directory, each skill in its own folder:

Claude Code (personal)~/.claude/skills/skill-audit/
Claude Code (one project)<project>/.claude/skills/skill-audit/

No dependencies to install. If you can run python3 --version, you can run this.

Install location differs by surface, and the two do not sync. A folder you drop into ~/.claude/skills/ or .claude/skills/ is local to Claude Code on that machine. Skills added to your claude.ai account are the ones that reach the web app, Cowork sessions, cloud sessions and routines. Installing one place does not install the other, so put it wherever you actually work — or both.

Three ways to get it

GitHub — clone it, read it, fork it.
Gumroad — $0 or pay what you want, if you would rather have it as a download.
Newsletter — subscribe and the download link comes with the first issue.

Get the download by email

Subscribe and the download link comes with the first issue. Roughly monthly after that; unsubscribe from any issue.

What the paid audit adds

  • Scope-boundary analysis across a whole skill directory, not one file.
  • Trigger collision detection — which of your skills will fire on each other's inputs.
  • Session-hygiene scoring.
Session Discipline, January 12 →