---
name: skill-creator
description:
  "Create and update Agent Skills (SKILL.md instructions, resources, validation, packaging) for any
  harness. Use when authoring, repairing, or packaging one skill's own contents; use
  project-skill-setup to choose which skills a repo installs."
argument-hint: "[skill-name | path-to-existing-skill]"
disable-model-invocation: true
---

# Skill Creator

Skills in this repo ship to both Claude Code and Codex. The frontmatter that gates a skill is
interpreted differently by each harness, and getting that wrong is silent — the skill still loads,
just not under the conditions intended. Start there.

## Cross-harness gates

`disable-model-invocation: true` is **Claude-only**. Codex still matches the skill implicitly
against user prompts unless the skill also ships `agents/openai.yaml` with:

```yaml
policy:
  allow_implicit_invocation: false
```

Set both together whenever a skill must only run on explicit invocation (`/skill` in Claude Code,
`$skill` in Codex). The frontmatter alone leaves the gate open on Codex.

Default for skills in this repo is explicit (both gates). The global implicit allowlist is
`engineering-standards`, `commit`, `pr`, `discovery`, and `scratchpad`. Do not omit the gates on a
new or newly globally installed skill unless it is one of those five. `init_skill.py` writes both
gates unless the name is on that list; `quick_validate.py` rejects a mismatch.

**Never remove a recognized extension because the current harness ignores it.** `argument-hint`,
`user-invocable`, `model`, `context`, `agent`, `hooks`, `references`, `disallowed-tools`, and
`disable-model-invocation` are all load-bearing somewhere. A field another harness owns is not an
invalid field. Put Codex-specific UI configuration in `agents/openai.yaml` rather than duplicating
it in SKILL.md frontmatter.

## Frontmatter

`name` and `description` are required. `name` is 1–64 lowercase letters, digits, or hyphens — no
leading, trailing, or consecutive hyphens — and must exactly match the directory name. `description`
is a non-empty string of at most 1024 characters; **wrap it in double quotes** if it contains a
colon.

The description is the only thing loaded before the skill triggers, so it is the entire triggering
mechanism. Put every "when to use" signal in it — a "When to Use This Skill" section in the body is
dead weight, because the body only loads after the decision to trigger has already been made. State
what the skill does and the concrete contexts that should route to it, plus a negative boundary when
a sibling skill is easily confused with it.

Optional portable fields, only when they earn it: `license`, `compatibility` (≤500 characters),
`metadata` (string key/value map), experimental `allowed-tools` (space-separated string).

## Structure

```
skill-name/
├── SKILL.md (required)          - frontmatter + imperative instructions
├── agents/openai.yaml           - Codex UI metadata, invocation policy, tool dependencies
├── scripts/                     - executable code; may run without loading into context
├── references/                  - docs loaded into context on demand
└── assets/                      - files used in the skill's output, never loaded into context
```

Reach for `scripts/` when the same code would otherwise be rewritten every run or when the operation
is fragile enough to need determinism. Reach for `references/` for schemas, API docs, and
variant-specific detail. Reach for `assets/` for templates, boilerplate, and fonts the output
consumes.

Progressive disclosure is the whole design: metadata is always resident (~100 words), the body loads
on trigger (aim under 5k words and 500 lines), references load only when the agent decides it needs
them. So keep the core workflow and the routing decision in SKILL.md and push variant detail out.
Treat those numbers as a review signal rather than a hard cap: crossing them means re-checking
whether each section still earns its place, and is the point to split content into references.

Branching decides _what_ moves. A branch is a distinct path a run can take through the skill, so
inline what every branch needs and push behind a link what only some branches reach. Where the
budgets tell you to look, branching tells you what to cut.

Three constraints are not negotiable because they break retrieval rather than merely bloating it:

- **References stay one level deep.** Every reference file links directly from SKILL.md. A reference
  that is only reachable through another reference will not be found.
- **Files over 100 lines get a table of contents** at the top, so a preview reveals the full scope.
- **References over ~10k words get grep patterns in SKILL.md.** A file that large cannot be read
  whole on demand, so name the search terms that find the right section — otherwise the reference
  has a link and no retrieval strategy.

Information lives in SKILL.md or in a reference, never both. Do not add README.md,
INSTALLATION_GUIDE.md, QUICK_REFERENCE.md, CHANGELOG.md, or any other file documenting the process
of building the skill — a skill contains only what an agent needs to do the job.

