跳到主要内容

skill-integrity

❖ Communityv0.2.0

Rug-pull detection for installed agent skills — fingerprints every file in every skill directory (SHA-256), keeps a profile-local snapshot, and reports exactly which skill files changed, appeared, or vanished since; a skill that mutates after install without the user touching it is the rug-pull signal. A skill directory made unreadable is reported as a finding, never treated as clean. Read-only observer, stdlib-only, zero network calls; blind spots (oversize files, symlinks, permission-denied) are counted and printed, never silent. The wrapper registers an hourly pre_llm_call hook that injects findings into the agent context, plus a /skill-integrity slash command (snapshot | check | show) that creates the baseline snapshot and shows the file-level diff. The CLI supports --state-dir to target the plugin's manifest directly. Skill dirs and state derive from get_hermes_home(), covering non-default profiles.

Open in Hermes Desktop
hermes plugins install skill-integrity

What it adds

Hooks 1

pre_llm_call

README

From the reviewed commit d812186 ↗; it updates when the author re-pins.

skill-integrity

Your agent skills were install-once. They don't stay that way.

Agent skills (Claude Code .claude/skills/, Hermes ~/.hermes/skills/, any folder of SKILL.md + scripts) are plain text on disk. The marketplace audits happen at publish time — but the files live in your machine and anyone (or any process, or the upstream repo) can rewrite them afterwards. In 2026 the ClawHavoc campaign published hundreds of malicious skills to a major skill registry, and rug-pull updates were documented as a real attack class.

skill-integrity fingerprints every file in every installed skill, keeps a local snapshot, and tells you exactly what changed since.

$ skill-integrity check

skills scanned: 23  (snapshot taken 2026-10-10T21:44:32+0800)

[~] pdf-extractor — MODIFIED
    changed: SKILL.md
    added:   fetch_helper.sh

1 skill(s) changed since snapshot. Review diffs before trusting them.

Install

Zero dependencies. Python 3.8+. One file.

git clone https://github.com/ZidoCode/skill-integrity
python3 skill-integrity/skill_integrity.py snapshot   # baseline

As a Hermes plugin

Drop it in your plugins directory and the agent itself gets told when a skill changes under it: the plugin's pre_llm_call hook injects the findings into the agent's context (hourly cadence, findings only — a clean check injects nothing):

git clone https://github.com/ZidoCode/skill-integrity ~/.hermes/plugins/skill-integrity
hermes plugins enable skill-integrity

The plugin also registers a /skill-integrity slash command in the chat:

/skill-integrity snapshot   # record the baseline the hourly hook reads
/skill-integrity check      # file-level diff vs the snapshot
/skill-integrity show       # snapshot summary

Run /skill-integrity snapshot once after installing your skills — without a baseline the hook has nothing to compare against and stays silent.

Snapshot location follows the active Hermes profile (~/.hermes/plugin-data/skill-integrity/manifest.json) — the CLI defaults to ~/.skill-integrity/manifest.json when run standalone; both are mode-0600, local-only, no network. In the plugin, both the snapshot dir and the scanned skill dirs derive from get_hermes_home(), so non-default profiles are covered.

The standalone CLI can point at the plugin's manifest with --state-dir:

python3 skill_integrity.py --state-dir ~/.hermes/plugin-data/skill-integrity snapshot
python3 skill_integrity.py --state-dir ~/.hermes/plugin-data/skill-integrity check --json

Usage

# 1. Record the current state of your skills (do this right after install)
python3 skill_integrity.py snapshot

# 2. Any time later — cron, before a big agent run, after pulling updates
python3 skill_integrity.py check

# 3. Machine-readable (for CI or your agent to consume)
python3 skill_integrity.py check --json

Exit codes

Code Meaning
0 clean (no findings)
1 findings exist (default) — pass --no-fail-on-change to get 0 instead
2 no snapshot exists yet / usage error

Scoped directories

By default it scans ~/.hermes/skills and ~/.claude/skills. The snapshot records which dirs it covers; check reuses those dirs (no mass false positives from a dirs mismatch). Override explicitly when needed:

python3 skill_integrity.py snapshot --dirs ~/work/skills   # record custom dirs
python3 skill_integrity.py check                            # uses recorded dirs
python3 skill_integrity.py check --dirs ~/other/skills      # explicit override;
                                                            # skills outside the
                                                            # scanned dirs are out
                                                            # of scope, not "removed"

