Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# See docs/DEVELOPMENT.md "Pre-commit setup" and docs/HARNESS.md for the
# defence-in-depth rationale. The same gitleaks scan runs in CI; this
# pre-commit layer is the first of three independent checkpoints.

repos:
# Ruff — format + lint with auto-fix.
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.12
hooks:
- id: ruff
args: [--fix]
- id: ruff-format

# Generic hygiene.
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-yaml
- id: check-toml
- id: check-json
# tsconfig.json uses JSONC (permits comments) per TS convention.
exclude: ^frontend/(tsconfig.*\.json|jsconfig\.json)$
- id: check-merge-conflict
- id: check-added-large-files
args: [--maxkb=500]
- id: end-of-file-fixer
- id: trailing-whitespace
- id: mixed-line-ending
args: [--fix=lf]

# Secret scan — third checkpoint (local → pre-commit → CI).
- repo: https://github.com/gitleaks/gitleaks
rev: v8.24.3
hooks:
- id: gitleaks

# Conventional commit enforcement — runs at commit-msg stage.
- repo: https://github.com/commitizen-tools/commitizen
rev: v4.1.0
hooks:
- id: commitizen
stages: [commit-msg]

# mypy — runs against the project's uv env so project deps are visible.
# CI runs the strict pass; pre-commit's job is fast feedback, not the gate.
- repo: local
hooks:
- id: mypy
name: mypy (strict, whole project)
# --frozen forbids uv from re-resolving the lockfile mid-invocation.
# Without it, a mid-edit pyproject.toml/uv.lock mismatch would
# trigger a silent transitive upgrade into the commit.
entry: uv run --frozen mypy src/ tests/
language: system
pass_filenames: false
types: [python]