compact-skill-creator · v1.24 · 2026-10-22 · sha256 2e5a0e5e126bcf0d

compact-skill-creator v1.24A

Immutable. This exact content never changes and is served at /api/v1/blob/2e5a0e5e126bcf0d.

---
name: compact-skill-creator
description: Author or refine a skill for maximum token economy without losing intent. Use when creating any new skill or editing an existing `SKILL.md`.
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
license: MIT
metadata:
  version: "1.24"
---

# Compact skill creator

Author a new skill, or improve an existing one, so it carries **all** its rules and intent in the
**least text possible**. Cost has two tiers: the `description` sits in context *every* session — the
skill's most expensive text — while the body loads only when the skill triggers. Both stay lean. Be
interactive: gather what you need, draft, then apply only on approval.

## Compaction — always via compact-docs-writer

The compaction rules — the least-text principle, the removal-audit verification, and the
present-and-confirm with a measured word delta — live in
[compact-docs-writer](../compact-docs-writer/SKILL.md), the single source of truth; this skill never
restates or re-derives them. From the moment you draft (step 4) through self-review (step 5) and
present (step 6), **always** invoke compact-docs-writer and follow its workflow on the skill text —
reading it, applying its principles by hand, or naming it after a direct edit does not count. This
skill adds only the skill-specific layer: trigger taxonomy, agnosticism, progressive disclosure,
completion criteria, metadata, and the version bump.

## Trigger taxonomy — classify first

How a skill is triggered decides how its `description` is written. Classify into one:

