diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 51551af..c29d32e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -128,7 +128,7 @@ repos: pass_filenames: false always_run: true require_serial: true - stages: [pre-push] + stages: [manual] - repo: https://github.com/codespell-project/codespell rev: v2.3.0 @@ -199,3 +199,17 @@ repos: |package\.json|package-lock\.json|pnpm-lock\.yaml |Cargo\.(toml|lock)|go\.(mod|sum) |\.fvmrc|\.nvmrc|\.python-version)$ + + - repo: local + hooks: + # The only pre-push hook. Everything that used to run here is now + # `stages: [manual]` -- run on demand with `scripts/check_gate_stamp.sh + # full`, and by CI on every push. finish_auto.sh stamps HEAD after its + # gate; a tree without that receipt cannot leave the machine. + - id: gate-stamp + name: pushed tree passed the local gate (stamp check) + entry: scripts/check_gate_stamp.sh check + language: system + pass_filenames: false + always_run: true + stages: [pre-push] diff --git a/scripts/check_gate_stamp.sh b/scripts/check_gate_stamp.sh new file mode 100755 index 0000000..b2e7c34 --- /dev/null +++ b/scripts/check_gate_stamp.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# ============================================================================ +# pre-push gate: is the pushed tree stamped as having passed the local gate? +# +# Thin delegate to the shared tool in ~/src/utils. The pre-push stage used to +# re-run every suite (10+ min under the resource cap); now finish_auto.sh's +# gate leaves a receipt (the tree hash) and this only compares against it. +# +# Usage: +# scripts/check_gate_stamp.sh check # pre-commit's pre-push stage (~1 s) +# scripts/check_gate_stamp.sh full # the old pre-push suites, then stamp +# ============================================================================ + +set -euo pipefail + +readonly SHARED_GATE="${UTILS_ROOT:-$HOME/src/utils}/scripts/gate_stamp.sh" + +main() { + if [[ ! -x "$SHARED_GATE" ]]; then + echo "Error: shared gate-stamp tool not found at $SHARED_GATE" >&2 + echo " Clone github.com/kuhyx/utils to ~/src/utils, or set" >&2 + echo " UTILS_ROOT to where it lives." >&2 + exit 1 + fi + + exec bash "$SHARED_GATE" "$@" +} + +main "$@" diff --git a/scripts/ci_mirror.sh b/scripts/ci_mirror.sh index 66c619d..4c8908a 100755 --- a/scripts/ci_mirror.sh +++ b/scripts/ci_mirror.sh @@ -15,8 +15,9 @@ # 2. `pre-commit run --all-files` (mirrors the pre-commit workflow); # 3. `python -m pytest` inside that clean venv (mirrors Tests). # -# Wired as the pre-push hook, so a red result blocks the push before CI ever -# sees it. Escape hatch for genuine emergencies: `git push --no-verify`. +# Runs on demand (`scripts/check_gate_stamp.sh full`, pre-commit's manual +# stage) and in CI. It left the pre-push path on 2026-09-20: 10+ minutes +# per push under the resource cap, for work finish_auto.sh had just done. # ============================================================================ set -euo pipefail @@ -37,7 +38,7 @@ log() { printf 'ci-mirror: %s\n' "$1" >&2; } fail() { log "FAILED — $1" - log "CI would be red. Fix the above, or 'git push --no-verify' to override." + log "CI would be red. Fix the above before pushing." exit 1 }