Suggested cron

# check skills twice a day, alert if anything moved
0 */12 * * * python3 ~/skill-integrity/skill_integrity.py check --json >> ~/.skill-integrity/checks.log

Honest coverage — read this

Hash comparison catches any byte change to any tracked file. It cannot judge intent — a legitimate upstream update and a malicious rewrite look identical to a hash. What this tool gives you is the trigger and the file list; reading the actual diff before trusting the skill is your half of the contract. It tracks files up to 512KB and skips caches (__pycache__, node_modules, .git) — it is an inventory-integrity tool, not an antivirus. Blind spots are counted, never silent: every check/snapshot prints how many files were skipped as oversize (>512KB) or symlinks, and per skill which ones. A skill directory that cannot be entered (permissions) is reported as unreadable — it is never treated as a clean empty scan, because an unreadable skill is exactly where a modification can hide.

Threat model

Scenario Caught?
Skill script rewritten after install ✅
New file quietly added to a skill ✅
Skill deleted (or quarantined) ✅
Brand-new skill appears ✅
Skill directory made unreadable (perm change to hide changes) ✅ (reported as unreadable, never "clean")
Legitimate intentional update ✅ (flagged — you re-snapshot after reviewing)
Malicious content inside an unchanged file ❌ (out of scope — see mcp-scan & friends)
File contents judged for intent ❌ (hashes don't read minds)
Attacker with write access re-snapshots over their tracks ❌ (the snapshot is agent-writable by design — see above)

State

Snapshot lives at ~/.skill-integrity/manifest.json (0600). Delete it and take a fresh one any time — nothing else is stored, nothing leaves your machine. No telemetry, no network calls.

Free forever (MIT). If it saves you from a bad update, star the repo — or check out agent-ledger and agent-janitor from the same suite.

License

MIT

agent-janitor❖ Community★ 0

Process hygiene for agent machines — finds the background processes your agent left behind (dev servers, tunnels, watchers, nohup jobs) using evidence signals (ppid=1 reparent, port listener via /proc/net/tcp{,6}, dev-server traits, TTL exceeded) and attributes them to the originating tool call via agent-ledger's ledger when present. Dry-run by default: nothing is killed until you write policy_mode=enforce; system daemons and host/VM management agents are exempt by name, a user-editable whitelist covers your real infrastructure, and each kill re-reads the cmdline first (SIGTERM, 2s, SIGKILL with PID-reuse check). stdlib-only, fails open. Disclosure — inside Hermes it only appends terminal commands that look like they start background work (first 300 characters, which can include inline secrets) to plugin-data/agent-janitor/spawns.jsonl, and reads agent-ledger's ledger.db read-only when present. Killing is a separate CLI you run yourself (janitor_cli.py sweep): after you write "enforce" to plugin-data/agent-janitor/policy_mode it sends SIGTERM then SIGKILL to every process re-parented to PID 1 for over a minute that is not on its built-in exempt list or your whitelist, whoever started it (for example a tmux server or a nohup'd hermes gateway), including other users' processes when run as root. Dry-run first; the dry-run list is the kill list.

Tools
agent-ledger❖ Community★ 0

Write-ahead ledger for agent side effects, with an OWASP Agentic Top 10 posture scorer. Disclosure — records the arguments (up to 4000 chars: terminal commands, file contents, MCP args) and a 300-char result digest of every state-changing tool call in a local plaintext SQLite ledger under HERMES_HOME/plugin-data/agent-ledger/ that is never pruned; injects a warning listing this session's unconfirmed calls into the next turn's context; an optional policy engine (off by default; you add policy.json and set policy_mode) can refuse matching tool calls before they run; the optional posture_daily.py script, run from your own cron, sends a score summary to Telegram with the bot token you give it.

Tools
context-audit❖ Community★ 0

Context-window forensics: per-turn input/output token estimates, the single largest tool output of each turn, oversized tool calls (args over 50 KB), and compaction events, recorded as metadata only (tool name, byte length, ids, timestamps — never args or results) in a local SQLite DB under HERMES_HOME/plugin-data/context-audit/. Adds a /context-audit slash command that prints the top 5 context eaters over a window with one mitigation per entry.

Tools

← Back to the catalog · catalog built Oct 16, 2026