Skillify

workflow no always-loaded rules -- loads on demand updated 2026-08-04

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

  • skills
  • authoring
  • durability
  • meta-learning

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:

  1. Identify the capability and its trigger (and classify each step as latent vs deterministic)
  2. 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
  3. Decide scope and location
  4. Check for name collisions against existing commands
  5. Write the skill contract, targeting only the RED failures
  6. Extract deterministic steps into a helper script
  7. Write a pinning test for the script
  8. Confirm GREEN (gate): re-run the same RED task with the skill loaded and confirm the behavior changed
  9. Register a pointer in the learnings store
  10. 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 /skillify workflow leans on in Phase 1
  • self-improving — provides ccgm-learnings-log which /skillify uses 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.

Manual, per file

Full control -- copy exactly the files you want from the sections below.

Files

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