validate-skills
Skill3 starsChanged 10 days agoMITView on GitHub
the shape every skill pair must hold: the doc, its sidecar, its frontmatter (saves report to .construct/)
9 other projects use a version of this.
Adopted by
Most recently taken up by
- patinaproject/skillstheir own version, first seen Oct 15, 2026
- TitusKirch/skillstheir own version, first seen Oct 13, 2026
- blutarche/skillstheir own version, first seen Oct 1, 2026
- ivuorinen/skillstheir own version, first seen Sep 24, 2026
- PIXARTSeu/Synapsetheir own version, first seen Sep 14, 2026
- callstackincubator/agent-skillstheir own version, first seen Aug 7, 2026
Other versions9 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 9
- callstackincubator/agent-skills★ 1.7ksame name
- microsoft/vstest★ 976same name
- PIXARTSeu/Synapse★ 9same name
- blutarche/skills★ 4same name
- ivuorinen/skills★ 4same name
- TitusKirch/skills★ 2same name
- patinaproject/skills★ 1same name
- danielvogler/ai-skills-library★ 0same name
- thinkyou0714/claude-lab-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository3 other files it gives its agents.
- export-readmeSkill
- push-releaseSkill
- test-skillsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
13 rules. 0 are common, 5 are distinctive, and 8 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 24
every frontmatter rule above is judged by .claude/skills/export-readme/export-readme.sh at the readme source.
- Distinctive: line 32
put the use case first, since a truncated listing keeps its opening and loses its end
- Very specific: line 75
every field prints on every run, and one with nothing to say prints none
- Distinctive: line 115
no doc is required to carry one, since most fold the same steps into their numbered procedure
- Very specific: line 174
default branch resolution goes through git_default_branch, since symbolic-ref is denied
- Very specific: line 184
CREATE the file first if it does not exist, with # <audit_file> as its only line
- Very specific: line 218
RUN .claude/skills/validate-skills/validate-skills.sh after touching a trigger doc or its sidecar.
- Very specific: line 219
RUN .claude/skills/export-readme/export-readme.sh after touching frontmatter or a preamble.
- Very specific: line 222
STOP on a secret finding and ask the user before truncating it.
- Very specific: line 242
every field prints, in this order.
- Distinctive: line 243
every value is COPIED from the source named beside it, never composed fresh
- Distinctive: line 244
ask what they are actually trying to do, and what they have already tried
- Distinctive: line 246
run no step, write no file, and never fall through to step 1
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Instructions
the pair
a skill is one folder, named for its trigger, holding exactly two files:
SKILL.mdcarries the frontmatter and the numbered steps, and nothing above them<name>.shcarries the sidecar, and the wayfinding header for the whole pair- the doc has no wayfinder of its own, since two headers that can disagree is worse than one
- frontmatter opens line 1 with
namematching the folder, and adescriptiona reader sees metadata.kindis declared rather than guessed, and decides the rest of the frontmatterkind: triggeracts on the repo, so it setsdisable-model-invocation: true; prose is not a gatekind: specdescribes a shape, so it stays auto-loading and never sets that flag- every frontmatter rule above is judged by
.claude/skills/export-readme/export-readme.shat the readme source; this pair's own checks stop at the body, the sidecar, the pairing, and the index
the listing budget
description and when_to_use are the whole listing; everything else loads only once a skill does:
- the harness truncates the two of them, combined, at 1536 characters, and says nothing when it does
- past the cap the tail is dropped, so a skill can lose the clause naming when it fires and still list
- put the use case first, since a truncated listing keeps its opening and loses its end
descriptionsays what the skill does;when_to_usecarries trigger phrases and example requests- the body is charged only when the skill loads, so long reference prose belongs under the frontmatter
- longer still belongs in a sibling file the body names, which costs nothing until it is read
metadatais free-form and the harness ignores it, so it never counts against the cap- export-readme measures the cap at the readme source, where the text is edited, not here
the telemetry block
a doc that runs a sidecar opens its body with one, in this shape and no other:
## Telemetry
```!
.claude/skills/validate-skills/validate-skills.sh "$ARGUMENTS"
echo "sidecar exit: $?"- it already ran, so there is no command to issue
- no argument scans
plugins/whole; a path argument grades that pair alone scanned: N pair(s)→ what the run actually covered, which is never the maintainer skillsprobed: N free-text skill(s)→ the pairs run on an apostrophe goal, the one check that executessecrets:above 0 → STOP and ask before touching the match; a committed key is already leaked- fail (
sidecar exit> 0) → an ERROR landed, or a WARN did under--strict; quote the findings table verbatim inside a markdown code block, and fix nothing until the user has read it - success (
sidecar exit= 0) → reporterrors,warningsandsecrets, then work the findings list top to bottom;none — every machine-checkable rule holdsis the clean result --quickreports inline and writes nothing,--strictpromotes warnings,--keepholds scratch- IF
--quick, STOP after the inline report;audit_file: noneconfirms it, and nothing is appended
- the heading opens straight onto the bang block, since a blank line there reads as a gap
- the bullets close it flush, and each names one branch the sidecar can actually report
- a sidecar call under any other heading is an ERROR; unlabelled telemetry is telemetry nobody reads
- numbered steps start AFTER the block, at 1, since reading the output is not a step
- a spec that runs nothing carries no telemetry section at all, and `logs` is the one example
- an auto-loading spec guards the call on `$ARGUMENTS`, since a bare load must run nothing
## the help section
every skill answers `--help` the same way, so the section is COPIED rather than written. it sits
directly above `## Output Style`, and this doc's own `## Help` below is the canonical text:
- the fence holds placeholders, never one skill's filled values, so all of them stay identical
- that is what makes this one comparison instead of a shape per skill; a drift is a bad paste
- `HELP_BLOCK` in the sidecar is the source, and the doc is compared to it whole
- every field prints on every run, and one with nothing to say prints `none`
- each value is copied from the source named beside it, so two runs of one skill agree
- the sidecar carries the matching guard, since the bang block runs before the doc is read
- a help invocation refused only in prose has already paid for the run it was refusing
- the guard prints `help: requested` and exits 0, so the doc branches on a line rather than silence
- that marker earns a telemetry bullet, since a bare exit 0 otherwise reads as a clean run
- a doc that runs no sidecar carries the section anyway, and `logs` is the one example
## the subagent style
the output style is opt-in and a subagent never inherits one, so the LAST body heading of every
doc is `## Subagent Style`, and it cats that plugin's compressed brief into the turn:
```text
awk 'NR>1 && /^---$/ {p=1; next} p' "${CLAUDE_PLUGIN_ROOT}/subagent-styles/operator.md"- it closes the doc, so the task instructions lead and the format rule lands last
- a
##section after it is an ERROR, since that section would read as the conclusion instead - the command is compared byte for byte; a paraphrase cats nothing and reports the same clean run
CLAUDE_PLUGIN_ROOTresolves per plugin, so one identical line serves every skill in the tree- the awk sheds frontmatter, which is config for the picker and instruction to nobody
- the block carries no numbered step, since step numbers climb once across a whole doc
- it carries no bullet either; the missing-file case is already an ERROR two layers up
- a plugin that ships skills ships
subagent-styles/operator.md, or the block cats an empty file - the copies are one readme section exported three ways, never three files edited three times
the body
frontmatter and pairing can both be correct while the body is structurally broken, which is how a pasted archive shape corrupted two docs and every gate still reported clean:
- the body opens on
# Instructions, the one h1 above every##section, so the doc has a seam - that h1 is never the template boundary; counting it as one switches the step check off silently
- the first
#heading after it is the boundary: above it the doc instructs, below it templates - step numbers above that boundary climb, each appearing once; a repeat is two blocks fighting
- a heading closing no backtick it opened ate the line it was meant to reference
- an archive shape names the kind its own template h1 declares, never a sibling's
- a
<kind>or<Kind>placeholder means the generic shape was pasted and never written - the kind is read from that h1 and never from a mention, since a findings example may name a sibling
- an audit directory is named for the SUBJECT audited, so
gitis owned by/gitgud:audit - a verify list reads under
## Verify; fenced, it renders as sample output a reader skips - no doc is required to carry one, since most fold the same steps into their numbered procedure
the two blocks
every sidecar prints the same pair, in the same order, so each trigger doc reads one contract.
the name in a block header is the INVOCATION, so the header and the / menu can never disagree:
=== /plugin:skill telemetry ===
key: value
=== /plugin:skill handover ===
# a note explaining the block, or why it is empty
git command one
git command two
=====================telemetryis what was measured; the trigger doc branches on ithandoveris what the user runs; every line is runnable as written, notes stay commentedtriggeris the optional third block: what the trigger runs as a tool call, never a paste- a sidecar that needs to mutate emits the command instead of running it, into either block
- close every trigger with ONE copy-paste bash block holding the handover, in that same order
the exec bit
every sidecar and every hook is tracked 100755, since git records the mode an install copies:
- a
chmodthat never reached the index fixes the authoring machine and nobody else's - the failure lands on the user as
permission deniedfrom a path they did not write inject-support.shshipped100644and died on the first outside install, which is why this is a gate- the check reads
git ls-files -s, never the disk, so a local bit nobody committed still fails - an untracked file has no recorded mode yet, so it is skipped rather than guessed at
- hooks pair with no doc, so they are walked repo-wide once instead of per skill
- the repair is
git update-index --chmod=+x <path>, which the finding prints in full shared/*.shstays100644on purpose, since those are sourced and never exec'd
the smoke case
below the help guard, every sidecar carries one --test case, which /test-skills is built to run:
- the case is one line:
case " $* " in *" --test "*) echo "test: ok"; exit 0;; esac - it sits above every preflight and every confirm gate, since a gated test is a test nobody runs
- it names no path and no invocation, so there is nothing in it a sibling's copy could get wrong
- what a sidecar declares about itself is graded by
/test-skillsfrom outside, never from within - a sidecar with no case is a WARN here, since this pair grades shape rather than execution
- ci runs
/test-skills --strict, so a new sidecar without the case fails the build outright - that gate went strict once all 32 adopted the case and the warning count reached zero
.claude/skills/test-skills/SKILL.mdowns the case's shape; this pair only checks it is there
the read-only contract
- a sidecar may fetch, since that moves only remote-tracking refs, and may call the github api
- a sidecar may NOT stash, switch, merge, push, reset, restore, clean, or delete a branch
- a sidecar's commands are not tool calls, so neither the deny floor nor the hook ever sees them
- that is the whole reason for the rule: a sidecar running them was a silent bypass of both gates
- where a trigger genuinely needs to mutate, the floor opens a narrow allow and the TRIGGER runs it,
which keeps the command in front of the gate; the sidecar emits it into a
triggerblock instead - a step earns that block only by ADDING safety:
@git-continue's sync is recoverable at every step, and@git-fresh's backup is the one line that makes the rest of its handover survivable - a step that SPENDS safety never earns it, however convenient — clean, reset and force-switch stay in the handover no matter how many times the same paste gets asked for
plugins/gitgud/shared/handover.shcarries the shared preflights, queries, and block emitters- default branch resolution goes through
git_default_branch, sincesymbolic-refis denied
the artifact
append one entry to [audit_file], in the shape under ## the entry below:
- the heading reads
## Validate Audit #[next_audit]: [timestamp], both taken from the telemetry stateis the scope and the counts, as hyphen bullets, one clause eachfindingsis the ERROR and WARN table the sidecar printed, or one bullet saying none held- a secret finding names its file and line and NOTHING else, since copying the match spreads it
telemetryis the sidecar's whole output, fenced and unedited, pasted last- CREATE the file first if it does not exist, with
# <audit_file>as its only line - the sidecar names the path and the count and writes nothing, so a ci run leaves no entry
the entry
the artifact this skill appends to;
/gitgud:auditgrades the shape on its next run
.construct/maintainer/validate-skills/YYYY-MM-DD.md
one file per day, appended to by every run:
- an entry captures one run at a moment in time, so it is never edited after the fact
- lines are hyphen bullets holding a single clause, capped at 100 characters
Validate Audit #1: YYYY-MM-DD HH:MM
state
the template, the pairs scanned, the skills probed, the index, and the three counts
example:
- template: .claude/skills/validate-skills/SKILL.md, index: README.md
- scanned: 28 pair(s), 5 free-text skill(s) probed
- counts: 0 error(s), 0 warning(s), 0 secret match(es)
findings
the table the sidecar printed, or one bullet saying every machine-checkable rule holds
example:
| ERROR | plugins/x/skills/y/y.sh:1 | exec_bit | 100644, repair: git update-index --chmod=+x |
telemetry
the sidecar's whole output, fenced and unedited
Verify
not part of the trigger; these run after a doc or a sidecar changes
- RUN
.claude/skills/validate-skills/validate-skills.shafter touching a trigger doc or its sidecar; pass a path to scope it - RUN
.claude/skills/export-readme/export-readme.shafter touching frontmatter or a preamble; the readme is their source - CONFIRM a new sidecar or hook reads
100755undergit ls-files -s <path>, since the disk bit lies - FIX every ERROR, since each one breaks a rule this spec states outright
- STOP on a
secretfinding and ask the user before truncating it; the key needs rotating first - JUSTIFY or fix every WARN; the sidecar tolerates them, the next reader may not
- ANSWER the checklist it prints, since those rules are the ones no script can judge
Help
IF the invocation carries
--helpor-h, this section is the whole turn:
SKILL: /plugin:name
DESCRIPTION: <the `description` frontmatter, verbatim>
POSTURE: <the readme index's keyword for this skill>
FLAGS:
- --flag: <what it changes, in the telemetry bullet's own words>
ARGUMENTS:
- <arg>: <what it names>
ARTIFACT: <the `metadata.artifact` path, or none>
OUTPUT: <what lands in the turn: an audit entry, a handover block, an inline report>
SPEC: <this doc's own path>- every field prints, in this order; one with nothing to say prints
none - every value is COPIED from the source named beside it, never composed fresh
- ask what they are actually trying to do, and what they have already tried
- name the flag or the sibling skill that fits their answer, then STOP
- run no step, write no file, and never fall through to step 1
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

