Skip to content

Repository files navigation

agentic-gates

Forced mechanical quality gates for Claude Code agents — the Turnstile.

Agents do not end a turn with mechanically failing code. Every verdict is a deterministic CLI result (exit codes + JSON), never an LLM judgment.

L0  PostToolUse      ≤150ms   format-in-place · syntax floor · secret scan   → auto-fix / feedback
L1  PostToolBatch    ≤2s      lint · typecheck · cycles on the batch         → block error-severity
L2  Stop             ≤30s     scoped tests · dep audit · diff security       → decision:"block" (TURNSTILE)
L3  /gate · CI       minutes  full suite · SBOM/license                      → same policy as CI

Install

claude plugin marketplace add davila7/agentic-hooks   # or your fork's path/URL
claude plugin install gates-essential@agentic-gates
# optional content packs (declarative tool-chain profiles):
claude plugin install gates-polyglot@agentic-gates
claude plugin install gates-security@agentic-gates
claude plugin install gates-strict@agentic-gates

Then in each project: /gate-init (creates .gate/ policy), /gate-doctor (checks tool availability).

Packs

Pack Role Enforcement hooks
gates-essential Engine: dispatcher + all hooks + guard + ratchet + commands yes (only here)
gates-polyglot Python + TS/JS tool chains (ruff, ty, biome, oxlint, tsc) registration only
gates-security secrets, gitleaks, osv-scanner, semgrep/ast-grep profiles registration only
gates-strict scoped tests, dep audits, cycles, expired-waiver enforcement registration only

Enforcement hooks live in the engine pack alone — plugin hooks run in parallel across packs, so two packs carrying a Stop handler would double-fire the turnstile.

Design laws

  1. Mechanical only. Deterministic tool exit codes. LLM-as-judge is banned as a verdict.
  2. Missing tool ≠ pass. A tool that is not installed produces an explicit DEGRADED verdict.
  3. Guard-the-guard. The agent cannot edit policy, waivers, baseline, hooks or settings — PreToolUse denies it, ConfigChange blocks it, and CI re-checks it.
  4. Ratchet. .gate/baseline.json registers existing debt once; only NEW findings block. Fingerprints are content-based, so line drift never looks like new debt.
  5. Waivers expire. Every suppression has an owner and an expiry date; expired waivers re-open their findings.
  6. Style is silent, semantics are strict. Formatting is auto-fixed with zero feedback; only error-severity semantic findings block.
  7. Feedback is compact. Findings are capped (~20 / 8k chars) — the platform's 10k additionalContext cap spills to a file with only a 2k preview.
  8. The loop guard releases. After loopguard.max_blocks identical blocks the turn is released with a systemMessage to the human — never wedged against the platform's 8-continuation cap.

Tool chains (v1: depth-first Python + TS/JS)

Concern Python TS/JS
format ruff format biome format → prettier
syntax in-process ast.parse node --check (JS)
lint ruff check oxlint → biome
types ty → pyright → mypy tsc --noEmit
secrets in-process pattern scan → gitleaks same

Chains are declared in .gate/policy.toml with explicit fallback order and budgets.

CLI

python3 core/gate.py init       # .gate/ skeleton
python3 core/gate.py doctor     # tool availability / degraded chains / lock skew
python3 core/gate.py check      # CI parity — exit 2 on blocking findings
python3 core/gate.py baseline   # register current debt (ratchet)
python3 core/gate.py waive --rule ruff/E501 --path 'legacy/**' --owner you@example.com --expires 2026-12-31
python3 core/gate.py report     # SARIF-lite dump

Repo layout

core/gate/            dispatcher source of truth (stdlib-only, Python 3.11+)
packs/essential/      engine pack (vendored core/ + hooks + commands)
packs/{polyglot,security,strict}/   declarative content packs
templates/            CI / pre-commit / gitignore parity templates
tools/                vendor_core, validate_manifests, build_packs
tests/                unit + hook-contract integration + fixtures + spikes

Development

PYTHONPATH=core python3 -m pytest tests/ -q
python3 tools/validate_manifests.py
python3 tools/vendor_core.py          # before release
python3 tests/spikes/h2_latency/bench_l0.py
python3 tests/spikes/h4_ratchet/run.py

Spike results live in tests/spikes/*/RESULTS.md (honest verdicts, including partial falsifications — see H2's unchanged-hash budget).

Status

v0.1.0 — engine, packs, guard, ratchet, turnstile, contracts all under test. H1/H3 spike runs (live agent sessions) are packaged as taskpacks ready to execute.

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages