Metadata-Version: 2.4
Name: ostup-agent-gate
Version: 0.1.0
Summary: Portable, stdlib-only guardrail for autonomous coding agents — safe continuations instead of reckless actions.
Author: GG
License-Expression: MIT
License-File: LICENSE
Keywords: agent,claude,claude-code,guardrail,hooks,safety,secrets
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# 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.md` first** (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)

1. **Copy the `agent-gate/` folder into your repo** so it lives at
   `your-repo/agent-gate/`.
2. **Preview the hooks:**
   ```
   ./agent-gate/agent-gate init
   ```
   This writes a PREVIEW file (`.claude/settings.agent-gate-preview.json`) and
   changes nothing live. To customize the rules, copy the bundled
   `agent-gate.toml` to your repo root and edit it.
3. **It already works before `init`.** Because the tool ships with a bundled
   `agent-gate.toml`, a dropped-in copy gates your repo immediately, even before
   you create a repo-root config. A repo-root `agent-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 commit` runs 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 of
  `agent-gate.toml`.
- For your repo's tests, build, lint, and so on, **wire your own commands** by
  adding `[[adapters]]` entries to `agent-gate.toml` and pointing a proof at them
  in `[verify_recipes]`. Example:
  ```toml
  [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 as `pending 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 a `safe 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
  `--activate` the 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.md` against 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 no `HANDOFF.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; `init` wires 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.
