Skillify
Slash command that promotes an ad-hoc session capability into a durable skill: a command file with triggers and rules, optional deterministic helper script, a pinning test, and a learnings-store entry pointing at the new skill. Inspired by the 'skillify' pattern where every repeated failure becomes structurally unreachable by being turned into a tested skill.
Tags
README
skillify
Slash command that promotes an ad-hoc session capability into a durable skill.
What It Does
Installs a /skillify command that walks the agent through turning "this just worked" into permanent, tested infrastructure:
- Identify the capability and its trigger (and classify each step as latent vs deterministic)
- Capture the RED baseline (gate): run a no-skill agent on a representative task and record its failure modes + rationalizations — if it succeeds with no skill, stop, there is nothing to skillify
- Decide scope and location
- Check for name collisions against existing commands
- Write the skill contract, targeting only the RED failures
- Extract deterministic steps into a helper script
- Write a pinning test for the script
- Confirm GREEN (gate): re-run the same RED task with the skill loaded and confirm the behavior changed
- Register a pointer in the learnings store
- Report what was created (including the RED baseline and GREEN confirmation)
Inspired by the skillify pattern: every repeated failure becomes structurally unreachable by being turned into a tested skill. The RED baseline + GREEN confirmation make this red-green-refactor for skills — a captured baseline failure proves the skill is needed and pins exactly what it must correct.
Manual Installation
# Global (all projects)
mkdir -p ~/.claude/commands ~/.claude/bin
cp commands/skillify.md ~/.claude/commands/skillify.md
cp bin/ccgm-skillify-check ~/.claude/bin/ccgm-skillify-check
chmod +x ~/.claude/bin/ccgm-skillify-check
# Project-level
mkdir -p .claude/commands
cp commands/skillify.md .claude/commands/skillify.md
Make sure ~/.claude/bin is on $PATH so the collision-check helper is discoverable.
Related Modules
skill-authoring— rules governing how skills are written (reference-file inclusion, voice, tool selection)code-quality(rules/latent-vs-deterministic.md) — the classification the/skillifyworkflow leans on in Phase 1self-improving— providesccgm-learnings-logwhich/skillifyuses in Phase 9 to register the new skill
Files
| File | Description |
|---|---|
commands/skillify.md |
The /skillify slash command — 10-phase red-green-refactor workflow from capability to durable skill |
bin/ccgm-skillify-check |
Deterministic helper: scans ~/.claude/commands/ and .claude/commands/ for exact and fuzzy name collisions |
ccgm-skillify-check
ccgm-skillify-check <skill-name>
Exit codes:
0 no collisions
1 exact collision — pick another name
2 fuzzy match — review before creating
3 invalid usage (non-kebab-case or wrong arg count)
Fuzzy matching splits the proposed name on hyphens and flags other commands that contain any token ≥ 4 characters. Short tokens are ignored to keep noise down.
Will install
| Path | Action | Target | Type |
|---|---|---|---|
commands/skillify.md | → | commands/skillify.md | command |
bin/ccgm-skillify-check | → | bin/ccgm-skillify-check | script |
Dependencies
No dependencies.
Required by
No other module depends on this one.
Included in presets
Install this module
Agent prompt
Recommended for agent users -- hands the whole install off to your assistant.
Fetch https://cd23a9be.ccgm-site.pages.dev/modules/skillify.md and install this module into my Claude Code setup.
Native plugin marketplace
One command via the native plugin marketplace -- additive, does not merge settings.json.
claude plugin install skillify@ccgm
The marketplace path is additive, not a replacement: it installs commands, agents, and skills as native plugin components, but it does not perform the bash installer's deep settings.json merge, and it does not write the always-loaded global CLAUDE.md context. Rules are only injected via an opt-in SessionStart hook rather than being auto-loaded. Use the bash installer when those pieces matter to you.
Files
command (1)
commands/skillify.md
# /skillify - Promote a Session Capability to a Durable Skill
Take what just worked in this session and turn it into a permanent skill: a command file with triggers and rules, deterministic code for the parts that don't need judgment, a test that pins behavior, and a learnings-store entry so future sessions find it.
## When to Use
- A multi-step process just worked in conversation and is likely to recur (OAuth setup, a deploy dance, a verification ritual)
- The agent made a mistake that shouldn't be possible to repeat (wrong side of a latent/deterministic divide — see `rules/latent-vs-deterministic.md` if installed)
- The user said something like "remember this" or "make it a skill" or "skillify it"
If the thing to capture is a single prose lesson rather than an executable workflow, prefer `/reflect` instead.
## Inputs
- `$ARGUMENTS` — optional kebab-case name for the new skill. If omitted, propose one based on what just happened and confirm before creating files.
## Workflow
Follow phases in order. Skip a phase only by announcing which phase and why.
### Phase 1: Identify the Capability
Summarize in one sentence: what did we just build or get right? What's the trigger — the phrase or situation where a future session should invoke this skill?
Classify every step in the workflow:
- **Latent** — needs judgment (summarizing, picking an approach, handling open-ended input)
- **Deterministic** — one right answer given inputs (arithmetic, parsing, file lookups, format conversions)
If `rules/latent-vs-deterministic.md` is installed, follow it strictly. Deterministic steps must become scripts; latent steps stay in the skill's prose.
### Phase 2: Capture the RED Baseline (Gate)
**Do not write any skill content until a no-skill agent has been watched failing the task.** This is red-green-refactor for skills: the baseline failure proves the skill is needed and pins exactly what it must correct. A skill written without a captured baseline is a guess about what an agent gets wrong.
If `rules/skill-authoring.md` is installed, follow its "RED Baseline" section. The steps:
1. **Pick a representative task** — a concrete instance of the situation the trigger will match, not a toy.
2. **Run a fresh subagent WITHOUT the skill** — give it only the task. Use the agent-dispatch tool (e.g., Task in Claude Code).
3. **Record the failure modes** — wrong tool, skipped step, bad default, unsafe action, missing verification.
4. **Record the rationalizations** — the phrases the baseline agent used to justify the wrong behavior. These become the left column of the skill's "Rationalizations" table in Phase 5.
**Gate:** If the baseline agent does the task correctly with no skill, **stop and do not create the skill.** A skill that does not change behavior is bloat that taxes every future invocation. Report that no skill was warranted and exit.
Keep the captured failure modes and rationalizations — Phase 5 targets them and Phase 8 re-runs against them.
### Phase 3: Decide Scope and Location
Ask (or infer from context):
- **Scope**: project-level (`.claude/commands/{name}.md`) or global (`~/.claude/commands/{name}.md`)?
- Project-level if it depends on this repo's structure
- Global if the capability is repo-agnostic
- **Helper code location**: project's existing scripts/lib directory, or `~/.claude/lib/` for global
### Phase 4: Check for Collisions
Run the deterministic helper:
```bash
ccgm-skillify-check <name>
```
It scans the user's command directories (`~/.claude/commands/` and any `.claude/commands/` in the current project) and reports:
- Exact name collisions (abort — pick another name)
- Fuzzy matches (warn — likely overlap; consider merging instead of creating a new skill)
If the check reports a collision, stop and resolve before creating files.
### Phase 5: Write the Skill Contract (Target the RED Failures)
Create the command file with this structure:
```markdown
# /{name} - <one-line purpose>
<2-3 sentence description: what the skill does, when the agent should reach for it>
## When to Use
- <trigger condition 1>
- <trigger condition 2>
## Inputs
- `$ARGUMENTS` — <what the user passes, if anything>
## Workflow
### Step 1: <latent or deterministic>
...
### Step 2: <latent or deterministic>
...
```
Each section of the skill must correct a specific failure mode or rationalization captured in the Phase 2 RED baseline. Add the captured rationalizations to the skill's "Rationalizations" table. Do not add advice for failures the baseline agent never produced — unprompted advice is the bloat the skill-authoring discipline exists to prevent.
Follow `rules/skill-authoring.md` if installed:
- Reference files by path, don't inline large content
- Imperative voice, not second-person
- One command per bash invocation, no chaining in the runtime shell
### Phase 6: Extract Deterministic Code
For every deterministic step identified in Phase 1:
1. Write a script (bash, python, or node) that pins the computation. Pure function: same input, same output.
2. Place it in the chosen helper directory. Name it after the skill (`<name>-<verb>` or just `<name>` if there's one operation).
3. Make it executable (`chmod +x`).
4. Have the skill's workflow invoke the script instead of describing the computation in prose.
### Phase 7: Write a Pinning Test
One test per script. Pin the output for a representative input. The goal is a regression guard, not exhaustive coverage.
- Shell projects: a small bats test or a `test_<name>.sh` with exit-code asserts
- Python projects: `test_<name>.py` with unittest/pytest
- JS/TS projects: `<name>.test.ts` with vitest
The test must fail if the script's output drifts. Watch it pass before moving on.
### Phase 8: Confirm GREEN (Re-run the RED Task With the Skill)
Close the red-green loop. Re-run the **same representative task from Phase 2**, this time with the new skill loaded (a fresh subagent that has the skill, or reload and invoke the trigger). Compare against the baseline:
- The failure modes captured in RED no longer appear.
- The behavior demonstrably differs from the no-skill baseline.
**Gate:** If a captured failure persists, the skill text did not target it sharply enough. Revise the skill (back to Phase 5) and re-run. Do not proceed to Register/Report until the GREEN run differs from the baseline. A skill whose GREEN run matches its RED run changed nothing and should not ship.
### Phase 9: Register with the Learnings Store
If `ccgm-learnings-log` is available, log an entry pointing at the new skill so future `/reflect` runs and searches surface it:
```bash
ccgm-learnings-log \
--type pattern \
--content "Skill '<name>' captures <one-line capability>. Trigger: <trigger>." \
--tag skill --tag <topic> \
--file <relative-path-to-skill.md> \
--confidence 7
```
If the learnings store isn't installed, skip this phase without ceremony.
### Phase 10: Report
State the result in 3-6 lines:
- RED baseline: `<the failure modes the no-skill agent produced>`
- GREEN confirmation: `<how the skill-loaded run differed from the baseline>`
- Skill created at: `<path>`
- Helper script at: `<path>` (or "no script — pure prose workflow")
- Test at: `<path>` (confirmed passing / pending)
- Learnings entry: `<id>` (or "skipped — no learnings store")
- Next: reload Claude Code if needed, and try the trigger to confirm the skill fires
## Red Flags
Stop and reconsider if you catch yourself:
- Writing skill content before a no-skill baseline (Phase 2) was watched failing the task
- Creating a skill when the baseline agent did the task correctly with no skill — there is nothing to skillify
- Shipping the skill without a GREEN re-run (Phase 8) that differs from the baseline
- Creating a skill before the workflow has actually worked once in this session
- Skipping Phase 4 (collision check) to save time
- Writing prose for a deterministic computation instead of a script
- Shipping the skill without writing the test
- Naming the skill generically (`helper`, `util`, `fix-stuff`) — the trigger won't match anything
## Rationalizations That Mean You Are About to Skip Steps
| You are about to say... | The reality is... |
|-------------------------|-------------------|
| "I know what the agent gets wrong, skip the baseline" | If you know, the baseline confirms it in two minutes. If you are wrong, you just avoided shipping a skill that targets the wrong failure. |
| "The baseline run is slower than just writing the skill" | Writing a skill the agent did not need taxes every future invocation forever. The baseline is the cheap path. |
| "The skill works, I'll skip the GREEN re-run" | Without a re-run against the RED task, you cannot prove the skill changed anything. The GREEN run is the gate. |
| "The test is trivial, I'll add it later" | Later means never. A skill without a test rots silently. |
| "It's a one-off, no need to skillify" | If it's one-off, don't skillify. If it might recur, don't cut the test. |
| "The collision check is paranoid" | The collision check runs in 200ms. Name conflicts are silent and permanent. |
| "I'll reuse that existing script" | Check whether the existing script is tested. If not, your new skill inherits its rot. |
script (1)
bin/ccgm-skillify-check
#!/usr/bin/env bash
#
# ccgm-skillify-check — scan user + project command dirs for skill-name collisions.
#
# Usage:
# ccgm-skillify-check <name>
#
# Exit codes:
# 0 no collisions
# 1 exact collision found (do not create a new skill with this name)
# 2 fuzzy match found (warn; review before creating)
# 3 invalid usage
set -u
PROG=$(basename "$0")
die_usage() {
echo "usage: $PROG <skill-name>" >&2
echo " name must be kebab-case (lowercase, hyphen-separated)" >&2
exit 3
}
if [ $# -ne 1 ]; then
die_usage
fi
NAME=$1
# Validate kebab-case: [a-z][a-z0-9]*(-[a-z0-9]+)*
if ! printf '%s' "$NAME" | grep -Eq '^[a-z][a-z0-9]*(-[a-z0-9]+)*$'; then
echo "error: '$NAME' is not kebab-case" >&2
die_usage
fi
# Search paths (stable order). Only those that exist contribute hits.
SEARCH_DIRS=(
"$HOME/.claude/commands"
".claude/commands"
)
EXACT_HITS=()
FUZZY_HITS=()
for dir in "${SEARCH_DIRS[@]}"; do
[ -d "$dir" ] || continue
# Exact match: {name}.md in the commands directory.
if [ -f "$dir/$NAME.md" ]; then
EXACT_HITS+=("$dir/$NAME.md")
fi
# Fuzzy match: any .md whose basename shares a token with $NAME.
# Split name on '-' and look for any token as a substring in other filenames.
while IFS='-' read -ra TOKENS; do
for tok in "${TOKENS[@]}"; do
[ ${#tok} -ge 4 ] || continue # skip short tokens to limit noise
while IFS= read -r -d '' file; do
base=$(basename "$file" .md)
[ "$base" = "$NAME" ] && continue
FUZZY_HITS+=("$file (shares '$tok')")
done < <(find -L "$dir" -maxdepth 1 \( -type f -o -type l \) -name "*${tok}*.md" -print0 2>/dev/null)
done
done <<< "$NAME"
done
# De-duplicate fuzzy hits (a single file matching multiple tokens would appear twice).
if [ ${#FUZZY_HITS[@]} -gt 0 ]; then
UNIQUE_FUZZY=()
while IFS= read -r line; do
UNIQUE_FUZZY+=("$line")
done < <(printf '%s\n' "${FUZZY_HITS[@]}" | sort -u)
FUZZY_HITS=("${UNIQUE_FUZZY[@]}")
fi
if [ ${#EXACT_HITS[@]} -gt 0 ]; then
echo "EXACT collision: a skill named '$NAME' already exists."
for hit in "${EXACT_HITS[@]}"; do
echo " - $hit"
done
echo ""
echo "Choose another name or update the existing skill instead."
exit 1
fi
if [ ${#FUZZY_HITS[@]} -gt 0 ]; then
echo "FUZZY matches for '$NAME' (review before creating a new skill):"
for hit in "${FUZZY_HITS[@]}"; do
echo " - $hit"
done
echo ""
echo "If any of these cover the same capability, extend that skill rather than creating a new one."
exit 2
fi
echo "OK: no skill named '$NAME' or close variants found."
exit 0