Skill Library Sanitization
Use this when preparing, importing, updating, or publishing a skill library, agent kit, prompt/tool bundle, or exported knowledge base. The goal is to preserve reusable workflows while stripping secrets, private identity, client data, infrastructure details, copyrighted/raw paid material, NSFW material, local-machine assumptions, and stale duplicates.
Core rule
Never import external skills directly into the live skill library. Pull into a staging area, scan, sanitize, curate, validate, then promote.
Standard directory model
Use explicit zones:
- Sources: external repos, marketplace exports, local Hermes/OpenClaw/Claude skills, appie-brain skills.
- Intake staging:
~/.hermes/skill-intake/<source>/<timestamp>/ for raw pulled material.
- Quarantine:
~/.hermes/skill-quarantine/<timestamp>/ for private, unsafe, duplicate, or unlicensed material.
- Clean database: a user-approved repo or folder such as
<CLEAN_SKILLS_REPO>/skills/.
- Install target:
~/.hermes/skills/ only after clean database validation passes.
Do not leave quarantine inside a public repo, even when .gitignore hides it.
Workflow
1. Intake, never direct install
For a Git source:
mkdir -p ~/.hermes/skill-intake
cd ~/.hermes/skill-intake
git clone --depth 1 <REPO_URL> <source>-$(date -u +%Y%m%dT%H%M%SZ)
For local sources, copy into staging instead of editing originals:
rsync -a --exclude '.git' <SOURCE_SKILLS_DIR>/ ~/.hermes/skill-intake/<source>-$(date -u +%Y%m%dT%H%M%SZ)/
Record source URL/path, commit SHA if available, timestamp, and license before touching content.
2. Inventory and normalize
Count skills by SKILL.md, not just folders. Extract:
- skill name and description
- source path and source license
- linked resources under
references/, scripts/, templates/, assets/
- duplicate names
- missing or malformed frontmatter
- support files outside allowed directories
- absolute paths, network calls, credential references, destructive commands
Use scripts/scan_skill_library.py from this skill for a masked inventory and leak scan.
3. Classify before editing
Classify every skill:
- Keep: generic, useful, low-risk, portable.
- Sanitize: useful workflow but contains private IDs, local paths, credentials, client references, internal hosts, or account names.
- Merge: narrow one-off that belongs in an umbrella skill.
- Quarantine: private/session-specific, NSFW/client-sensitive, raw paid-course/transcript material, unsafe automation, unclear license, or private memory.
- Retire: stale, broken, duplicate with no unique content.
Do not delete useful workflows just because they contain private IDs. Replace identifiers with placeholders and document required env vars.
4. Sanitize into portable placeholders
Replace concrete values with placeholders while keeping the procedure intact:
- API keys/tokens/cookies/auth headers ->
<API_KEY>, <TOKEN>, env-var references, or .env.example keys.
- Notion database/data-source/page IDs ->
<NOTION_DATABASE_ID>.
- Webflow site/collection IDs ->
<WEBFLOW_SITE_ID>, <WEBFLOW_COLLECTION_ID>.
- Google Drive/docs/sheets IDs ->
<GOOGLE_FILE_ID> / <SPREADSHEET_ID>.
- Tailscale/private IPs/internal domains ->
<PRIVATE_HOST> / <INTERNAL_DOMAIN>.
- SSH hosts/key paths/usernames ->
<SSH_HOST>, <SSH_KEY_PATH>, <REMOTE_USER>.
- Local absolute paths ->
$HOME/... or <PROJECT_PATH>.
- Client/person/bot handles ->
<CLIENT_NAME>, <ACCOUNT_HANDLE>, <BOT_NAME>.
- Signed URLs/query tokens -> strip query string or replace with
<SIGNED_URL>.
5. Quarantine safely
Move unsafe files outside the clean database and keep a private manifest:
mkdir -p ~/.hermes/skill-quarantine/<timestamp>
mv <unsafe-path> ~/.hermes/skill-quarantine/<timestamp>/
The public report should say counts and categories only. Do not paste raw private snippets into chat or public reports.
6. Curate the clean database
For promoted skills:
- Keep one canonical skill per workflow, with umbrella skills preferred over narrow one-offs.
- Use lowercase hyphenated names and ensure global uniqueness.
- Keep
SKILL.md concise; move long examples to references/.
- Keep support files only under
references/, scripts/, templates/, or assets/.
- Replace environment-specific commands with variables and setup notes.
- Prefer deterministic scripts for repeatable scanning/conversion.
- Preserve attribution/license metadata in a private or public manifest when allowed.
7. Layered verification before promote/install
Run all gates before copying into the clean database or install target:
python3 <THIS_SKILL_DIR>/scripts/scan_skill_library.py <STAGED_OR_CLEAN_DIR> --json-out /tmp/skill-scan.json
# If available:
gitleaks detect --source <STAGED_OR_CLEAN_DIR> --no-git --redact
Also verify:
- Unique skill names equal total public skills.
- Missing frontmatter/description: 0.
- Duplicate names: 0.
- Broken links/support-file paths: 0.
- Secret/private-pattern findings: 0, except explicitly accepted false positives.
- Touched scripts pass syntax checks.
- Git diff contains no private report content.
8. Promote atomically
Promote only validated skills:
rsync -a --delete <CLEAN_CANDIDATE_DIR>/ <CLEAN_SKILLS_REPO>/skills/
Then install or sync from the clean database into ~/.hermes/skills/ if desired. Avoid editing installed skills directly when a clean source-of-truth repo exists.
9. Ongoing update loop
For updates:
- Pull new upstream material into a fresh staging folder.
- Compare against current clean database.
- Re-run scan and classification.
- Apply sanitization/merge decisions in staging.
- Validate.
- Promote with a reviewed diff.
- Update indexes/manifests and this skill if the workflow changed.
Reporting
Final reports should be terse and actionable:
- Source(s) inspected.
- Public/clean skill count.
- Kept, sanitized, merged, quarantined, retired counts.
- Duplicate skill count.
- Frontmatter/description validation result.
- Secret/private-pattern scan result.
- Generic scanner result.
- Syntax/index validation result.
- Quarantine path and file count.
- Clean database path and report paths.
- Reminder that intentional deletions need review before commit/push.
Never paste raw secrets or full private findings into chat. Mask them or reference the private quarantine path.
Pitfalls
- Do not treat
gitleaks alone as sufficient. It misses private identities, internal domains, client names, local paths, signed URLs, and operational details.
- Do not trust marketplace/community skills until read and scanned. Skills can contain destructive shell commands, exfiltration URLs, or hidden credential assumptions.
- Do not promote raw session transcripts, paid course transcripts, private memory, NSFW client-bot material, or client-specific docs into a shared kit.
- Do not rely on directory names for uniqueness. Read
name: frontmatter.
- Do not create one skill per cleanup session. Fold recurring lessons into this skill and put run-specific patterns in
references/.
Support files
scripts/scan_skill_library.py: masked inventory and leak scanner for skill trees.
references/curated-skill-database-workflow.md: detailed intake, sanitize, curate, promote workflow.
references/appie-kit-cleanup-2026-06-14.md: compact example of a completed public skill-kit cleanup, including validation checklist and reporting shape.
1---2name: skill-library-sanitization3description: Audit, sanitize, curate, and maintain AI agent skill libraries. Use when pulling external/community skills, updating installed skills, removing secrets/private info, quarantining unsafe material, deduplicating skills, or building a clean curated skill database for public or shared use.4---56# Skill Library Sanitization78Use this when preparing, importing, updating, or publishing a skill library, agent kit, prompt/tool bundle, or exported knowledge base. The goal is to preserve reusable workflows while stripping secrets, private identity, client data, infrastructure details, copyrighted/raw paid material, NSFW material, local-machine assumptions, and stale duplicates.910## Core rule1112Never import external skills directly into the live skill library. Pull into a staging area, scan, sanitize, curate, validate, then promote.1314## Standard directory model1516Use explicit zones:1718- **Sources**: external repos, marketplace exports, local Hermes/OpenClaw/Claude skills, appie-brain skills.19- **Intake staging**: `~/.hermes/skill-intake/<source>/<timestamp>/` for raw pulled material.20- **Quarantine**: `~/.hermes/skill-quarantine/<timestamp>/` for private, unsafe, duplicate, or unlicensed material.21- **Clean database**: a user-approved repo or folder such as `<CLEAN_SKILLS_REPO>/skills/`.22- **Install target**: `~/.hermes/skills/` only after clean database validation passes.2324Do not leave quarantine inside a public repo, even when `.gitignore` hides it.2526## Workflow2728### 1. Intake, never direct install2930For a Git source:3132```bash33mkdir -p ~/.hermes/skill-intake34cd ~/.hermes/skill-intake35git clone --depth 1 <REPO_URL> <source>-$(date -u +%Y%m%dT%H%M%SZ)36```3738For local sources, copy into staging instead of editing originals:3940```bash41rsync -a --exclude '.git' <SOURCE_SKILLS_DIR>/ ~/.hermes/skill-intake/<source>-$(date -u +%Y%m%dT%H%M%SZ)/42```4344Record source URL/path, commit SHA if available, timestamp, and license before touching content.4546### 2. Inventory and normalize4748Count skills by `SKILL.md`, not just folders. Extract:4950- skill name and description51- source path and source license52- linked resources under `references/`, `scripts/`, `templates/`, `assets/`53- duplicate names54- missing or malformed frontmatter55- support files outside allowed directories56- absolute paths, network calls, credential references, destructive commands5758Use `scripts/scan_skill_library.py` from this skill for a masked inventory and leak scan.5960### 3. Classify before editing6162Classify every skill:6364- **Keep**: generic, useful, low-risk, portable.65- **Sanitize**: useful workflow but contains private IDs, local paths, credentials, client references, internal hosts, or account names.66- **Merge**: narrow one-off that belongs in an umbrella skill.67- **Quarantine**: private/session-specific, NSFW/client-sensitive, raw paid-course/transcript material, unsafe automation, unclear license, or private memory.68- **Retire**: stale, broken, duplicate with no unique content.6970Do not delete useful workflows just because they contain private IDs. Replace identifiers with placeholders and document required env vars.7172### 4. Sanitize into portable placeholders7374Replace concrete values with placeholders while keeping the procedure intact:7576- API keys/tokens/cookies/auth headers -> `<API_KEY>`, `<TOKEN>`, env-var references, or `.env.example` keys.77- Notion database/data-source/page IDs -> `<NOTION_DATABASE_ID>`.78- Webflow site/collection IDs -> `<WEBFLOW_SITE_ID>`, `<WEBFLOW_COLLECTION_ID>`.79- Google Drive/docs/sheets IDs -> `<GOOGLE_FILE_ID>` / `<SPREADSHEET_ID>`.80- Tailscale/private IPs/internal domains -> `<PRIVATE_HOST>` / `<INTERNAL_DOMAIN>`.81- SSH hosts/key paths/usernames -> `<SSH_HOST>`, `<SSH_KEY_PATH>`, `<REMOTE_USER>`.82- Local absolute paths -> `$HOME/...` or `<PROJECT_PATH>`.83- Client/person/bot handles -> `<CLIENT_NAME>`, `<ACCOUNT_HANDLE>`, `<BOT_NAME>`.84- Signed URLs/query tokens -> strip query string or replace with `<SIGNED_URL>`.8586### 5. Quarantine safely8788Move unsafe files outside the clean database and keep a private manifest:8990```bash91mkdir -p ~/.hermes/skill-quarantine/<timestamp>92mv <unsafe-path> ~/.hermes/skill-quarantine/<timestamp>/93```9495The public report should say counts and categories only. Do not paste raw private snippets into chat or public reports.9697### 6. Curate the clean database9899For promoted skills:100101- Keep one canonical skill per workflow, with umbrella skills preferred over narrow one-offs.102- Use lowercase hyphenated names and ensure global uniqueness.103- Keep `SKILL.md` concise; move long examples to `references/`.104- Keep support files only under `references/`, `scripts/`, `templates/`, or `assets/`.105- Replace environment-specific commands with variables and setup notes.106- Prefer deterministic scripts for repeatable scanning/conversion.107- Preserve attribution/license metadata in a private or public manifest when allowed.108109### 7. Layered verification before promote/install110111Run all gates before copying into the clean database or install target:112113```bash114python3 <THIS_SKILL_DIR>/scripts/scan_skill_library.py <STAGED_OR_CLEAN_DIR> --json-out /tmp/skill-scan.json115# If available:116gitleaks detect --source <STAGED_OR_CLEAN_DIR> --no-git --redact117```118119Also verify:120121- Unique skill names equal total public skills.122- Missing frontmatter/description: 0.123- Duplicate names: 0.124- Broken links/support-file paths: 0.125- Secret/private-pattern findings: 0, except explicitly accepted false positives.126- Touched scripts pass syntax checks.127- Git diff contains no private report content.128129### 8. Promote atomically130131Promote only validated skills:132133```bash134rsync -a --delete <CLEAN_CANDIDATE_DIR>/ <CLEAN_SKILLS_REPO>/skills/135```136137Then install or sync from the clean database into `~/.hermes/skills/` if desired. Avoid editing installed skills directly when a clean source-of-truth repo exists.138139### 9. Ongoing update loop140141For updates:1421431. Pull new upstream material into a fresh staging folder.1442. Compare against current clean database.1453. Re-run scan and classification.1464. Apply sanitization/merge decisions in staging.1475. Validate.1486. Promote with a reviewed diff.1497. Update indexes/manifests and this skill if the workflow changed.150151## Reporting152153Final reports should be terse and actionable:154155- Source(s) inspected.156- Public/clean skill count.157- Kept, sanitized, merged, quarantined, retired counts.158- Duplicate skill count.159- Frontmatter/description validation result.160- Secret/private-pattern scan result.161- Generic scanner result.162- Syntax/index validation result.163- Quarantine path and file count.164- Clean database path and report paths.165- Reminder that intentional deletions need review before commit/push.166167Never paste raw secrets or full private findings into chat. Mask them or reference the private quarantine path.168169## Pitfalls170171- Do not treat `gitleaks` alone as sufficient. It misses private identities, internal domains, client names, local paths, signed URLs, and operational details.172- Do not trust marketplace/community skills until read and scanned. Skills can contain destructive shell commands, exfiltration URLs, or hidden credential assumptions.173- Do not promote raw session transcripts, paid course transcripts, private memory, NSFW client-bot material, or client-specific docs into a shared kit.174- Do not rely on directory names for uniqueness. Read `name:` frontmatter.175- Do not create one skill per cleanup session. Fold recurring lessons into this skill and put run-specific patterns in `references/`.176177## Support files178179- `scripts/scan_skill_library.py`: masked inventory and leak scanner for skill trees.180- `references/curated-skill-database-workflow.md`: detailed intake, sanitize, curate, promote workflow.181- `references/appie-kit-cleanup-2026-06-14.md`: compact example of a completed public skill-kit cleanup, including validation checklist and reporting shape.