skills/skill-vetter/SKILL.md
Assess trust and safety of external SKILL.md files before importing into Cairn. Use when asked to vet, review, import, or check an external skill. Keywords: vet, vetting, trust, safety, review skill, check skill, import skill, external skill, security review
npx skillsauth add avifenesh/cairn skill-vetterInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Security assessment of external SKILL.md files before importing into Cairn's skill system.
Determine the target file from $ARGUMENTS:
cairn.shell: gh api repos/OWNER/REPO/contents/PATH --jq '.content' | base64 -d > /tmp/vetting-skill.md
cairn.shell: curl -sL --max-time 15 --max-filesize 524288 'URL' > /tmp/vetting-skill.md
Set FILE to the resolved path. If --repo owner/name is provided, save it for step 5.
Read the file and validate structure:
cairn.shell: head -50 "$FILE"
cairn.shell: wc -l "$FILE"
cairn.shell: sha256sum "$FILE"
Check each frontmatter field:
| Field | Requirement |
|-------|-------------|
| name | Present, lowercase, max 64 chars. If inside a skill directory, should match directory name (warning only for temp/standalone files) |
| description | Present, includes trigger phrase ("Use when...") |
| disable-model-invocation | Set to true for side-effect skills (deploy, send, delete, write, execute) |
| allowed-tools | Present and scoped (flag bare Bash without cairn. prefix) |
| inclusion | on-demand unless explicitly justified as core reference |
| body length | Under 500 lines |
Check file size before processing:
cairn.shell: wc -c < "$FILE" | awk '{if ($1 > 1048576) print "WARNING: file exceeds 1MB"; else print "OK:" $1 "bytes"}'
Run consolidated checks against the file and record findings:
Blockers (any match = UNTRUSTED) — single combined grep:
cairn.shell: grep -nEi \
-e '(Bearer\s+[A-Za-z0-9._~+/\-]{20,}|gh[ps]_[A-Za-z0-9_]{36}|github_pat_[A-Za-z0-9_]{82}|ghu_[A-Za-z0-9_]{36}|ghr_[A-Za-z0-9_]{36}|-----BEGIN.*PRIVATE KEY)' \
-e '(rm\s+-rf\s+/|chmod\s+777|mkfs|fdisk|dd\s+if=|shutdown|reboot|halt|systemctl\s+(stop|disable))' \
-e '(curl\s+.*-X\s*POST|curl\s+.*--data|curl\s+.*-d\s|wget\s+.*\|\s*(ba)?sh|curl.*\|\s*(ba)?sh)' \
-e '(nc\s+-e|ncat|socat.*EXEC)' \
-e '(base64\s+-d\s*\|\s*(ba)?sh|eval\s+\$\(|eval\s+`)' \
"$FILE" || echo "(no blocker matches)"
For curl POST matches: check if the target is localhost:8788/v1/* (Pub API) — those are OK. External POSTs to unknown hosts are blockers.
Warnings (flagged for review) — single combined grep:
cairn.shell: grep -nEi \
-e '(\$\{?[A-Z_]*(TOKEN|SECRET|API_KEY|PASSWORD|CREDENTIAL|AUTH|PRIVATE_KEY)[A-Z_]*\}?|process\.env\.|os\.environ)' \
-e '((>|>>)\s*|tee\s+)(/|\.\./|~|\$HOME)' \
-e '(pip\s+install|npm\s+install|cargo\s+install|apt\s+install|apt-get\s+install)' \
-e '[0-9a-f]{64,}' \
"$FILE" || echo "(no warning matches)"
Also flag:
allowed-tools not scoped (bare Bash, or no restriction)inclusion: always on a non-core skillcurl to external APIs (check if expected and documented in the skill body)Scan the skill body for command references and verify availability:
# Extract command names (handles cairn.shell: prefix and bare commands)
cairn.shell: grep -oE '\b(python3|node|npm|pip|cargo|go|docker|curl|jq|gh|gws|sqlite3|openssl)\b' "$FILE" | sort -u
For each binary found, batch-check availability:
cairn.shell: for cmd in $(grep -oE '\b(python3|node|npm|pip|cargo|go|docker|curl|jq|gh|gws|sqlite3|openssl)\b' "$FILE" | sort -u); do printf '%s: ' "$cmd"; which "$cmd" 2>/dev/null && echo "found" || echo "MISSING"; done
Flag any MISSING dependencies.
Query the source repository for trust signals:
cairn.shell: gh repo view OWNER/REPO --json name,description,stargazerCount,createdAt,pushedAt,isArchived
cairn.shell: gh api repos/OWNER/REPO/contributors --jq '.[0:5] | .[] | .login'
Flag:
pushedAt to today)Space gh calls 2s apart.
Apply the scoring rubric based on scan results:
| Rating | Criteria | |--------|----------| | VERIFIED | Registry source + clean scan + active repo (>50 stars, recent commits, multiple contributors) | | TRUSTED | Known source + clean scan + no warnings | | UNKNOWN | Clean scan but no repo info or unverifiable source | | SUSPICIOUS | Has warnings but no blockers — requires human review | | UNTRUSTED | Has any blocker pattern — DO NOT IMPORT |
Present findings as a structured report:
## Skill Vetting Report
**File:** <path>
**SHA-256:** <hash>
**Lines:** <count>
**Rating:** VERIFIED | TRUSTED | UNKNOWN | SUSPICIOUS | UNTRUSTED
### Frontmatter
- name: <value> [OK | ISSUE: ...]
- description: <value> [OK | MISSING TRIGGER]
- allowed-tools: <value> [OK | WARNING: too broad]
- inclusion: <value> [OK | WARNING: always on untrusted]
- disable-model-invocation: <value> [OK | WARNING: missing for side-effect skill]
### Security Scan — Blockers
- Secrets/tokens: <count> findings
- Destructive commands: <count> findings
- Data exfiltration (curl POST, nc -e, socat): <count> findings
- Encoded payloads / command substitution: <count> findings
### Security Scan — Warnings
- Env var token reads: <count> findings
- External file writes: <count> findings
- Runtime dependency installs: <count> findings
### Dependencies
- <binary>: found | MISSING
### Repository (if checked)
- Stars: <n> | Created: <date> | Last push: <date>
- Contributors: <list>
- Archived: yes/no
### Recommendation
<IMPORT | REVIEW_REQUIRED | REJECT> — <reasoning>
Offer the appropriate next action:
backend/.pub/skills/<name>/SKILL.md?"After import, remind: run /enhance --focus=skills to validate the imported skill.
gh api calls 2s apart to avoid rate limitingdata-ai
Detect agent-cairn PRs that have stalled (no activity >=90 min) and classify the failure mode to route to appropriate recovery agent.
tools
Post-install skill adaptation: read a newly installed SKILL.md, fix environment-specific references (paths, accounts, tool names), assign the skill to relevant agent types, and propose an AGENTS.md update. Triggered automatically after cairn.installSkill completes.
data-ai
Monthly self-improvement brief for Cairn. Queries error_patterns, action_exemplars, experiment_windows, and session_journal to synthesize what Cairn learned, where it failed, and 3 concrete proposals for Avi to approve. Run on the 1st of each month. Keywords: growth brief, monthly review, self-improvement, what did cairn learn, how is cairn doing, monthly report
testing
Decision support with memory-backed context. Retrieves past decisions, journal history, and relevant facts before answering questions that involve a choice or tradeoff. Keywords: should I, which is better, tradeoff, compare, decide, choose, option, alternative, pros and cons, recommend