Distill session insights into rules, skill improvements, recipes, and cross-repo promotions to marketplace plugins. Use when capturing learnings, codifying workflow into .claude/rules, or promoting a session-invented pattern into a specific plugin/skill as a PR.
Distill session insights into rules, skill improvements, recipes, and cross-repo promotions to marketplace plugins. Use when capturing learnings, codifying workflow into .claude/rules, or promoting a session-invented pattern into a specific plugin/skill as a PR.
Distill session insights into reusable project knowledge.
When to Use This Skill
Use this skill when...
Use alternative when...
End of session, want to capture learnings
Full end-of-session pass (wrap + distill + feedback) -> session-plugin:session-end
Discovered a project pattern worth codifying
Capturing loose threads to taskwarrior -> session-plugin:session-wrap
Want learnings as rules/recipes in this repo
Need to write a blog post -> /blog:post
Discovered a pattern worth reusing
Need to analyze git history for docs gaps -> /git:log-documentation
Found a CLI workflow worth saving as a recipe
Need to configure a justfile from scratch -> /configure:justfile
Want to update rules based on session experience
Need to check project infrastructure -> /configure:status
Asked to "codify the workflow" or "analyze and promote session patterns to rules"
Need a one-off implementation, not a reusable rule -> implement directly
A pattern is reusable beyond this repo and belongs in a shared plugin/skill
The learning is project-specific -> keep it in this repo's .claude/rules
The session invented a technique with no home skill yet, or one a named plugin's skill is missing
Reporting friction/errors for triage -> feedback-plugin:feedback-session (the error loop)
May also be reached via the end-of-session flow: the plugin's Stop hook (hooks/session-end-nudge.sh) offers session-plugin:session-end once per session on user wind-down, and the orchestrator runs this skill when a durable learning qualifies.
Core Principle: Update Over Add
Before proposing any artifact, evaluate: Does it update an existing one? Does an existing one already cover this? Is this genuinely new and reusable? See REFERENCE.md for detailed evaluation criteria.
Only analyze potential process/methodology captures (script+recipe or project-local .claude/skills/ skill)
--all
Analyze all categories (default)
--dry-run
Show proposals without applying changes
Tool Call Efficiency
Minimize LLM round-trips: batch file reads in a single response, combine evaluation and redundancy checking in one pass, complete one category before starting the next.
Execution
Execute this session distillation workflow:
Step 1: Run the distill collector, then read conversation for rules
Run the read-only collector — the distill-side analogue of session-survey.sh.
It mines this session's transcript (and the cross-session window) for the
mechanical signals, so you don't re-read the whole conversation for
commands/edits or re-run just --dump from memory:
RECIPE_CANDIDATES — normalized commands that recurred across separate
sessions or are commit-bracketed this session, and are NOT already a just
recipe or churn (status/diff/log/test/build/ls/…). Each carries a
concrete _FIRST example, _SESSIONS count, and _NOVEL_TOKENS.
HOT_FILES — the files this session edited/wrote most (exact paths) — where
rule/doc updates likely land.
COMMIT_INTERVALS + COMMAND_DIGEST — the mechanical grouping you use to
name a process or sequence. The script never infers a sequence itself
(sequence-naming is judgment); it hands you completed-work intervals.
RULE_HINTS_FROM_TOOLING — repeated permission/auth denials, the only
mechanical rule signal.
When TRANSCRIPT_AVAILABLE=false / STATUS=SKIP (fresh clone, remote sandbox,
mid-conversation flush, or no --session-id), fall back to reading the
conversation history directly for commands and edits.
Durable rules live in conversation reasoning, not tool_use mining. For
the rules category always read the conversation's decisions, corrections, and
constraints yourself — the collector deliberately does not pre-compute rules
beyond the narrow RULE_HINTS_FROM_TOOLING denial signal.
Step 2: Evaluate and check redundancy (single pass per category)
When --all: complete rules -> skills -> recipes/process. Do not interleave.
Rules (.claude/rules/*.md): from the conversation reasoning (plus any
RULE_HINTS_FROM_TOOLING signal), Glob rule files and Read only the subset
the learning touches — the HOT_FILES paths and the rules adjacent to them —
then evaluate each insight in one pass (update/skip/remove/merge/add). Do not
glob-read every rule when the collector already narrowed the surface.
Skills: Glob relevant skill files (target specific plugins from Step 1),
Read in one response, evaluate in one pass.
Recipes / process: the collector already ran just --dump, so
RECIPE_CANDIDATES are already novel (not existing recipes). Route each per the
destination table — a recurring single
command → a just recipe; a multi-step workflow → a script or a project-local
skill (see --process).
Step 3: Present proposals
Categorize as: [UPDATE], [SKIP], [NEW], [REDUNDANT], or [PROMOTE] with file paths and reasons.
[PROMOTE] is the additive, cross-repo category — distinct from the others,
which all write this repo's .claude/. Use it when the insight is reusable
beyond this repo and belongs in a marketplace plugin: either a pattern the
session invented that has no home skill yet (→ propose a new skill), or a
capability an existing named skill is missing (→ propose an edit to it). A
[PROMOTE] does not require anything to have gone wrong — a smooth session that
produced a strong reusable technique is exactly its trigger. Each [PROMOTE]
names a target <plugin>/skills/<skill> (new or existing) and is applied as a
PR against the plugin repo, never an edit to the current repo (see
Cross-Repo Promotion).
Step 4: Apply changes
If --dry-run: skip this step.
In auto mode: apply proposals directly without per-category AskUserQuestion. All targets are reversible via git restore — rule files, skill files, and justfile recipes are tracked in git, so a wrong edit can be undone with one command. This matches auto mode's "prefer action over planning" directive. Retain AskUserQuestion for destructive operations ([REDUNDANT] proposals that remove a rule or recipe).
In manual / interactive mode: use AskUserQuestion to confirm each category before applying. The user can multi-select which [UPDATE] / [NEW] proposals to accept.
In plan mode: neither default applies — the harness disallows non-readonly tool calls (including AskUserQuestion-then-apply) except writes to the active plan file. Write the proposal set to the active plan file as a single coherent block (Context + per-category [UPDATE] / [NEW] / [REDUNDANT] sections + a brief verification section), then call ExitPlanMode to surface for user approval. Do not apply directly. After the user approves the plan, fall back to the auto-mode or manual-mode flow above depending on which is active.
For [PROMOTE] proposals, do not edit the current repo. Apply them via the
cross-repo PR hand-off below — gate it behind AskUserQuestion in every mode
(opening a PR against another repo is outward-facing), and never push to that
repo's default branch.
Step 5: Report summary
Output concise summary of changes made, including any [PROMOTE] PRs opened
(with their URLs) so the promotion is traceable.
Routing a learning to a destination
Each surviving insight goes to exactly one home. Pick most-specific first — a
new artifact type was deliberately not added (no .claude/runbooks/); a
project-local process reuses the .claude/skills/ convention CLAUDE.md
documents as a first-class, auto-loaded home.
The learning is…
Destination
Proposal tag
A convention/constraint that prevents mistakes
.claude/rules/<name>.md
[UPDATE] / [NEW]
A recurring single command with fixed flags (a RECIPE_CANDIDATE)
a just recipe
[UPDATE] / [NEW]
A deterministic multi-step workflow (no decision points)
scripts/<name>.sh + a thin just recipe wrapping it
[NEW]
A multi-step process with decision points, project-local
a project-local .claude/skills/<name>/SKILL.md (auto-loaded, no marketplace entry — see the repo's CLAUDE.md)
[NEW]
Reusable beyond this repo
a marketplace plugin/skill via PR
[PROMOTE]
The --process category covers the two multi-step rows: a deterministic
workflow becomes scripts/*.sh + a recipe (offload to a deterministic
substrate); a judgment-bearing one becomes a project-local skill. Name the
sequence yourself from COMMIT_INTERVALS / COMMAND_DIGEST — the collector
gives you the grouping, not the name.
Cross-Repo Promotion ([PROMOTE])
The other categories keep knowledge in this repo. [PROMOTE] is how a
session-invented pattern reaches the shared plugin marketplace so every repo
benefits — the additive complement to feedback-plugin's error loop (which only
fires on friction). A near-zero-friction session can still produce several
[PROMOTE] candidates.
Routing: which plugin/skill should own it
Pick the target by the pattern's domain, most specific first:
Pattern is about…
Likely owner
A language/tool's build/test/lint (cargo, uv, biome…)
that language plugin (rust-plugin, python-plugin, …)
propose a new skill in the closest plugin and flag the routing choice for review
Then decide new skill vs. edit existing: glob the owner plugin's skills/,
read the closest few, and prefer extending an existing skill (a new section +
cross-link) over a new skill unless the pattern is genuinely its own topic
(Update Over Add still applies — across repos now).
The PR hand-off (isolated clone — never edit cwd, never push to default)
The plugin source lives in its own repo. Open a PR there; the human reviews and
merges. Match the repo's conventions: skills are auto-discovered (add
skills/<name>/SKILL.md with dated frontmatter + user-invocable/allowed-tools),
update the plugin README's skill catalog, keep !-context commands free of pipes/
redirects, use a conventional commit (feat(<plugin>): for a new skill,
docs(<plugin>): for an edit — release-please versions from it), and apply the
<plugin> routing label (create it if missing).
Do the whole promote in a throwaway clone, never in a long-lived local
checkout of the plugins repo. That checkout is frequently contended by a
concurrent Claude session: a coworker's operation can autostash your in-flight
edit and move HEAD between two of your calls, so the next git add/commit
reports "nothing to commit, working tree clean" and the edit is silently gone
(issue #2113). A fresh clone shares no .git with that checkout, so no coworker
can move HEAD under it. git worktree add is not equivalent — it
registers in the shared checkout's .git and was itself observed failing
(already used by worktree) once HEAD had moved.
Remove the throwaway (rm -rf "$WORK") only after the PR URL is in hand — it is
the only copy of the work until the push lands.
Cross-references for the shared-checkout hazard this avoids:
repos/.claude/rules/shared-checkout-branch-isolation.md (the
git log --oneline origin/main..HEAD verification above — a branch must contain
only your own commits before you push), repos/.claude/rules/concurrent-session-pr-check.md
(before recreating work that "vanished", check whether a peer session already
opened a PR for it — never pop a shared stash), and git-plugin:git-coworker-check
(run it before any operation that genuinely must touch a shared checkout).
The PR body should cite the session as evidence (what the pattern is, why it's
reusable, where it was used) — the additive analogue of the friction loop's
evidence summary.
Agentic Optimizations
Context
Command
Distill collector (recipe candidates + hot files + process groupings)