Skip to content

Quality Gates

Every code change passes through three automated quality gates before commit.


The Gate Flow

flowchart LR
    A[Code Change] --> B[Stop Hook]
    B -->|pass| C[Linter Agent]
    B -->|fail| X1[Block]
    C -->|pass| D[Code-Reviewer]
    C -->|fail| X2[Auto-fix & Retry]
    D -->|approve| E[Validator]
    D -->|reject| X3[Fix & Retry]
    E -->|pass| F[Ready to Commit]
    E -->|fail| X4[Debug & Retry]

Gate 1: Stop Hook

Trigger: End of every turn Speed: ~10ms Tool: ruff check

Catches lint errors immediately, before they reach CI.

# What it checks
ruff check src/changed_file.py

# On failure
LINT_GATE:FAIL - 3 errors found
  src/foo.py:12: E501 line too long
  src/foo.py:25: F401 unused import

Benefits: - Instant feedback (vs 2-min CI wait) - Only checks edited files - Blocks commits with errors


Gate 2: Linter Agent

Model: Haiku 4.5 (cost-optimized) Scope: Modified files only

Auto-fixes safe mechanical issues:

Fixes Does NOT Touch
Import order Control flow
Unused imports Logic
Formatting Semantics
Trailing whitespace Variable names
{
  "summary": "Fixed 12 lint issues",
  "files_modified": ["src/foo.py"],
  "remaining_issues": 0,
  "status": "APPROVED"
}

Gate 3: Code-Reviewer

Model: Opus 4.5 Focus: Security & correctness

Reviews semantic quality (not style):

Checks: - [ ] OWASP Top 10 vulnerabilities - [ ] SQL injection, XSS, command injection - [ ] Logic errors and edge cases - [ ] API design patterns - [ ] Test coverage gaps - [ ] Performance concerns

Skips (when linter passed): - Whitespace - Import order - Trailing commas


Gate 4: Validator

Model: Sonnet 4.5 Tool: pytest, mypy

Runs tests and type checks:

pytest tests/ --cov=src
mypy src/

On failure: 1. Analyzes error 2. Suggests fix 3. Loops back to Implementer


Feedback Loops

Gates can loop back for fixes:

flowchart TD
    I[Implementer] --> R[Code-Reviewer]
    R -->|needs changes| I
    R -->|approved| V[Validator]
    V -->|tests fail| I
    V -->|pass| C[Commit]

Maximum 3 retry loops before escalating to user.


Performance

Without Gates With Gates
2 min (CI feedback) 10ms (instant)
Entire repo scanned Only changed files
Manual review Automated
Post-push discovery Pre-commit prevention

Configuration

Gates are configured in .claude/settings.json:

{
  "hooks": {
    "Stop": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "python .claude/hooks/lint_gate.py"
      }]
    }]
  }
}

What's Next?