#!/bin/bash # Pre-commit hook — scans staged files for secrets using gitleaks # --- freshness notice: is this the gate that was SHIPPED? ---------------------- # Wiring is not freshness. git runs whatever the hooks directory holds TODAY, so # a clone that ran setup-hooks.sh once and never pulled runs an old gate while # looking perfectly configured. Measured 2026-09-21 on tor-ms22 (logstream seq # 172/173): core.hooksPath correct, zero stale copies in .git/hooks, tree clean # — and no pre-push hook at all, because the clone predated the commit adding it. # Shared implementation: myconfigs/common/hooks/hook-freshness.sh. ONE copy for # all six tracked-hook repos in this fleet, because five vendored copies of a # drift detector are five things that drift. SOFT dependency: silent when # myconfigs is not alongside, and it always exits 0 — a notice, never a gate. _fresh_root="$(git rev-parse --show-toplevel 2>/dev/null || true)" for _m in "${MYCONFIGS_DIR:-}" "$(dirname "${_fresh_root:-.}")/myconfigs" "${HOME:-}/myconfigs"; do [ -n "$_m" ] && [ -f "$_m/common/hooks/hook-freshness.sh" ] || continue sh "$_m/common/hooks/hook-freshness.sh" "$_fresh_root" || true break done if ! command -v gitleaks >/dev/null 2>&1; then echo "" echo "⚠️ gitleaks is not installed — skipping secret scan" echo " Install: brew install gitleaks (macOS)" echo " Or: curl -sSL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks_\$(uname -s)_\$(uname -m).tar.gz | sudo tar -xz -C /usr/local/bin gitleaks" echo "" exit 0 fi echo "🔒 Scanning for secrets..." if gitleaks protect --staged --no-banner 2>/dev/null; then echo "✅ No secrets detected" exit 0 else echo "" echo "❌ Secrets detected in staged changes — commit blocked" echo "" echo " Details: gitleaks protect --staged --verbose" echo " Bypass: git commit --no-verify" echo "" exit 1 fi