From 5f023afe96981466a5fdf9fbd2ea8291510b6434 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Thu, 14 May 2026 21:20:21 +0200 Subject: [PATCH] perf(pre-commit): move mypy/pylint/bandit from pre-push to pre-commit Heaviest hooks now run on tiny per-commit staged diffs instead of the full force-push diff. After the recent filter-repo history rewrite, origin/main shares no ancestor with local main, so pre-push was feeding mypy/pylint/bandit ~every .py file in the repo, OOM-killing inside the 4 GiB cgroup. Per-commit cost: ~5-10 s on Python edits. Pre-push now only runs pytest-coverage (scoped) and prettier (scoped+isolated). --- ...pre-commit-stage-rebalance-2026-05-14.json | 28 +++++++++++++++++++ meta/.pre-commit-config.yaml | 16 +++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 docs/superpowers/evidence/pre-commit-stage-rebalance-2026-05-14.json diff --git a/docs/superpowers/evidence/pre-commit-stage-rebalance-2026-05-14.json b/docs/superpowers/evidence/pre-commit-stage-rebalance-2026-05-14.json new file mode 100644 index 00000000..12dcfe92 --- /dev/null +++ b/docs/superpowers/evidence/pre-commit-stage-rebalance-2026-05-14.json @@ -0,0 +1,28 @@ +{ + "intent": "Make pre-push fast and lightweight by moving the heaviest hooks (mypy, pylint, bandit) from pre-push to pre-commit so they run on tiny per-commit staged diffs instead of the full force-push diff that scans ~every .py file in the repo.", + "scope": [ + "meta/.pre-commit-config.yaml", + "Non-goals: do not change ruff/codespell/shellcheck stages; do not relax the 4 GiB pre-push cgroup cap; do not remove pytest-coverage or prettier from pre-push." + ], + "changes": [ + "mypy: stages: [pre-push] -> stages: [pre-commit]", + "pylint: stages: [pre-push] -> stages: [pre-commit]", + "bandit: stages: [pre-push] -> stages: [pre-commit]", + "Updated section comments to reflect new per-commit scoping rationale (force-push divergence after history rewrite caused full-repo scans + OOM under cgroup cap)." + ], + "verification": [ + { + "command": "pre-commit validate-config meta/.pre-commit-config.yaml", + "result": "pass", + "evidence": "exit 0; grep confirms stage assignments: mypy:pre-commit, pylint:pre-commit, bandit:pre-commit, pytest-coverage:pre-push, prettier:pre-push." + } + ], + "risks": [ + "Per-commit time grows by ~5-10 s on Python edits (mypy + pylint + bandit on the staged file set). Acceptable trade vs current pre-push behavior which scans thousands of files after a divergent force-push.", + "If a user bypasses commit-stage hooks (e.g. amends with --no-verify, which is forbidden by policy) the safety net is gone on push. Mitigation: existing repo rule forbids --no-verify; ai-evidence-contract hook still runs on commit." + ], + "rollback": [ + "Revert this commit (git revert ) to restore stages: [pre-push] on the three hooks.", + "After rollback: run pre-commit install --hook-type pre-commit --hook-type pre-push to refresh local hooks." + ] +} diff --git a/meta/.pre-commit-config.yaml b/meta/.pre-commit-config.yaml index 11232614..e99d2fa6 100644 --- a/meta/.pre-commit-config.yaml +++ b/meta/.pre-commit-config.yaml @@ -131,13 +131,15 @@ repos: types_or: [python, pyi] # =========================================================================== - # MYPY - Static type checking (runs on push only for speed) + # MYPY - Static type checking (per-commit on changed files only) + # Was on pre-push, but force-push diffs caused full-repo scans + OOM. On + # pre-commit it sees only the file(s) currently staged → near-instant. # =========================================================================== - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.13.0 hooks: - id: mypy - stages: [pre-push] + stages: [pre-commit] args: - --ignore-missing-imports - --no-error-summary @@ -172,13 +174,14 @@ repos: - types-python-dateutil # =========================================================================== - # PYLINT - Comprehensive Python linter (runs on push only for speed) + # PYLINT - Comprehensive Python linter (per-commit on changed files only) + # Was on pre-push, but force-push diffs caused full-repo scans + OOM. # =========================================================================== - repo: https://github.com/pylint-dev/pylint rev: v3.3.2 hooks: - id: pylint - stages: [pre-push] + stages: [pre-commit] args: - --rcfile=pyproject.toml - --fail-under=8.0 @@ -191,13 +194,14 @@ repos: exclude: ^(Bash/|\.venv/) # =========================================================================== - # BANDIT - Security linter (runs on push only for speed) + # BANDIT - Security linter (per-commit on changed files only) + # Was on pre-push, but force-push diffs caused full-repo scans + OOM. # =========================================================================== - repo: https://github.com/PyCQA/bandit rev: 1.7.10 hooks: - id: bandit - stages: [pre-push] + stages: [pre-commit] args: - -c - pyproject.toml