Portable, stdlib-only guardrail for autonomous coding agents — safe continuations instead of reckless actions.
Project description
agent-gate
A portable safety fence for AI coding agents. It blocks the dangerous actions (leaking secrets, deleting things, claiming "done" without proof, publishing or rewriting history) and lets the safe ones through, so the agent keeps working but cannot be reckless.
It is stdlib-only Python (no dependencies, nothing to install) and is meant to drop into any git repository.
- New here? Read
ABOUT.mdfirst (plain language, no commands). - Full design and sources:
docs/DESIGN.md. - The rule catalog:
docs/RULES.md.
Status (v0.1.0): honest about what works today
| Works now (LIVE) | Planned (NOT built yet) |
|---|---|
before-action (classify a command) |
session-start / session-close |
verify (run proofs, built-in secret scan, repo adapters) |
preflight (discover repo state) |
done-check (block unproven "done") |
policy-lint (find rule conflicts) |
init (generate hooks; PREVIEW unless --activate) |
Stop / SessionStart hook enforcement |
subagent open|close (scoped sub-agent leases) |
full adoption-safety sidecars in init |
doctor (handoff-drift check) |
|
hook (block a command when Claude Code calls it) |
|
| 53 automated tests, all passing |
The fence is built and tested. It is not auto-wired into Claude Code until
you run the init step and activate it. Until then, you or the agent run it on
demand. Off by default, on purpose.
Requirements
- Python 3.11 or newer (it uses the stdlib
tomllib, added in 3.11). - Nothing to install. No internet, no third-party libraries.
Drop into any repo (quick start)
- Copy the
agent-gate/folder into your repo so it lives atyour-repo/agent-gate/. - Preview the hooks:
This writes a PREVIEW file (./agent-gate/agent-gate init.claude/settings.agent-gate-preview.json) and changes nothing live. To customize the rules, copy the bundledagent-gate.tomlto your repo root and edit it. - It already works before
init. Because the tool ships with a bundledagent-gate.toml, a dropped-in copy gates your repo immediately, even before you create a repo-root config. A repo-rootagent-gate.toml, when present, always wins over the bundled one.
To actually enforce in Claude Code, activate the hooks (your explicit choice):
./agent-gate/agent-gate init --activate
This writes the live .claude/settings.json. It merges, never duplicates, and
leaves your other settings and hooks intact. Safe to run twice.
Verifying work
verify commitruns the built-in secret scanner (no external script needed). It reads what is staged in git and flags secret patterns, forbidden file globs (for example.env,*.pem,id_rsa), credential extensions, and oversized files. It is configured by the[sensitive]section ofagent-gate.toml.- For your repo's tests, build, lint, and so on, wire your own commands by
adding
[[adapters]]entries toagent-gate.tomland pointing a proof at them in[verify_recipes]. Example:[verify_recipes] tests_pass = { kind = "adapter", adapter = "tests" } [[adapters]] name = "tests" cmd = "pytest -q" kind = "tests" success = "exit0"
Proofs with no automated recipe are reported aspending manual attestation. agent-gate never pretends an unprovable proof is satisfied.
Prove it works (run the tests)
From the repo where this folder lives, with any Python 3.11+ that has pytest:
PYTHONPATH=agent-gate python3 -m pytest agent-gate/tests -q
Expect a row of dots ending in 53 passed. (pytest is the only thing the test
run needs; the tool itself uses no third-party libraries.)
Commands
You normally type ./agent-gate/agent-gate <command>. Add --json to any
command for machine-readable output (useful for other tools and agents).
before-action (LIVE)
- What: sorts a command or file-change into one of four modes (see ABOUT.md).
- Flags:
--command "...",--paths a b c,--intent "free text",--json,--run-id <name>. - Example:
./agent-gate/agent-gate before-action --command "rm -rf build" - Output:
[mode] reason, plus asafe path:line when it is blocked.
verify (LIVE)
- What: establishes the proofs a change needs. Runs the built-in secret scan
and any repo adapters you configured. Lists everything else as
pending manual attestation. - Flags:
--change-type <type>(required),--attest <proof>,--evidence "<what you did>",--run-id <name>,--json. - Example:
./agent-gate/agent-gate verify --change-type commit
done-check (LIVE)
- What: reads a sentence. If it claims completion ("done", "fixed", "passing"), it checks the required proofs are on record for that change-type. No proof, no pass. In-progress wording ("still working on") is not treated as a claim, so it never freezes an honest update.
- Flags:
--claim "..."(required),--change-type <type>,--run-id,--json.
init (LIVE, preview by default)
- What: writes the Claude Code hook settings. By default a PREVIEW file; with
--activatethe live.claude/settings.json. Merges, never duplicates.
subagent open|close (LIVE)
- What: pins a helper sub-agent to a goal, the exact paths it may touch, and forbidden actions, and refuses to let it close without returned evidence.
- Open:
./agent-gate/agent-gate subagent open --goal "refactor X" --allowed-paths src/foo - Close:
./agent-gate/agent-gate subagent close --lease-id <id> --evidence "tests pass"
doctor (LIVE)
- What: checks
HANDOFF.mdagainst reality. v1 compares the "Latest commit" line to recent git history and reports if the handoff is stale. (Reports a finding if your repo has noHANDOFF.md.)
hook <event> (LIVE)
- What: the bridge to Claude Code. Reads the command Claude Code is about to
run (on stdin), classifies it, and blocks it (exit code 2, with a reason) if it
is in the red lane. You do not run this by hand;
initwires it in.
How it connects to Claude Code (hooks)
- Claude Code can run a command at certain moments, called "hooks" (for example, before every Bash command).
- agent-gate provides
agent-gate hook PreToolUse, which inspects the command and returns "block" or "allow." - Turning it on changes how Claude Code behaves in this repo, so it stays off
until you choose to enable it (
init --activate).
Where everything lives
| Thing | Location |
|---|---|
| The rules (editable, plain text) | agent-gate.toml (repo root, or the bundled one) |
| The program | agent-gate/agent_gate/ |
| The launcher | agent-gate/agent-gate |
| The tests | agent-gate/tests/ |
| The design and sources | agent-gate/docs/DESIGN.md |
| Logs and proof records | ~/.agent-gate/ (OUTSIDE the repo, so they can never be committed) |
Limitations (please read)
- Not auto-on until you activate it. Today it guards only when run, or after
you run
init --activate. - Some proofs are manual. agent-gate records and timestamps an attestation, but it cannot physically confirm, for example, that a human looked at a screenshot.
- Detection uses patterns. It can miss a cleverly worded dangerous command, or occasionally over-flag a safe one. It is a strong safety net, not a guarantee. Keep a human in the loop.
- It does not fix code or run your app. It judges actions and proof only.
- The built-in secret scan is regex-based. It is a portable, zero-dependency backstop, not a replacement for a dedicated secret-scanning service.
- It is v0.1. Several designed commands are not built (see the status table).
Origin
agent-gate was hardened in a real safety-critical repository (MAP, a child-safety
location-tracking tool), where a prior agent leaked secrets via git add -A,
silently stopped a background job, and claimed work was "done" without observing
it. Those incidents are the reference implementation behind these rules. The tool
is now generic and carries no project-specific assumptions.
Editing the rules
The rules are in agent-gate.toml, plain text, each with a reason next to it. To
change behavior, edit that file. After editing, run the tests:
PYTHONPATH=agent-gate python3 -m pytest agent-gate/tests -q
You do not need to touch the program code to change the rules.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ostup_agent_gate-0.1.0.tar.gz.
File metadata
- Download URL: ostup_agent_gate-0.1.0.tar.gz
- Upload date:
- Size: 21.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6267037a71df6cd5b272f839796f919f638371ceabadf2bff1083ef4ffeb058b
|
|
| MD5 |
3b660ce2040a8f7619c0c878dcebad2d
|
|
| BLAKE2b-256 |
8772b8bc500419b15ca55deb60ef7203de7d99d8cde405e05d45eae589bda554
|
File details
Details for the file ostup_agent_gate-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ostup_agent_gate-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e0cdf379bd74711f41119c6409764be88176156c5a7c99d51c71865d00cdd1c
|
|
| MD5 |
54778dc010d4d819bf8354fe95c3f355
|
|
| BLAKE2b-256 |
03ef6d319bb86a884d0bf943f7301804f26e372c37cb44a1e300a9e5c131bf43
|