v0.3.0 — pre-install gate
The pre-install gate: vet an untrusted skill / MCP server / plugin from a URL before it
touches your machine. Every prior mode assumed you already trusted the code enough to check it
out. The gate inverts that and scans agent code, from a URL, before install. No new checks; the
library is unchanged at 332. JSON is still the default for a local scan, so the skill and the
pre-commit/Action paths are unaffected.
Added
scan.py --url <url|owner/repo>. Fetches an untrusted target into an isolated temp dir
(never~/.claude, never the cwd), classifies it (skill / plugin / MCP / agent-config / app),
scans it, and prints a go/no-go verdict. The target is never executed — static read only.
--refpins a branch/tag; the verdict names the exact commit SHA vetted.- Hardened fetch. The repo is written by someone trying to attack the scanner, so the clone
uses a git protocol allowlist (https/git only — noext::command-exec, nofile://local
read), an isolated HOME with system/global git config off, no submodule recursion, no
clone-time template hooks, a wall-clock timeout, and a post-clone size ceiling. Temp clones are
always cleaned up (Windows read-only git objects included). --format gate. A three-level verdict — DO NOT INSTALL (a critical/high that fires at
install/load time), REVIEW FIRST (real findings, none that fire on load), LOOKS CLEAN
(within the mode's reach) — with install-time risks surfaced above ordinary app-sec findings,
and a footer naming what was checked and that the code was not run. The default format for
--url. The blocking surface is data-driven: aninstall_time_categoriesset in
patterns.json(claude-ext,mcp,ai-config-trust,supply-chain), and every finding now
carries aninstall_timeflag in JSON.--keep. With--url, leaves the hardened checkout in place and prints its path so the
skill'sfull/ultratiers can read it under the hostile-repo posture instead of re-cloning
unsafely.- Skill gate flow. SKILL.md routes a URL + install intent ("is this skill safe to install?",
"git gud gate<url>") to the gate, leads with the verdict, and writesINSTALL_GATE.md.
Tests
- Gate oracle in
run_tests.py: URL resolution + protocol refusal (ext/file/ssh/scp/bare-path),
artifact classification, the hardened clone (pinned SHA, size cap, no stranded temp dir, ext::
refused by the clone itself), the three verdict thresholds, and--format gateend to end
against a malicious-skill and a clean-skill fixture.