64. Pre-commit Hooks Strategy
Date: 2025-11-29Status
AcceptedCategory
Development & ToolingContext
Code quality enforcement can happen at multiple stages:- IDE/Editor: Real-time linting (variable, depends on developer setup)
- Pre-commit: Before code is committed (local, fast)
- CI/CD: After code is pushed (remote, comprehensive)
- Bad code reaches the repository
- CI fails after push (slow feedback)
- Code review wastes time on style issues
- Inconsistent formatting across developers
- 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: truestops on first error (faster feedback)- Slow checks (mypy) run only on push, not commit
--no-verifyavailable for emergencies (logged in CI)- CI runs same checks to catch bypassed hooks
Hook Selection Criteria
| Hook | Purpose | Time | Stage |
|---|---|---|---|
| trailing-whitespace | Clean files | <1s | commit |
| ruff | Linting + fixing | 2-5s | commit |
| ruff-format | Formatting | 1-3s | commit |
| mypy | Type checking | 10-30s | push |
| bandit | Security scan | 3-5s | commit |
| gitleaks | Secret detection | 2-3s | commit |
| validate-frontmatter | Docs validation | 1-2s | commit |
| check-test-memory-safety | Test quality | 2-3s | commit |
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