Use when asked to find automatable routines, improve an existing skill, review skill candidates, or list and roll back autosave-installed skills. Detects repeated procedures, reviews create/patch/support-file skill proposals (human-in-the-loop), and audits autosave auto-mode changes.
Resources
1Install
npx skillscat add jinwon-int/ccc-node/skillsuggest Install via the SkillsCat registry.
skillsuggest — propose skills from repeated work (+ autosave post-hoc review)
Approximates "auto-skillification": find procedures you keep repeating and
either improve the matching skill or create a distinct one. Detection is
automatic; anything this skill authors or applies requires user approval.
Skill Review may stage legacy SKILL.md drafts or isolated v2proposal.json create/patch/write_file packages under the pending queue.
Two autosave modes change what "review" means here (docs/skill-autosave.md):
- approve (default): drafts wait in the pending queue; this skill is the approval gate (step 1 below).
- auto (#355, opt-in): machine gates install passing drafts unattended and the owner is notified after the fact; this skill becomes the post-hoc review / rollback tool (step 1b below). Drafts that failed a gate stay pending and are still approved/rejected via step 1.
Procedure
Check pending Skill Review drafts first (LLM-drafted, still human-gated):
The queue is node-global. Resolve it withCCC_SKILL_REVIEW_STATE_DIR, never
withCCC_STATE_DIR— the bridge scopes that one per memory audience, and
reading it here reports an empty queue while real drafts sit unread.STATE="${CCC_SKILL_REVIEW_STATE_DIR:-$HOME/.claude/state}" find "$STATE/pending-skills" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort$STATE/pending-skills/index.jsonlis the one-row-per-draft ledger
(status from the approve/install/reject rename suffix, prescreen verdict,archived:<kind>rows from the archive manifests). The nightly sweep
rebuilds it; if it looks stale or empty,ccc-skill-autosave.sh reindex
rebuilds it on demand (#2283).
For a chosen<id>:STATE="${CCC_SKILL_REVIEW_STATE_DIR:-$HOME/.claude/state}" jq . "$STATE/pending-skills/<id>/meta.json" AUTO="${CCC_CLAUDE_DIR:-$HOME/.claude}/hooks/skill-review/autoinstall.sh" if [ -f "$STATE/pending-skills/<id>/proposal.json" ]; then bash "$AUTO" render <id> else sed -n '1,220p' "$STATE/pending-skills/<id>/SKILL.md" fiA draft with a
prescreen.jsonwas already read by the fleet intake
reviewer (rubric 2026-08-28.2, #2183). Read its verdict first — it tells
you where to look, it does not decide for you:jq '{verdict, max_severity, status, findings: (.findings // [] | map("\(.severity)/\(.area): \(.note)"))}' "$STATE/pending-skills/<id>/prescreen.json" 2>/dev/nullapprove= nothing found, skim and decide;revise= read the listed
findings against the draft;status: error= the reviewer could not run,
review as if unscreened. Drafts the reviewer rejected with a blocker are
not in this queue any more — they sit under$STATE/skill-autosave-archive/prescreen-reject-<date>/with the blocker
text inmanifest.jsonl;ccc-skill-autosave.sh pending-restore <id>
brings one back if the reviewer was wrong.
For a v2 proposal, approve only after checking its exact target, expected
hashes, provenance and full diff/content. Never copy v2 content by hand:bash "$AUTO" apply <id>For a legacy
SKILL.mddraft, approve only after reading the full draft and
checking for node-specific facts or secrets:STATE="${CCC_SKILL_REVIEW_STATE_DIR:-$HOME/.claude/state}" id="<id>" name="$(jq -r '.name // empty' "$STATE/pending-skills/$id/meta.json")" [ -n "$name" ] || name="$(awk 'NR>1 && /^---/{exit} /^name:/ {sub(/^name:[[:space:]]*/,""); print; exit}' "$STATE/pending-skills/$id/SKILL.md")" mkdir -p "$HOME/.claude/skills/$name" cp "$STATE/pending-skills/$id/SKILL.md" "$HOME/.claude/skills/$name/SKILL.md" # #2374: a hand-copied SKILL.md has no autosave marker, so it is a node-local # install that is never promoted (local-installed:manual, Wiki TM-3906) jq '.status="approved" | .lifecycle="local-installed:manual"' "$STATE/pending-skills/$id/meta.json" > "$STATE/pending-skills/$id/meta.approved.json" mv "$STATE/pending-skills/$id" "$STATE/pending-skills/$id.approved-$(date -u +%Y%m%d%H%M%S)"Reject by archiving rather than deleting:
STATE="${CCC_SKILL_REVIEW_STATE_DIR:-$HOME/.claude/state}" # record the owner's decision on the draft (#2283 lifecycle, #2373: an owner # reject is an archive reason, not the P6 fleet review `verdict:*`) m="$STATE/pending-skills/<id>/meta.json" [ -f "$m" ] && jq '.status="rejected" | .lifecycle="archived:owner-rejected"' "$m" > "$m.tmp" && mv "$m.tmp" "$m" mv "$STATE/pending-skills/<id>" "$STATE/pending-skills/<id>.rejected-$(date -u +%Y%m%d%H%M%S)"A pending draft with an
autosave-block.jsonfile was machine-rejected by
the auto mode gate —jq . "$STATE/pending-skills/<id>/autosave-block.json"
shows the reason (secret / node-specific / lint / dedup / codex-incompat /
unverified-claim / dead-citation). Give those extra scrutiny before
approving.The last two come from
gate_unverified_claimsand mean the draft states a
falsifiable technical fact the reader cannot re-derive:unverified-claim exit-code|http-status|version-pin— the draft asserts an
exit code, HTTP status, or pinned version with no citation: no URL, nofile.ext:linesource reference, no--help/--versioncommand shown,
and no dated "verified" marker. Do not approve by judging whether the claim
sounds right. Re-derive it: run the command, or read the source, then
require the draft to carry that evidence before approval.dead-citation http-404|http-410— a URL the draft cites is gone. Find the
live path and correct the citation; a dead citation is indistinguishable
from a fabricated one to the next reader.
The gate checks citability, not truth — a machine cannot verify a claim
is correct, only that it is checkable. Approving one of these means you
became the verification step; actually do the check.
1b. Autosave post-hoc review / rollback (auto mode installs are tracked in a
ledger and always reversible):
AUTO="${CCC_CLAUDE_DIR:-$HOME/.claude}/hooks/skill-review/autoinstall.sh"
bash "$AUTO" list # ledger + currently installed + blocked drafts
bash "$AUTO" status # mode, daily cap usage, recent activity
bash "$AUTO" rollback <name> # archive one auto-installed skill (undo)
bash "$AUTO" rollback --all # bulk-undo every auto-installed skill Rollback archives into ~/.claude/state/skill-autosave-rollback/ (never
deletes) and refuses skills that lack the .autosave-meta.json marker, so
hand-authored skills are untouchable. Mode switch (owner decision — ask
before changing it): ~/.claude/hooks/ccc-skill-autosave.sh set-mode review
restores the human gate (the fleet default since #2011);
set-mode auto (or exporting CCC_SKILL_AUTOSAVE_MODE=auto) opts back in.
Refresh deterministic candidates (command-shape scan of transcripts):
bash ~/.claude/skills/skillsuggest/scan.sh cat ~/.claude/state/skill-candidates.md(The daily skill-autosave sweep also refreshes this file and drafts skills
from bridge/SDK transcripts — enable it withscripts/install-skill-autosave-cron.sh --apply; seedocs/skill-autosave.md.)Interpret, don't dump. Read the ranked command shapes and cluster them into procedures:
- Group related high-count shapes by tool/intent (e.g.
wiki-agent write-path+wiki-agent pr= the wiki flow). - Drop shapes already covered by an existing skill (listed in the report).
- Drop one-off/trivial shapes; a skill is worth it only for a multi-step procedure you repeat across sessions.
- Group related high-count shapes by tool/intent (e.g.
Propose (max ~3). For each strong candidate, show the user a short proposal: name, one-line description, the steps it would encode, and why it recurs. Ask for approval (numbered options).
4b. Pending-draft reviews use the full review format. When presenting blocked/pending drafts for a decision, show per draft: 배경 (origin session id/date + the task that produced it — read the source transcript's opening user messages when available), 제안 이유 (what recurring pain/procedure it encodes), 차단 사유·정당성 (the gate reason and whether the gate was right), 개선사항 (numbered, concrete: what must change before approval — heading format, trigger-style description, node-specific path generalization, session-specific numbers), and a 판정 (approve-after-fix / reject-and-why / hold). Then a single numbered approval request.
- Author on approval only. For each approved deterministic candidate, create
~/.claude/skills/<name>/SKILL.md:- Frontmatter:
name(kebab-case) + a detaileddescription(it drives auto-matching). - Body: numbered steps, exact commands, and safety rules (no raw secrets — read keys from the node's env file, resolved at run time rather than hardcoded; redact in output). A 2026-08-28 fleet check found
~/.hermes/.envon 8 of 11 nodes and/opt/ccc-node/bridge/.envon the others, so a skill that names one path is wrong on roughly a third of the fleet. This matters here specifically: a path baked into this authoring rule is reproduced into every skill drafted from it. - Offer to also land it in the
jinwon-int/ccc-nodetemplate (claude/skills/) via PR, and record it in the Wiki (use thewiki-recordskill). - When landing a new
claude/skills/<name>/in the template, also add its classification entry tocodex/compatibility.json(adaptedwith a codex mirror, orclaude-onlywith a reason). The catalog is fail-closed: an unclassified skill failsvalidate-harness(catalog_unclassified) and blocks CI (#789).
- Frontmatter:
Rules
- Never author or overwrite a skill without explicit approval. (In auto mode the
pipeline installs machine-gated drafts on its own — but you, running this
skill, still never install, roll back, or change the mode without the user's OK.) - Keep skills node-agnostic where possible; keep secrets out (locations/handling only).
- The scan is a heuristic over command shapes — always sanity-check that a candidate is a real recurring procedure before proposing.
- Treat rollback as safe and cheap: when the user doubts an auto-installed skill, roll it back first and re-propose later.