# gate
A pre-push quality gate, packaged as a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) skill.
`gate` runs a fan-out of parallel review agents over a changeset before you push it, then triages and fixes what they find. It is the review pass you would run by hand if you had the time and never got tired: nine distinct lenses, each with its own checklist and worked examples, plus a deterministic mechanical floor that runs first so no file is silently skipped, and a bounded fix-and-re-review loop that makes the run terminate instead of rewriting your code forever.
It is language-aware for Go, TypeScript/JavaScript/Svelte, and Rust, and degrades gracefully on anything else.
## Why it exists
Ordinary review, human or automated, is a single pass with a single attention budget. It reads a diff top to bottom and flags what jumps out. That misses whole classes of defect: the bug that only exists across two files, the fix applied at one call site but not its three siblings, the test that passes without exercising the thing it names, the panic that never fires until production. `gate` splits the review into independent lenses that each go looking for one family of hazard, so the correctness pass is not distracted by style and the reuse pass is not glossing over a race. Every lens reports a per-file coverage table, so a file that got skipped shows up as a gap instead of vanishing. And every defect it once missed is recorded as a durable check, so the gate gets harder to fool over time.
## What it checks for
Each lens is one review agent with its own checklist. The categories below are representative, not exhaustive.
### Reuse and efficiency
Redundant work the codebase already does better.
- Reimplementing an existing utility or helper; duplicated functionality across files
- Inline logic that belongs in (and duplicates) a shared function
- Unnecessary work, recurring no-op updates, overly broad operations
- Missed concurrency and parallelism; abstraction dispatch in tight loops; hot-path bloat
- Redundant install of an already-declared dependency in a build or CI step
### Correctness and safety
The bugs that crash, corrupt, or leak.
- Potential panics; missing nil guards on stored function fields; constructor input validation
- Race conditions, resource leaks, shutdown races, missing context propagation
- Data corruption, including non-atomic file writes and shallow copies of reference types shared across goroutines
- Security: sensitive data in telemetry, secrets written to a subprocess without required framing, a reject path that echoes its own sensitive input, a remote-supplied value choosing a request destination with only its scheme validated
- A remote integer scaled into a duration, size, or index with no bound; output accumulated from untrusted input in an unbounded loop
- Calendar-time and day-boundary correctness; non-deterministic ordering with no tiebreaker
- Destructive bulk operation guarded by a presence check that a detached or empty resource satisfies
- Lexical path validation trusted as containment while the real operation follows symlinks (TOCTOU)
- A guard added at one call site while its siblings consuming the same source stay open
- Portability traps: OS-specific error-string matching, a path matched against a separator-specific matcher on Windows
- Critical TODOs; an exported doc comment stating a guarantee no line enforces
### Quality and patterns
Code that works but will rot.
- Redundant state, parameter sprawl, copy-paste with slight variation, leaky abstractions, stringly-typed code, deeply nested conditionals
- Swallowed errors, dead code, magic numbers, commented-out code, low-value comments and logging
- Test-passing hacks; sentinel cache entries treated as valid; stale cache files; incomplete multi-site fixes; inconsistent guard patterns
- Prose (comments, docs) making a claim the code does not support; stub or placeholder return values that report a misleading status
- Go API design smells; Svelte 5 reactivity bugs (binding to read-only `$derived`, invalid reactivity), malformed Tailwind classes, a component-library class with no component library
- Hardcoded user-facing strings; un-localized number, date, or unit values sitting beside localized text; missing `type="button"` inside a form
### i18n translation integrity
- Missing keys (gaps) and orphaned keys across locales
- Source-language placeholders left in translated files
- Structural mismatches between locale files
- Stale fallback text left behind after a source value changed
### Integration and wiring (cross-file)
The defects that live between files, never in one.
- End-to-end data flow: a frontend that gates on a field the API never serializes
- Validation and guard completeness across a pipeline's stages; sibling-function and constructor-factory consistency
- Event-schema consistency across every emission site; recursive-type handling in serialization
- Read-time filter versus write-time invariant conflicts; stale configuration captured at construction
- Routing parity for a new route or subpage; grid/flex placement contract for a new page or layout component
- Generated-artifact cross-job dependencies (a CI step that consumes an artifact an earlier job never built)
### Regression and backward compatibility
What this change breaks for existing users and data.
- Config and settings schema changes; HTTP/RPC response-contract changes; DB schema and migrations
- CLI flag and UX changes; a renamed name in a stable contract; a changed default or type
- Primitive or engine swaps checked for refactor-equivalence
- Whether a change is additive and safe, or silently requires existing data to migrate
### Test quality
Tests that are green for the wrong reasons.
- Trivially passing assertions; tests that never exercise the path they name
- Flaky or non-deterministic tests; wall-clock and day-boundary flakiness; absolute duration upper-bound assertions
- Cross-platform test assumptions that pass on Linux CI and fail on macOS or Windows
- Cancellation/timeout tests that never assert the cancellation was observed
- Discarded or absent teardown in a `defer`/`t.Cleanup`; a discarded error inside a measurement closure
- A test that re-implements the branch it is testing, or asserts via `grep` on the source
- Missing differential or property test for a parser, encoder, or format change; a fuzz target whose only invariant is survival
### UX/UI and accessibility (report-only)
- Project doctrine violations; ambiguity and comprehension problems; missing system-status and empty states
- Destructive and risky actions without confirmation; accessibility gaps; consistency and look-and-feel drift
- Form and input clarity; layout robustness under overflow and translation; microcopy, notifications, and motion
### Performance
Hot-path cost, measured rather than guessed.
- Hot-path dispatch overhead; heap allocations in hot paths; escape analysis
- Bounds-check elimination; goroutine and channel overhead; string and slice allocation patterns
- `sync.Pool` usage; GC pressure and object layout; memory layout and cache efficiency
- Compiler hints, assembly patterns, and SIMD kernel tails
- Every finding is labelled mechanical-fix or report-only and carries a verification command; nothing is flagged without establishing the hot path first
## How it runs
1. **Phase 0, mechanical floor (deterministic).** Discovers the repo's shape (frontend roots, translation locations, CSS framework, generated-artifact drift guards, issue tracker) with evidence for every fact, runs the project's own build/lint/test commands with the flags CI uses, and applies matcher-decidable static checks over the diff. No guessed defaults: an undeterminable fact is null with its reason stated.
2. **Phase 1, scope and plan.** Builds a deterministic scope manifest (which files are reviewable, classified by content into areas, packed into review bundles within size caps, with a rename-aware size class that drives fan-out), extracts a structured "what's new" summary, and matches the changeset against the escaped-defects ledger so past misses become present coverage.
3. **Phase 2, review agents.** Launches the lenses above in parallel (sharded across bundles on large changesets), each reading its own checklist. Every agent reports a per-file coverage table.
4. **Phase 3, aggregate, fix, report.** Verifies coverage, filters false positives, triages each finding on its argument rather than its label, plans the fix wave by hazard before editing, then fixes within a bounded, rising-bar loop and re-reviews its own fixes (where most escaped defects actually live).
## Install
Drop the skill into your Claude Code skills folder:
```bash
git clone https://github.com/tphakala/claude-gate-skill.git ~/.claude/skills/gate
```
Then invoke it from Claude Code (for example, "run the gate before I push" or `/gate`, depending on how you trigger skills).
## Requirements
- **Required:** `git`, `bash`, `python3` (3.8+), and `jq`. The mechanical floor and scope scripts use these.
- **Recommended:** the language toolchains for the code you review (Go, Node, Rust), so the gate can run the project's own build/lint/test commands.
- **Optional and pluggable:**
- An **external second-opinion reviewer**: any capable non-Claude model reachable over a CLI or an MCP tool. The gate can dispatch the changeset to it in the background and fold its findings in as leads. Skip it and the in-process agents still run.
- A **cross-project memory bank**: any persistent recall tool. The gate can query it to rank the most relevant lessons for a changeset and to remember confirmed false positives. Entirely optional.
Both optional integrations are described in `reference/tooling.md`. Nothing about them is hard-wired to a specific vendor; wire them to whatever you have, or leave them out.
## Layout
- `SKILL.md`: the controller's runbook. The phases above, in order.
- `reference/patterns-agent<N>.md`: one file per review lens, holding that lens's checklist and worked examples.
- `reference/escaped-defects.md`: the lessons ledger. Every entry is a defect the gate once passed and a later layer caught, distilled to an "applies when" trigger and the check that now prevents it. Consulted at scope time, closed at report time.
- `reference/tooling.md`, `reference/fix-wave.md`, `reference/maintenance.md`, `reference/false-positives.md`: supporting detail for the scripts, the fix-wave discipline, how to extend the skill, and known-benign static-analysis patterns.
- `scripts/`: the deterministic mechanical floor (`discover`, `scope`, `static-checks`, `verify`, `contract-diff`, `triggers`, `ledger-match`, and helpers).
## A note on the ledger
`reference/escaped-defects.md` reads like a changelog of near-misses because that is what it is. Each entry was a real defect that slipped a review pass somewhere and got caught later. The specific origins have been genericized; the technical lesson and its trigger are what carry forward. New misses are meant to be appended (see `reference/maintenance.md`), so the gate gets harder to fool over time.
## License
MIT. See [LICENSE](LICENSE).