| name | self-evolve |
| description | Capture user-correction patterns from this session and, when a pattern recurs, draft a new project skill. Use at end of session, when the user signals wrap-up, or when invoked directly. |
Self-Evolve
Use /self-evolve to turn this session's mistakes into reusable project skills.
When to run
- User signals end-of-session ("done", "bye", "thanks", "/exit", "wrapping up", "ship it").
- You finish the user's last task with no pending todos and they have not requested follow-up.
- The user invokes
/self-evolve directly.
Skip if: the session was fewer than 3 turns, or the session contained no user corrections.
What counts as a "correction"
A user message right after one of your responses that pushes back on what you did. Signal phrases (case-insensitive):
- explicit rejection: "no", "wrong", "that's wrong", "not what i asked", "undo", "revert"
- redirection: "wait", "stop", "actually", "instead", "rather"
- prohibition: "don't", "do not"
Ignore false positives ("no problem", "stop the server", "don't worry") by checking that the phrase rebukes your prior action.
The loop
0. Once-per-session guard
Two checks. If either trips, stop immediately, say "self-evolve already ran this session", and do nothing else.
Exception (both checks): if the user explicitly retyped /self-evolve to force a re-run, skip both checks.
Check A — conversation memory. If you have already invoked /self-evolve in this conversation, stop.
Check B — durable marker. Read .omp/self-evolve/.last-run-session (single-line UUID, may not exist). Determine the current Copilot CLI session UUID via shell:
ls -td ~/.copilot/session-state/*/ 2>/dev/null | head -1 | xargs -n1 basename
If the marker file exists and its contents match the current session UUID, stop. (If ~/.copilot/session-state/ is empty or unreadable, skip Check B and rely on Check A alone.)
Check B survives session resume (copilot --resume) and conversation compaction, where Check A could miss the earlier invocation.
1. Inspect this session
Walk back through the conversation and list every correction event. For each, record:
- topic — short kebab-case label (e.g.
trailing-newline-shell-output, python-string-quotes, unwanted-readme-edits)
- area — file path or subsystem the correction touched, or
- if none
- summary — one sentence: what you did wrong and what the user wanted instead
2. Append to the ledger
The ledger lives at .omp/self-evolve/log.md. If .omp/self-evolve/ does not exist but the legacy .oh-my-copilot/self-evolve/ does, move the legacy directory to .omp/self-evolve/ first (mkdir -p .omp && mv .oh-my-copilot/self-evolve .omp/self-evolve). Create the directory and file if missing. Append one entry per correction in this exact shape:
- YYYY-MM-DD | <topic> | <area> | <summary>
Keep entries chronological. Never rewrite past entries.
3. Count repeats
For each new topic from this session, grep the ledger for the same topic label. The count includes today's entries.
Threshold: 3 occurrences. Fewer → stop here.
4. Check existing coverage
Before drafting, list:
.github/skills/*/SKILL.md (project skills, including any previously promoted learned-*)
.omp/self-evolve/drafts/*/SKILL.md (in-flight drafts not yet promoted)
~/.copilot/skills/*/SKILL.md (user skills, if present)
Match bar (high, not vague). A skill counts as covering this topic only if:
- its frontmatter
description explicitly names the exact behavior the user kept correcting, OR
- it contains a
Do or Don't bullet that, applied literally, would have prevented every correction in the cluster.
Generic adjacency does not count. A "code quality" skill does not cover "respect Python quote style"; a "respect-quotes" skill does. When in doubt, treat as not covered.
If clearly covered, do not draft. Append one note to the ledger and stop:
# covered-by: <existing-skill-name> | <topic>
If covered ambiguously (some bullets are adjacent but none are a direct match), still draft — but add a line to the new draft's Source section noting the overlap, so a human reviewer can decide on merge or supersede:
possible-duplicate-of: <existing-skill-name>
Bias: when unsure, draft. Drafts live in .omp/self-evolve/drafts/ and are inert until a human promotes them, so a stray draft costs nothing while a missed pattern wastes signal.
5. Draft the new skill
Path: .omp/self-evolve/drafts/<slug>/SKILL.md
This is outside .github/skills/ on purpose. Drafts must NOT live in the plugin's active skill root: anything under .github/skills/ is loaded as an active skill on the next Copilot session, so a draft there would silently auto-arm before a human reviewed it. The .omp/self-evolve/drafts/ location is never read by Copilot CLI; a human promotes a draft by moving its directory to .github/skills/learned-<slug>/ (see docs/self-evolve.md).
- Slug rule: kebab-case of the topic, max 40 chars.
- The draft's frontmatter
name should be learned-<slug> (matches the target dir name a human will promote it into).
Write the file with this exact frontmatter and body:
---
name: learned-<slug>
description: <one sentence — when this skill should fire>
status: draft
---
# Learned: <human title>
Invoke `/learned-<slug>` when the trigger below applies.
## Trigger
<one-line condition derived from the recurring corrections>
## Do
<concrete instruction(s) that would have prevented the corrections>
## Don't
<the wrong behaviour you kept doing>
## Source
Drafted by /self-evolve from 3+ corrections in .omp/self-evolve/log.md.
Promote to active by moving this directory to .github/skills/learned-<slug>/.
6. Report to the user
State:
- how many corrections this session contributed to the ledger,
- whether any topic crossed the threshold,
- the path of any draft skill written,
- the path of the ledger.
7. Persist the session marker
Before exiting, write the current Copilot CLI session UUID to .omp/self-evolve/.last-run-session (overwrite, no newline needed). Use the same shell line as Step 0 to determine it. Subsequent invocations within the same session will short-circuit via Check B in Step 0.
If ~/.copilot/session-state/ was empty or unreadable in Step 0, write the literal string unknown-session so the marker exists but cannot accidentally match a real UUID later.
Output discipline
- One ledger line per correction. Never batch into a paragraph.
- One draft skill per recurring topic. Never combine unrelated topics.
- Drafts always carry
status: draft. A human promotes them by moving the draft directory from .omp/self-evolve/drafts/<slug>/ into .github/skills/learned-<slug>/ (and optionally deleting the status: draft line). Until that move, the draft is inert — Copilot CLI does not load it.
- If unsure whether something is a correction, skip it. False negatives are cheap; false positives pollute the loop.