Skip to content
Part 3: The Craft 8 min read

Lesson 08

Quality Gates

Catch 87% of Bugs Before a Human Ever Reads Your Code

Here's a number that changed how we think about code quality: fixing a bug at commit time takes 2 minutes. Fixing the same bug in production takes 40+ hours. That's a 1,200x cost difference.

The question isn't whether to automate quality checks. It's where and how fast.

Three layers, strict speed budgets

Speed budgets aren't optional. They're the difference between a quality system that sticks and one that gets bypassed within a week.

Layer 1: Pre-commit (budget: under 5 seconds)

Runs on every save. If it's slow, developers will add --no-verify to muscle memory.

# .pre-commit-config.yaml
hooks:
  - ruff --fix           # Auto-fix formatting + imports
  - ruff-format          # Consistent code style
  - check-yaml           # Valid YAML
  - detect-private-key   # Catch committed secrets

Note: auto-fix, not just check. Developers shouldn't have to think about formatting. The tool handles it.

Layer 2: Pre-push (budget: under 60 seconds)

Runs before code leaves your machine. Catches the stuff that takes longer to check.

# .git/hooks/pre-push
mypy app/                # Full type check
pytest tests/unit/ -x    # Unit tests (fail-fast)
ruff check --select S    # Security-focused rules

Layer 3: CI/CD (budget: under 5 minutes)

The final gate before merge. Comprehensive, thorough, no shortcuts.

# .github/workflows/quality-gates.yml
- ruff format --check .          # Formatting
- ruff check .                   # Full lint suite
- mypy app/ --strict             # Strict type checking
- pytest --cov-fail-under=80 -v  # Tests + coverage floor
- pip-audit --strict             # Dependency vulnerabilities

The results

LayerIssues caughtAvg fix timeCost multiplier
Pre-commit1,200+2 min1x
Pre-push89515 min8x
CI/CD37745 min23x
Human review3783 hours90x

87% of all issues caught before any human looked at the code. That's not a testing stat — it's a team velocity multiplier. Your reviewers spend their time on architecture and logic instead of pointing out formatting and type errors.

Roll it out gradually

Don't add everything at once. Developers revolt against sudden, sweeping tooling changes.

WhenAdd
Week 1Formatting only (zero friction, instant consistency)
Week 2Basic linting rules
Month 1Type checking (permissive), coverage floor at 60%
Month 2Security scanning, coverage up to 70%
Month 3Full strict suite, coverage at 80%

Why speed budgets are non-negotiable

The fastest way to destroy a quality system is making it slow. Here's what happens:

  1. Pre-commit hook takes 30 seconds
  2. Developers start using --no-verify
  3. Issues pile up in CI instead of getting caught locally
  4. CI takes 15 minutes because it's catching everything
  5. Developers push and go get coffee instead of fixing issues immediately
  6. Context switch. Issues are now 10x harder to fix.

Keep pre-commit under 5 seconds. This is the one thing you don't compromise on.