Every stage is reversible and each one is worth doing before the next.
No hooks, nothing installed. From the repo folder:
python3 scgate.py check
python3 scgate.py os
python3 scgate.py scout <project>
python3 scgate.py attest <project>
python3 scgate.py audit <project>
Writes only <project>/.scgate/attestation.json and ~/.claude/scgate/.
Read two audits before going further. Expect the first to be long: that is the
baseline, not a verdict.
bash install.sh
# then in ~/.claude/scgate/policy.json: "mode": "audit"
Every Claude Code session is now gated, but nothing is blocked; every decision
is logged. Work normally. After a few days: scgate.py stats and read the
ledger for what would have been blocked. Tune the catalogue
(allow-attested <project> for each repo you trust) until it would be quiet.
"mode": "enforce". Unknown packages ask with the registry facts attached;
hallucinated names are denied; attested versions are pinned.
python3 ~/.claude/scgate/scgate.py shim install --rc # any agent, any terminal
python3 ~/.claude/scgate/scgate.py proxy --port=8791 # catalogue-only registry
python3 ~/.claude/scgate/scgate.py lockdown # pip.conf / uv.toml / .npmrc -> proxy
python3 ~/.claude/scgate/scgate.py anchor # copy the line off-machine
On a server: Stage 0 only, with audit --installed=<the app's python> and
os. Do not run lockdown on a server until the proxy is in place. If the
app ships as a container, the image is what runs: after any upgrade, rebuild
it and env-audit a python inside it.
scout → prepare (fills a scratch env with the current pins) → plan
(dry run) → apply (snapshot, install) → run the project's own tests →
change the pins → rebuild → attest + audit → commit .scgate/.
Never change a pin before the tests have run on the new version.
Commit .scgate/ and .claude/settings.json (or install the plugin) so
everyone who clones the repo gets the same gate and the same approvals. Add
examples/ci/scgate-audit.yml so a CVE published overnight fails the next
build.