John SmithandClaude Code a138b13668 feat: agentic-gates — mechanical quality-gate marketplace for Claude Code
Multi-plugin marketplace of forced mechanical gates (the Turnstile): agents
cannot end a turn with mechanically failing code. Verdicts are deterministic
CLI results — never LLM-judged.

- core/gate: stdlib-only dispatcher (Python 3.11+) with SARIF-lite finding
  protocol (content-based fingerprints, line-drift proof), policy loader with
  includes/tiers, tool-chain resolver with fallback order + explicit DEGRADED
  verdicts, verdict cache, ratchet baseline, expiring waivers, guard-the-guard,
  loop-guard, turn ledger, doctor, report
- 14 tool adapters: py_ast, ruff_format/check, secret_scan, node_check, tsc,
  oxlint, biome_*, prettier, ty, pyright, mypy, gitleaks (pure parsers, unit-
  testable without the tools installed)
- packs: gates-essential (engine + all enforcement hooks + commands),
  gates-polyglot/security/strict (declarative content packs, registration-only
  hooks, dependencies on the engine — multi-fire structurally prevented)
- Quality Ladder wiring: L0 PostToolUse (format/syntax/secrets, unchanged-hash
  fast path), L1 PostToolBatch (lint+types), L2 Stop turnstile with loop-guard,
  L3 gate check for CI parity
- 56 tests: unit + golden-stdin hook contracts + packaging invariants +
  registration idempotence; manifest validator; seed fixtures
- Spike results: H4 ratchet PASSED (0 false blocks / 10-10 caught); H2 partial
  falsification recorded (unchanged-hash <15ms unreachable at ~51ms p95 with
  per-edit CPython spawn — escalation path documented)
- Design history: .research/brainstorm_20260926T1835.md (dialectic + tool matrix)

Co-Authored-By: Claude Code <[email protected]>
2026-09-26 19:35:51 -04:00

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 [email protected] --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.

S
Description
No description provided
Readme
109 KiB
Languages
Python 100%