- **Mandatory** — must auto-load *whenever* a task type is touched (e.g. "working on UI components",
  "dealing with unit tests"). A silent miss defeats its purpose, so the description **spends words**
  on a strict, concrete trigger: concrete verbs + the artifact ("when creating, editing, or
  reviewing …").
- **Manual** — invoked by name: a `/command`, or sibling skills/rules that reference it
  explicitly. The by-name reference does all the routing, so trigger wording buys nothing: the
  description is one short line of what the skill does — enough for a human choosing from a
  list — never a body summary, never a "load when …" clause. When the skill format can block
  model invocation (e.g. a `disable-model-invocation` flag), set it for Manual skills nothing
  invokes programmatically — the description then costs no standing context; pair the flag with
  `type: flow` — some agents hide flag-bearing skills even from manual invocation without it.
  When sibling skills must drive this one, keep it model-invocable and mark it "invoke manually
  only" in the description instead.
- **Self-Evident** — auto-loadable, but intent is obvious from a natural request (e.g. "fetch a
  ticket"). Trigger words ≈ the task name, so a short description routes correctly without a
  when/when-not clause.

Governing rule: **description tokens are justified only by trigger precision, never by summary.**
Compress *within* a type — but never starve a Mandatory trigger to save a few tokens.

In every type, never use `:` in the description — `: ` in the unquoted value breaks some agents'
YAML parsers; avoid the character rather than quote it.

Two sharpeners for the trigger wording:

- **One trigger per distinct path** through the skill. Phrasings collapse only when they lead the
  agent down the same path (true synonyms — "review a branch" / "check changes before merging");
  never collapse triggers that name different inputs or modes (a PR link vs a bare branch name).
- **Front-load the skill's leading word** (see compact-docs-writer). When the description carries
  the word the user's prompts and docs already use, the agent links that shared language to the
  skill and fires it more reliably.

Placement corollary: the body loads only after the skill triggers, when the choice is already
made — so keep when-to-use and routing cues in the description (read *before* the choice), never
in the body, where they steer nothing.

## Agnosticism

- **Agent-agnostic — hard rule.** Say "the agent" / "the session"; never vendor names ("Claude
  Code", "Claude", etc.). When improving a skill, flag violations and fix the ones that are
  framing; a clearly-marked agent-specific mechanism example with a generic fallback (e.g. a
  memory/config discovery path) is deliberate — flag it at most, never strip it.
- **Project-agnostic — best-effort.** Default to generic wording. Couple to a project/framework/tool
  only when the skill's purpose requires it; when you must, keep it explicit and contained —
  declared up front or in a referenced doc — but skip a standalone declaration when the body already
  names the coupled artifacts throughout, since restating them only duplicates.
- **Tool-agnostic — follow the skill's stance.** When a skill operates over an external tool/service
  with interchangeable equivalents (design tools, trackers, cloud providers, …): if the skill is
  already agnostic — treating such tools as a class, naming specific ones only as examples —
  **preserve that**; new or edited content must stay generic, never hardcode a lone vendor as the
  sole path. Otherwise it's a nice-to-have: prefer generic wording, and when unsure whether to
  generalize or couple, ask the user.
- **Sibling-decoupled: track dependencies.** A skill may be installed with only its declared hard
  dependencies, not the whole toolkit, so a link to a sibling that isn't a dependency can dangle.
  Reference another skill only when it's a declared dependency or the link earns its keep
  operationally (e.g. an actionable next-step handoff); never add orientation prose that merely
  situates the skill among its siblings. An optional sibling gates its hand-off; gate the artifact
  feeding it too only when, without the sibling, it isn't worth its run-time cost.

## Progressive disclosure — when to split

A skill folder can hold a lean `SKILL.md` that references supporting `.md` docs. A referenced doc
loads **only when the agent follows the pointer** — that is the lever.

- **Primary criterion: conditional relevance.** Extract content needed only in a sub-case (rare
  branch, long reference table, worked example, framework-specific detail). Keep always-needed
  instructions inline.
- **Size only modulates:** large conditional chunks are strong candidates; tiny ones stay inline (a
  pointer plus a round-trip can cost more than it saves). These are signals, not hard limits.
- Test: *"Needed on every invocation, or only in a sub-case — and big enough that inlining taxes
  every invocation? If both, extract it."*
- Every referenced doc links from `SKILL.md` directly, never only from another referenced doc.

## Completion criteria — steps end checkable

When a skill encodes steps, end each on a **completion criterion** the agent can check — done vs
not-done — and make it exhaustive where a partial pass could look complete ("every modified file
accounted for", not "produce a summary"). A vague criterion is what makes an agent wrap up early;
sharpening it is the first and cheapest fix. Only when a criterion stays irreducibly fuzzy and
later steps still tempt rushing should those later steps move out of sight (a follow-on skill or a
disclosed doc).

## Workflow

1. **Detect mode.** A path/skill argument → improve; none → create. To create, put the skill in its
   own folder alongside existing skills, following the project's convention — ask the user if it's
   unclear; folder name and `name` field must match, in kebab-case.
2. **Intake — interview relentlessly to shared understanding.** Before drafting, walk down each
   branch of the skill's design tree, resolving dependencies between decisions one at a time —
   never fire a fixed batch of questions once and then draft. Cover at least the purpose, **trigger
   type**, and any unavoidable coupling, plus whatever each answer opens up. Ask one question at a
   time, each with your recommended answer, worded via `explain-in-simple-language` when
   available; if a question can be answered by exploring the codebase, explore instead of asking.
   A skill reading what other skills produce, or stepping into their hand-offs, takes its input
   types, the options its own hand-off carries on, and the files it must never write from a search
   of every such skill — never from the one pipeline in mind.
   Scale depth to complexity (complex skill → more questions; simple → few). The only limit: never
   interview for its own sake.
3. **Metadata.** Frontmatter always carries `name` and `description`, plus every field the
   project's conventions or all its sibling skills carry (e.g. a license, `metadata.version`);
   per-skill ones (tool grants, invocation flags) follow from the skill's own needs, never copied.
   Never hardcode values. Creating: infer defaults from context (sibling `SKILL.md` files,
   `git config user.name`, repo `LICENSE`), ask the user to confirm or override. The first
   version follows the project's stated convention; none stated → ask `"1.0"` or a `"0.x"` trial.
   Improving: preserve existing fields, and flag any missing one.
4. **Draft** (create) or **improve** (existing): get the skill's content right — the rules it
   encodes, plus what improving adds (clarify where it's vague, under-specified, or missing a rule;
   loop back to intake if gaps surface) — compacting it through compact-docs-writer as you write,
   not in a later pass.
5. **Self-review** before presenting — terse yes/no, skill-specific (compact-docs-writer runs the
   compaction and removal-audit checks):
   - Wording agent-agnostic? Project coupling contained? Cross-references limited to declared
     dependencies or a real operational benefit?
   - Trigger type identified, and the description written to fit it? Test it, reading only the
     description:
     - Mandatory or Self-Evident: write three prompts the skill must fire on and three near
       misses it must not (a similar task, a different input type) and judge each from the
       description alone. Manual: would an agent open it for the intended task, and skip a
       similar but unrelated one?
     - does it match what the skill now does (no stale claim the body contradicts)?
     - does it carry the skill's leading word itself — a paraphrase feels compliant but does no
       invocation work?

     Reword until all hold.
   - Body consistent with itself? Every "never" checked against each step and source it could
     forbid; every advertised input type handled by each step that touches it (a check fitting
     only one type fails the rest); every write surfaced where its reader looks — when a later
     phase reads only a document derived from the edited one, the addition reaches that one too.
   - Spawns a subagent, reviewer or fork? Its brief and its return are defined: what it receives,
     what it reports back (paths written, verdicts, blockers, edits made, what it did not check),
     and that it hands nothing off itself.
   - Creating: hand a fresh agent (a subagent when the tool offers one, else a prompt the user
     runs in a clean session) only the draft and one realistic input; have it walk the draft dry,
     writing, committing and posting nothing, narrating step by step and listing each point where
     the text is ambiguous, contradictory or silent. Each point loops back to draft; done when the
     run reports none. Improving: offer the run, never require it.
   - No new or grown inline chunk meets the split test (progressive disclosure)?
   - Steps end on checkable, exhaustive completion criteria?
   - [scripts/check-skill.sh](scripts/check-skill.sh) `<skill-dir>` passes? While the draft sits
     in scratch, set `CHECK_SKILL_AS=<real folder>`. It holds the conventions above that a script
     can check (wrap, links, frontmatter) and prints the version at HEAD, merge base and working
     tree for step 6; fix every failure before presenting.
6. **Present & confirm** through compact-docs-writer (diff + word delta measured from the files,
   applied only on approval). In improve mode the draft **includes a version bump** — the last
   component, unless the author names a value — never a question put to the user. Skip it only
   when the version was already raised, uncommitted or on the branch against its target, verified
   from git (version at HEAD and at the merge base vs working tree), never from session memory:
   the repo may have moved concurrently. A version line saying `base unknown` or `no merge base`
   never reads as "not bumped": resolve the target as self-review does — the `upstream` remote's
   default branch when one exists, else `origin`'s, via `git ls-remote --symref <remote> HEAD`;
   offline, the sole existing candidate among `main`, `master`, `develop`/`development` — and
   rerun the script with `CHECK_SKILL_BASE=<ref>`; still unknown → ask the user only which branch
   is the target, never whether to bump. Done when the skill and every place the project catalogs
   its skills (a README entry, a manifest or dependency list, a relationship graph) carry the
   change, including any hard dependency a new cross-reference adds; find them by searching the
   repo for a sibling skill's name.