Skip to main content

64. Pre-commit Hooks Strategy

Date: 2025-11-29

Status

Accepted

Category

Development & Tooling

Context

Code quality enforcement can happen at multiple stages:
  1. IDE/Editor: Real-time linting (variable, depends on developer setup)
  2. Pre-commit: Before code is committed (local, fast)
  3. CI/CD: After code is pushed (remote, comprehensive)
Without pre-commit hooks:
  • Bad code reaches the repository
  • CI fails after push (slow feedback)
  • Code review wastes time on style issues
  • Inconsistent formatting across developers
The project requires a pre-commit strategy that:
  • Catches issues before they reach CI
  • Runs fast enough to not disrupt workflow
  • Covers linting, formatting, type checking, and security
  • Is consistent across all developer machines

Decision

Use pre-commit framework with a curated set of hooks covering code quality, security, and documentation validation.

Hook Categories

1. Fast Checks (< 1 second)

2. Code Formatting (< 5 seconds)

3. Type Checking (< 30 seconds)

4. Security Scanning (< 10 seconds)

5. Documentation Validation (< 5 seconds)

6. Test Infrastructure (custom)

Execution Strategy

Developer Workflow

Consequences

Positive

  • Early Feedback: Issues caught before commit, not in CI
  • Consistent Code: All developers use same formatting/linting
  • Security: Secrets and vulnerabilities caught locally
  • Faster CI: Pre-validated code reduces CI failures
  • Documentation: Validates frontmatter and links locally

Negative

  • Commit Delay: Hooks add ~10-30 seconds per commit
  • Setup Required: Developers must run pre-commit install
  • False Positives: Occasional issues with hook detection

Mitigation

  • fail_fast: true stops on first error (faster feedback)
  • Slow checks (mypy) run only on push, not commit
  • --no-verify available for emergencies (logged in CI)
  • CI runs same checks to catch bypassed hooks

Hook Selection Criteria

Alternatives Considered

Husky (JavaScript)

  • Rejected: Requires Node.js, not Python-native
  • Additional dependency for Python project

Git hooks directly

  • Rejected: Not portable, hard to version control
  • No hook management or updates

CI-only validation

  • Rejected: Slow feedback loop
  • Wastes CI resources on obvious issues

Lefthook

  • Considered: Fast, parallel execution
  • Rejected: Smaller ecosystem, less Python integration

References

  • Configuration: .pre-commit-config.yaml
  • Validation scripts: scripts/check_test_memory_safety.py, scripts/docs/validate-frontmatter.py
  • Related ADRs: ADR-0065
  • External: pre-commit Documentation