skill-tuning
Skill2 starsChanged 6 days agoApache-2.0View on GitHub
Grade an Agent Skill — or a whole skills/ tree — against the enforceable skill-standard and drive it green: frontmatter portability, description discipline, no credential material, no author-machine paths, size budgets. Use when authoring a new SKILL.md, when adopting the standard across an existing skill library, before publishing a plugin or a marketplace entry, or when a skill loads but never fires and nobody can say why.
4 other projects use a version of this.
Adopted by
Most recently taken up by
- catlog22/Maestro-Flowtheir own version, first seen Oct 9, 2026
- jramsahai/obsidian-mcp-braintheir own version, first seen Sep 13, 2026
- catlog22/maestro-flowtheir own version, first seen Sep 4, 2026
- zhao-wuyan/ccw-command-explorertheir own version, first seen May 8, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- catlog22/maestro-flow★ 571same name
- catlog22/Maestro-Flow★ 571same name
- zhao-wuyan/ccw-command-explorer★ 45same name
- jramsahai/obsidian-mcp-brain★ 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 repository5 other files it gives its agents.
- AGENTS.mdAGENTS.md
- llms.txtllms.txt
- bceSkill
- skill-tuningSkill
- bceSkill
The file
We split this skill into the rules it gives an agent
8 rules. 0 are common, 3 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 33
Do not reach for this to judge whether a skill is *good*.
- Very specific: line 78
every constraint's path narrow → the same prefix.
- Very specific: line 103
Read coverage.filesScanned in the report FIRST, before the score.
- Very specific: line 144
Read the verdict as a measurement, not a word to satisfy.
- Very specific: line 175
Never move a fixture under skills/, and never name one in the skills array.
- Very specific: line 184
Advisory: Commit .bce-mode.json containing { "mode": "advisory" }.
- Distinctive: line 194
Not gated. Run it, and report it as a checklist.
- Distinctive: line 228
Never narrow a clause to make a red go green: If a hit is a genuine false positive, baseline it — that is visible in a diff.
“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
skill-tuning — grade a skills/ tree against a standard that can go red
An Agent Skill fails quietly. A misspelled frontmatter key is dropped, not rejected. A placeholder description loads and never routes. An absolute path into the author's home directory resolves on exactly one machine. Every one of those files looks fine, passes review, and does not do what its author believes it does.
This skill grades a skills tree against the skill-standard — a set of properties written so a machine can decide them — and drives the tree green. The gated half is a bce blueprint, so a change that breaks it is refused rather than reviewed. The rest is a checklist run here, honestly labelled as such.
When to fire
- Authoring a new
SKILL.md. Grading it before it ships is minutes; finding the dropped key after twenty people installed it is not. - Adopting the standard across an existing library. Expect red on day one. There is a brownfield path below that does not require fixing everything first.
- Before publishing a plugin or a marketplace entry. A skill directory is copied verbatim onto every installer's machine. Whatever is in it, ships.
- A skill loads but never fires. The usual cause is the description — a placeholder, or a self-referential opening that gives a router nothing to match on. S3, S4 and S5 name that directly.
- A frontmatter key that "does nothing". Almost always a near-miss spelling. S1 is the clause, and it is the highest-hit-rate clause on real libraries.
Do not reach for this to judge whether a skill is good. The standard decides whether a file behaves the way its author expects on someone else's machine. It has no opinion about the subject matter, and it should not acquire one.
The two halves, and why the split is stated out loud
The engine's enforceable-on-markdown constraint types are forbiddenPattern (a per-line regular
expression with an optional path narrow), forbiddenFile (a filename glob), and the
extraction.minFiles floor. There is no required-content type — requiredEvidence,
minimumMetric and customPolicy are declared-but-run-only and bce teeth reports them
INDETERMINATE.
So: the forbidden half is the blueprint and blocks a merge. The required half is the checklist in this skill, and does not. Both are real; only one is a gate. Do not report the checklist items as gated — that is the exact class of claim this whole tool exists to refuse.
The procedure
1. Inventory
find skills -name SKILL.md | sortNote the count. It is the denominator for everything that follows, and a scan that later resolves fewer files than this is a scoping mistake, not a clean tree.
2. Copy the blueprint and aim it at the tree
Resolve the installed package root, then copy the shipped standard into the target repository.
The npm path is the normal external-consumer path; use BCE_PACKAGE_ROOT=. only while working in
a bce source checkout:
BCE_PACKAGE_ROOT=node_modules/bce-engine
mkdir -p .blueprints
cp "$BCE_PACKAGE_ROOT/spec/skill-standard/skill-standard.blueprint.json" \
.blueprints/skill-standard.blueprint.jsonThen edit exactly three things:
scope.repositories→ the target repository, asorg/repo.scope.pathsandextraction.paths→ where the skills actually live.skills/**for a plugin or marketplace repository;.claude/skills/**for a project-local library.- every constraint's
pathnarrow → the same prefix. The narrows readskills/**/SKILL.mdandskills/**; if the tree is at.claude/skills/, they must be rewritten to match or those clauses will scan nothing and pass vacuously.
That third step is the one that gets missed, and it fails silently in the worst direction: the constraint is present, the blueprint is valid, and the clause grades an empty set. After editing, prove the aim before trusting any verdict:
bce validate --blueprint .blueprints/skill-standard.blueprint.json3. Run it
bce run \
--blueprint .blueprints/skill-standard.blueprint.json \
--ct-repo . --no-pin --extractor ast \
--out skill-standard-report.json--no-pin grades the working tree. Without it the run pins to a committed revision via
git archive, which is the right default for CI and the wrong one while you are editing — a green
on the pinned tree says nothing about the file open in front of you.
Read coverage.filesScanned in the report FIRST, before the score. If it does not match the
inventory from step 1, the paths are wrong and the score is meaningless. A blueprint whose scan
resolves nothing is the failure mode this engine is built to make impossible, and step 2 is where
it gets introduced.
Then read the violations. Each carries the constraint id, the severity, and file#Lline.
4. Fix, by clause
The rewrite move per clause. The exact regular expressions live in the blueprint — read them there rather than from any prose, including this page, so the two can never disagree.
| clause | the move |
| S1 frontmatter-key-portability | Decide what the key was meant to do, then use the spelling a consumer actually reads — or delete it. Check references/portability-matrix.md first: several of these keys are platform extensions, so re-spelling one makes the file non-portable, and deleting it is often the better fix. |
| S2 name-shape | Lowercase, digits and hyphens, ≤64 characters, and equal to the directory name. Rename the directory too, or the two disagree and consumers differ on which wins. |
| S3 description-placeholder | Write the description. One sentence saying what it does, one saying when to reach for it, key use case first. |
| S4 description-budget | Cut it under 1,024 characters on the line. If the material is genuinely needed, it belongs in the body or in references/, not in the routing text every other skill shares a budget with. |
| S5 description-voice | Delete the self-referential opening and start with the verb. A router is deciding whether this is the right skill; "This skill…" spends the highest-value words in the file on a word that discriminates nothing. |
| S6 no-model-pin | Remove the dated model id. Omit the key, or inherit. |
| S7 no-credential-material | Remove it, then rotate it — it is in the git history now, and if the skill was ever installed it is on other machines. Fixing the file is the smaller half of this one. |
| S8 no-author-machine-paths | Replace with the substitution the format provides for a skill's own directory, or the plugin root. See the note below on the false-positive class before assuming every hit is a defect. |
| S9 no-harness-imitation | Delete it. There is no legitimate reason for a distributed skill to carry text shaped like harness framing or an instruction to disregard prior instruction. |
| S10 no-placeholder-body | Finish the file, or delete the scaffolding. |
| S11a/b/c key-material files | Delete the file, rotate whatever was in it, and add the glob to .gitignore so it cannot return. |
S8 has a real false-positive class, and it is not a bug to route around. An absolute path into a container's home directory is correctly absolute and has nothing to do with anyone's laptop — but it is the same shape as an author-machine path, and a per-line regular expression cannot tell them apart. Measured on a 34-skill library: 24 hits, 17 genuine, 7 of this class. Do not narrow the clause to make them go away; on a Linux author's machine that same shape is the true positive. Baseline them instead (step 6).
5. Prove the red
A clause you have not seen fail is a clause you hope works.
bce teeth --blueprint .blueprints/skill-standard.blueprint.json --ct-repo . --no-pin --extractor astRead the verdict as a measurement, not a word to satisfy. On a clean tree most of these clauses
report evaluator-refutable: the mutation was synthetic, which proves the evaluator can refute the
constraint and not that the constraint bites real extractor evidence. That is an honest verdict,
not a failure.
The substance proof is the seeded corpus that ships with the standard:
BCE_PACKAGE_ROOT=node_modules/bce-engine
bce run --blueprint "$BCE_PACKAGE_ROOT/spec/skill-standard/skill-standard.blueprint.json" \
--ct-repo "$BCE_PACKAGE_ROOT/examples/skill-standard/drift" \
--no-pin --extractor ast --out /tmp/drift.json
bce run --blueprint "$BCE_PACKAGE_ROOT/spec/skill-standard/skill-standard.blueprint.json" \
--ct-repo "$BCE_PACKAGE_ROOT/examples/skill-standard/clean" \
--no-pin --extractor ast --out /tmp/clean.jsondrift/ reddens every clause; clean/ scores 100. Against drift/, bce teeth reports 13/13
extractor-real, because the violations are really there. If you add a clause, it does not ship until
drift/ reddens it too.
A hazard the corpus creates, and how it is contained. examples/skill-standard/drift/ holds a
deliberately broken skill — a placeholder description, a fake key, harness-imitating text. It is
inert for exactly two reasons, and both must stay true:
- It lives under
examples/, which no plugin loader ever scans. Onlyskills/is auto-discovered. - It is not named in the plugin manifest's
skillsarray. That array is ADDITIVE, not an allowlist — it does not narrow discovery, it ADDS directories from outsideskills/. Naming a fixture directory there would publish a deliberately broken skill into every installer's session, and the manifest would still be perfectly well-formed, so no schema check would see it.
Never move a fixture under skills/, and never name one in the skills array. In the bce
repository tests/skill-contract.test.ts asserts both; an adopting repository should copy that
assertion along with the corpus.
6. Adopting on a library that already drifts
Day one on a real library is red — expect it, and do not fix it by weakening the blueprint. Three rungs, each a committed, reviewable artifact:
- Advisory. Commit
.bce-mode.jsoncontaining{ "mode": "advisory" }. Full verdict printed, nothing blocked. Nothing is suppressed — only the build consequence is. - Baseline.
bce baselinerecords today's violations as the accepted set; new ones block, recorded ones are shown and counted but do not. The file only ever shrinks. Preview withbce baseline --dry-run. This is the right home for the S8 container-path class. - Graduate.
bce graduateflips advisory to enforced. Reversing it requiresbce graduate --downgrade --rationale "<why>", so a quiet weakening cannot happen.
7. The required-half checklist
Not gated. Run it, and report it as a checklist.
- Every skill directory holds a
SKILL.md. - The frontmatter fence is line 1 and it closes. (
head -1is---.) nameanddescriptionare present and non-empty;nameequals the directory name.- Body under 500 lines:
wc -l SKILL.md. Deeper material goes inreferences/, read on demand. licensepresent on anything published — a plugin, a marketplace entry, a public repository.- Frontmatter confined to the portable core, unless a platform extension is a deliberate,
recorded choice.
references/portability-matrix.mdcarries both lists and the rejection message you get for crossing them. - Bundled paths use the skill-directory or plugin-root substitution, never a literal path.
- No vendored dependency tree inside a skill directory. This is a checklist item because it
cannot be gated: the extractor's directory walk skips
node_modulesby name before any glob applies, so a constraint aimed at it scores 100 against a tree that carries one. Measured, not assumed.find skills -type d -name node_modulesdecides it. - Every command line the skill teaches names a real verb and real flags of the tool it drives.
Worth automating: a stale command in a skill is an agent confidently running a flag that has
never existed and reading the refusal as a repository problem.
tests/skill-contract.test.tsin the bce repository is this check with the CLI source as its oracle.
8. Wire the gate
bce gate --repo . --extractor ast --allTwo ways a required check goes wrong, both of which wedge a merge queue rather than fail it: a workflow-level path filter (a path-filtered required check never reports on a PR outside its filter), and a moving version tag on the engine (the same tree then yields different verdicts on different days — pin an exact version). The gate self-scopes, so a PR touching nothing in any blueprint's scope passes trivially; make sure the workflow also runs on the merge-queue event.
The honesty invariants
- Never narrow a clause to make a red go green. If a hit is a genuine false positive, baseline it — that is visible in a diff. Editing the pattern is not.
- Read
filesScannedbefore the score. A blueprint aimed at the wrong path scores 100 forever, and looks exactly like a clean tree. - Never report a checklist item as gated. The required half is checked here, by an agent, and an agent's report of its own work is not evidence. Say which half a result came from.
- Do not claim a clause works until you have produced its red. The seeded corpus exists so that this costs one command.
--no-pinfor the working tree, pinned for committed proof. Mixing them up produces a green that describes a tree you are not looking at.- A fixture is never a shipped skill. Under
examples/, never underskills/, never in the manifest'sskillsarray.
References
Loaded on demand, not up front:
${CLAUDE_SKILL_DIR}/references/skill-standard-clauses.md— every clause with its rationale, its failure mode, and the fixture that proves its red.${CLAUDE_SKILL_DIR}/references/portability-matrix.md— the portable core versus the platform extensions, and what crossing that line costs.
The normative standard itself, with the required half and the deliberately-omitted clauses: https://github.com/blueprint-conformance/bce/blob/main/spec/skill-standard/SKILL-STANDARD.md
(Full URL on purpose: once this skill is installed, it is nowhere near the repository, so a repo-relative path would resolve to nothing.)
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.

