Skill Authoring — easy-cheese conventions
This document codifies the skill-authoring rules for easy-cheese, drawn from
obra/superpowers (CSO principle, Iron Law template, pressure-test gate) and
Matt Pocock's skills repo (size budget, authoring checklist). It is the
canonical reference for anyone adding or revising a skill.
Description rule (CSO)
The description is the only thing the harness shows the model when choosing
a skill. Optimize it for triggering, not explanation.
The rule: sentence 1 = capability; sentence 2 = "Use when [triggering
conditions]". No workflow summary, no pipeline-position prose, no feature list.
Rationale: a description that summarizes the skill's workflow creates a
shortcut the model takes instead of reading the SKILL.md body. The skill
then silently degrades to its own one-line description.
Constraints:
- Maximum 1024 characters (Codex rejects longer descriptions).
- Third-person, present tense.
- Triggering conditions name concrete phrases the user might say.
Test: strip the description and ask: could a model choose this skill over
all others based on these words alone? If not, the triggers are missing.
Size budget
Keep SKILL.md bodies lean. The goal is a body a model can read in one pass
without losing the thread.
The budget: 3,600 estimated tokens for the SKILL.md body (frontmatter
excluded). At this repo's measured prose density that's roughly 150 lines,
but tokens are the gated unit, not lines — line count misleads on dense
prose: all 16 skills in this repo pass Anthropic's 500-line rule, while 8
exceed our 3,600-token budget on the same bodies.
Enforcement: CI runs this as a shrink-only ratchet —
.github/scripts/validate_skills.py
, baselines recorded in
.github/skill-budgets.json
, regenerated via
just update-skill-budgets
.
A skill already over budget when the ratchet was introduced is grandfathered
at its recorded value and may only shrink from there; a skill at or under
budget must stay under 3,600.
Anthropic's published Level-2 figures are 500 lines / under 5k tokens.
easy-cheese deliberately sits tighter than that ceiling.
Practical budget:
- Push satellite detail — step-by-step sub-protocols, reference tables,
prompt templates, large examples — into named files.
The SKILL.md body points to them; it does not duplicate them.
- The dir is the right home for: long rationalization tables,
output format templates, detailed sub-protocol steps, graph conventions.
- Splitting only helps if SKILL.md says when to read the reference file.
Reference files load only on an explicit link from the body — moving
prose into without a pointer just relocates the tokens off
the visible budget rather than deferring them from the model's read.
Smell test: if the SKILL.md body has grown to the point where the Flow
section is buried below a long Inputs section and three flag tables, it is
time to factor.
Provenance: the budget originated as an adaptation of Matt Pocock's
<100-line cap for his skills repo, and has since been restated in tokens
against this repo's own measured prose density.
Iron Law / Red Flags / Rationalization-table template
Discipline skills (skills that enforce a process, not just explain a
technique) follow this three-part structure. Apply it in a
section in the SKILL.md body, or in a
references/<skill>-discipline.md
satellite file when the body is already
at budget.
Iron Law
One sentence. States the gate that must never be skipped. The Iron Law is
descriptive, not aspirational: it names what the skill will refuse to do
without.
Example shape:
Iron Law: No [output] without [prerequisite step] first.
Red Flags
A short list of signals that the Iron Law is about to be violated. These are
the observable pre-rationalizations — the moment before a step gets skipped.
Example shape:
Red Flags — stop if you notice these:
- "The tests will obviously pass after this change."
- "I'll add the test in the next commit."
- [skill-specific patterns]
Rationalization table
A table enumerating the excuses an agent uses to skip the Iron Law step, with
an explicit rebuttal for each. The table is adversarial by design: it assumes
the model will reach for a rationalization under pressure.
| Rationalization | Why it fails | Required action |
|---|
| "The change is obvious, tests would just mirror the code." | A test that mirrors code catches regressions; that is its job. | Write the test. |
| [skill-specific row] | [rebuttal] | [required action] |
Keep the table to the rationalizations actually observed in practice (5-10
rows maximum). An exhaustive list defeats the purpose.
Authoring review checklist
Before a skill ships, verify:
Pressure-test-first authoring gate
Iron Law: no skill ships without a failing-baseline subagent run first.
Before writing a new skill body:
- Construct a representative pressure scenario — a prompt that describes a
task the skill is meant to improve.
- Run a subagent on that scenario without the skill active. Capture the
output as the baseline.
- Identify the specific failure: what did the subagent do wrong, skip, or
misframe?
- Write the skill body to address that specific failure.
- Re-run the subagent with the skill active and confirm the failure is
corrected.
A skill whose body was never tested against a failing baseline may fix a
problem the model does not actually have, or it may describe a workflow the
model already follows without being told.
frontmatter (candidate — not yet applied)
Matt Pocock's skills repo uses
disable-model-invocation: true
in the
frontmatter of pure-prompt skills (skills that execute immediately without
re-prompting the model). The Claude Code frontmatter validator
(
.github/scripts/validate_skills.py
) already allows this key.
Status: candidate-pending-harness-verification. Do not apply to any
easy-cheese skill until the harness behavior is confirmed: what does the
harness do when this key is set, and does it match the intended
"execute immediately" semantics? Document the verification result here
before applying.