evolve — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited evolve (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<objective> Cluster active and proven instincts by lexical similarity and trigger family, write CLU-*.md cluster files, identify project instincts eligible for promotion, and update the INSTINCTS.md index with a Clusters section. </objective>
You are clustering existing instincts — not extracting new ones and not promoting anything automatically. This is the structural pass that groups related behavioral rules so future skills can act on them.
Determine scope from the invocation arguments:
--global → only load from ~/.claude/instincts/global/--project <slug> → load from global AND ~/.claude/instincts/projects/<slug>/--global behavior)GLOBAL_DIR="$HOME/.claude/instincts/global"
ls "$GLOBAL_DIR"/INS-*.md 2>/dev/nullIf --project <slug> was passed, also load:
PROJECT_DIR="$HOME/.claude/instincts/projects/<slug>"
ls "$PROJECT_DIR"/INS-*.md 2>/dev/nullFor each instinct file found, read the full content and parse the YAML frontmatter. Extract:
id, name, status, confidencesignals.trigger_patterns (list of strings)lineage.cluster_id (current cluster assignment if any)score.successes, score.confirmations, score.opportunities (or len of evidence array as opportunity proxy)evidence (array length = opportunity count)created_at## Operational Rule body text (the rule text used for similarity)Filter: Only keep instincts where status is active or proven. Candidates are too immature to cluster.
If fewer than 2 active/proven instincts remain after filtering, output:
Not enough instincts to cluster.
Found N total instinct(s) but only M with status=active or status=proven.
Clustering requires at least 2 active/proven instincts.Then stop.
First, try the cluster library:
python3 -c "
import sys, json; sys.path.insert(0, '$HOME/.claude/instincts/lib')
from cluster import cluster_instincts
clusters = cluster_instincts('$HOME/.claude/instincts/global/', min_similarity=0.55)
print(json.dumps(clusters, default=str))
" 2>/dev/nullIf the cluster library is unavailable (ImportError or non-zero exit), fall back to manual pairwise comparison using trigram_jaccard. Run the comparison across ALL loaded instincts (global + project if applicable):
python3 - <<'PYEOF'
import sys, json, os
sys.path.insert(0, os.path.expanduser('~/.claude/instincts/lib'))
from similarity import trigram_jaccard, parse_instinct_file
# Build instinct list from all loaded files
files = <LIST_OF_INSTINCT_FILE_PATHS>
instincts = [parse_instinct_file(f) for f in files]
instincts = [i for i in instincts if i and i.get('rule_text')]
# Pairwise similarity
pairs = []
for i in range(len(instincts)):
for j in range(i + 1, len(instincts)):
a, b = instincts[i], instincts[j]
sim = trigram_jaccard(a['rule_text'], b['rule_text'])
if sim >= 0.55:
pairs.append({'a': a['id'], 'b': b['id'], 'sim': round(sim, 4),
'a_name': a['name'], 'b_name': b['name']})
pairs.sort(key=lambda x: x['sim'], reverse=True)
print(json.dumps(pairs))
PYEOFClustering logic (union-find approach): Start with each instinct in its own singleton group. For each similar pair (similarity >= 0.55), merge their groups. After processing all pairs, groups with 2+ members become clusters. Singletons are listed in the "No Clusters" section of the report.
When assigning cluster names and trigger families:
trigger_patterns from member instinctstrigger_family = the shortest common prefix/theme across all trigger patternsFor each cluster, compute:
avg_confidence = mean of all member instincts' confidence valuesskill_hypothesis = one-line description of what skill this cluster could become (e.g., "A skill that enforces correct Slack unread detection and triage patterns")Ensure the clusters directory exists:
mkdir -p "$HOME/.claude/instincts/global/clusters"For each cluster with 2+ members, generate a unique ID:
SUFFIX=$(python3 -c "import secrets; print(secrets.token_hex(2))")
CLU_ID="CLU-$(date +%Y%m%d)-${SUFFIX}"Check if a cluster file for this group already exists by reading existing CLU-*.md files in ~/.claude/instincts/global/clusters/ and comparing their member_ids sets. If an existing cluster contains a subset or superset of the current member set (overlap >= 50%), treat it as the same cluster and update rather than create.
For a NEW cluster, write ~/.claude/instincts/global/clusters/CLU-YYYYMMDD-XXXX.md:
---
id: CLU-YYYYMMDD-XXXX
name: "<generalized cluster name in kebab-case>"
member_ids: [INS-..., INS-...]
avg_confidence: 0.XX
trigger_family: "<common pattern>"
skill_hypothesis: "<one-line: what skill would this cluster become?>"
status: candidate
created_at: "<ISO-8601>"
updated_at: "<ISO-8601>"
---
## Members
- INS-... | "<name>" | confidence: 0.XX | scope: global|project
- INS-... | "<name>" | confidence: 0.XX | scope: global|project
## Trigger Family
Shared patterns: <comma-separated list>
## Skill Hypothesis
<2-4 sentences describing the generalized behavioral rule this cluster represents and what a synthesized skill would enforce.>For an UPDATED cluster (existing CLU file gains a new member), update member_ids, avg_confidence, updated_at, and the ## Members section. Append the new member line.
After writing each cluster file, update each member instinct's lineage.cluster_id using the confidence library helper:
python3 -c "
import sys
sys.path.insert(0, '$HOME/.claude/instincts/lib')
from confidence import update_instinct_file
update_instinct_file('<INSTINCT_PATH>', {
'lineage.cluster_id': '<CLU_ID>',
'updated_at': '<ISO_TIMESTAMP>',
})
"If the helper fails, use the Edit tool to do a targeted replacement of cluster_id: null with cluster_id: <CLU_ID> in the instinct's frontmatter.
This step only runs if project instincts were loaded (i.e., --project <slug> was passed).
Scan all proven project instincts (those with scope: project and status: proven). For each, check all three promotion eligibility criteria:
confidence >= 0.85opportunities >= 15 (use len(evidence) as opportunity count proxy if no explicit field)## Operational Rule text that are project-specific (project names, file paths, tool names unique to the project, API endpoints, etc.). The ratio of project-specific tokens to total tokens must be < 30%.For the generality check, use this heuristic:
*.py/*.js that appear to be project-specific, API URLs with project-specific domains, team names, ClickUp/Linear IDs.Report each eligible instinct but do NOT modify it. Only /promote moves instincts.
Read ~/.claude/instincts/global/INSTINCTS.md. Find the ## Clusters section. If it does not exist, append it at the end of the file.
Rebuild the ## Clusters section from scratch by reading ALL CLU-*.md files currently in ~/.claude/instincts/global/clusters/:
## Clusters
- CLU-XXXXXXXX-XXXX | N members | avg_conf: 0.XX | "<trigger family>"
- CLU-XXXXXXXX-XXXX | N members | avg_conf: 0.XX | "<trigger family>"Sort entries by avg_confidence descending. If there are no clusters at all, keep the section as:
## Clusters
(none yet)Use the Edit tool to replace the existing ## Clusters section content with the rebuilt version. Do not touch any other section.
Output a summary to the user:
## Instinct Evolution Report
**Analyzed**: N instincts (N active, N proven) across N scope(s)
**Clusters formed**: N new, N updated
### New Clusters (N)
- CLU-XXXXXXXX-XXXX | N members | "<trigger family>" | skill hypothesis: "<one-line>"
Members: INS-XXX ("name"), INS-XXX ("name")
Avg confidence: 0.XX | Min similarity: 0.XX
### Updated Clusters (N)
- CLU-XXXXXXXX-XXXX | added INS-XXX | N→N+1 members | "<trigger family>"
### Promotion Candidates (N)
- INS-XXX | "<name>" | confidence: 0.XX | opportunities: N | scope: project/<slug>
→ Eligible for /promote — run /promote <id> to move to global scope
### No Clusters (N singletons)
- INS-XXX | "<name>" — no similar instincts found (best pair similarity: 0.XX)
- INS-XXX | "<name>" — no similar instincts found (no pairs above 0.55 threshold)If there are 0 promotion candidates, omit that section entirely. If there are 0 singletons (all instincts clustered), omit the singletons section. If there are 0 updated clusters, omit that section.
/promote.~/.claude/instincts/global/clusters/ exists before attempting to write CLU-*.md files.lineage.cluster_id, only change that one field. Never rewrite the whole instinct file.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.