#!/usr/bin/env bash
# pre-commit — the fast lint gates, enforced so they cannot be silently skipped (review F-1).
# ruff format --check is one of the six ci_local.sh gates; hosted Actions is startup-dead and the
# bar had degraded to "a human remembers to run the script". This runs the two fast gates on every
# commit. The FULL stack (mypy, pytest, lint-imports, conformance) stays in scripts/ci_local.sh —
# run it before every push/milestone. Activate once per clone: git config core.hooksPath .githooks
set -u
cd "$(git rev-parse --show-toplevel)" || exit 1
RUFF="$(command -v ruff || echo .venv/bin/ruff)"
fail=0
echo "pre-commit: ruff format --check"
"$RUFF" format --check || { echo "  -> run: ruff format"; fail=1; }
echo "pre-commit: ruff check"
"$RUFF" check || fail=1

# Sprint 224h gate: `# noqa: BLE001` with no trailing rationale is banned.
# Every wide `except Exception` catch must name the boundary (HTTP handler
# top, background sweep, mid-write read) or the class(es) the wide catch
# subsumes. Zero rationale-less BLE001 sites remain as of ee7054c6; this
# gate makes drift loud rather than silent.
echo "pre-commit: BLE001-rationale gate"
if grep -rn 'noqa: BLE001[[:space:]]*$' src/ tests/ 2>/dev/null; then
  echo "  ^^ BLE001 sites above have no rationale. Add '— <boundary or class list>' after the noqa."
  fail=1
fi

# REVIEW-2026-08-28 Q1 gate: mypy strict on `src/substrate`. The BLACKBOARD
# claimed "mypy strict clean" 111 times across 2026-06 through 2026-08; at
# review open, mypy strict was returning 10 errors across 6 files. The
# check runs in about 4 seconds when the cache is warm. Adding it to the
# pre-commit gate closes the "green is not proven" class named in memory
# `be-your-own-skeptic-green-is-not-proven`. `scripts/ci_local.sh` runs
# the full stack (pytest + lint-imports + conformance); this gate keeps
# mypy at every commit.
echo "pre-commit: mypy --strict src/substrate"
UV="$(command -v uv || echo .venv/bin/uv)"
if ! "$UV" run mypy --strict src/substrate > /tmp/substrate-mypy.log 2>&1; then
  tail -15 /tmp/substrate-mypy.log
  echo "  ^^ mypy strict violations. Fix or add a scoped [tool.mypy.overrides] entry with justification."
  fail=1
fi

# Sprint 224h gate + drift-grooming 2026-09-02: raw-status-string
# comparison ban. `SessionStatus(StrEnum)` in
# `substrate/src/substrate/session_registry.py` names the four values;
# any `== "ended"` / `== "parked"` etc. in the daemon code is a drift
# point that would silently return False after a rename. The old
# STATUS_* aliases were dropped in this pass; substrate-ui/session_registry.py
# now re-exports SessionStatus directly. Substrate (this repo) does not
# carry session status literals, so this grep is a no-op here; the same
# hook shipped on substrate-ui catches regressions on that side.
echo "pre-commit: status-literal-comparison gate (substrate-ui side)"
if [ -d ../substrate-ui ]; then
  if grep -rn '== "ended"\|== "parked"\|== "interrupted"\|== "running"' ../substrate-ui/*.py 2>/dev/null; then
    echo "  ^^ Compare against SessionStatus.ENDED / .PARKED / .INTERRUPTED / .RUNNING instead."
    fail=1
  fi
fi

[ "$fail" -ne 0 ] && echo "pre-commit FAILED — fix the above (or: git commit --no-verify to override deliberately)"
exit $fail