Write the body in imperative form, for another agent instance rather than for a human reader.

For multi-step or conditional workflows see [references/workflows.md](references/workflows.md); for
strict output formats and example-driven quality bars see
[references/output-patterns.md](references/output-patterns.md).

## Scoping a new skill

Before writing, get concrete about how the skill will actually be invoked: what a user says that
should trigger it, and what it does once triggered. Ask in **one focused round** — batch the
questions, propose a default for each, then proceed. Generating plausible usage examples and
confirming them is usually faster than interviewing from scratch.

Then work backwards from those examples: what would have to be rewritten from scratch each run
becomes a script, what would have to be rediscovered each run becomes a reference, what gets copied
into the output becomes an asset.

## Craft

A skill exists to get determinism out of a stochastic system. Predictability is the target — the
agent taking the same _process_ every run, not producing the same output. Three levers move it.

**Use leading words.** A leading word is a compact concept already in the model's pretraining that
the agent thinks with while running the skill — _tracer bullet_, _fog of war_, _tight_, _red_.
Repeated as a token rather than restated as a sentence, it accumulates a distributed definition and
anchors a whole region of behaviour in the fewest tokens, because it recruits priors the model
already holds. Prefer an existing word to a coined one: a made-up term recruits nothing, so you pay
in definition tokens what a pretrained word gives free. A quality spelled out at three sites is
usually one leading word waiting to replace it.

**Make completion criteria checkable and exhaustive.** Every step ends on a condition, and two
independent properties make it a lever. _Checkable_ means the agent can tell done from not-done —
"understanding reached" cannot be, and lets attention slide to the next step. _Exhaustive_ means it
forces the work — "every modified model accounted for" digs where "produce a change list" does not.
The second binds flat reference too: "every rule applied" is what makes a skill with no steps still
thorough.

**Prompt the positive.** A prohibition names the behaviour into context and makes it more available,
not less — _don't think of an elephant_. State the target behaviour so the banned one is never
spoken. Keep a prohibition only as a guardrail you cannot phrase positively, and even then pair it
with what to do instead.

## Tooling

The `skills` CLI (`~/.bun/bin/skills`) manages installation: `skills add`, `remove`, `list`,
`update`, `init`. Treat `skills --help` as authoritative over anything written here — the surface
moves. Use `skills init <name>` when creating a skill that will be installed through the CLI, and
use it over the bundled scaffold whenever the repo already manages skills that way.

The bundled scripts are for the authoring loop itself and take an explicit path, so they work on a
skill directory that is not yet installed anywhere. Paths below are relative to this skill's own
directory, which the harness announces when the skill loads — resolve them against it rather than
against the repo you are working in, and never hard-code an install prefix, since the same skill can
live at user scope, at project scope under `.agents/skills/`, or under a relocated Codex home.

```bash
scripts/init_skill.py <skill-name> --path <output-directory>
scripts/quick_validate.py <path/to/skill-folder>
scripts/package_skill.py <path/to/skill-folder> [output-dir]
```

`init_skill.py` scaffolds the directory with frontmatter, TODO placeholders, `agents/openai.yaml`,
and example files in each resource directory — delete the ones the skill does not need.
Non-allowlisted names get both invocation gates; allowlisted names stay implicit.

## Gates

**Validate before installing or distributing.** `quick_validate.py` checks the portable projection
against the official `skills-ref` library through `uv`, type-checks the cross-harness extensions
above, enforces the invocation allowlist, and rejects unfinished TODO placeholders and an empty
instruction body. Fix every reported error; packaging runs the same validator and refuses to produce
output while any remain.

**Run any script you add.** A script that has never been executed is an assumption, not a resource.
With several similar scripts, running a representative sample is enough.

Codex discovers local skills directly from `.agents/skills` at repository scope and
`~/.agents/skills` at user scope, so a `.skill` ZIP is only needed for explicit distribution —
`package_skill.py` produces one (a zip with a `.skill` extension) after validating.

## Iterate

Skill quality shows up under real use, not review. When a skill struggles on a real task, fix the
instruction that let it struggle while the context is fresh, then run the same task again.

When the struggle repeats, name it before editing:
[references/failure-modes.md](references/failure-modes.md) gives the five recurring ones and the
lever that cures each.
