#!/usr/bin/env bash # # pre-push: the Lens pass. Runs `make verify` (cheap gate + heavy sensors + both # test suites) and blocks the push if anything fails. # # Install with `make hooks` (symlinks this file into this clone's git hooks # directory). Deliberate bypass: `git push --no-verify`. # # Why a symlink and not `git config core.hooksPath .githooks`: bd keeps its own # managed hooks in .git/hooks (pre-commit flushes .beads/issues.jsonl, post-merge # imports it). Pointing core.hooksPath elsewhere would silently retire them, and # bd would still report its hooks as installed. Installing one symlink per hook # in .githooks/ keeps every hook manager's files where they expect them. # # stdin carries " " per ref being # pushed; the Lens pass is repo-wide, so it is deliberately not read. set -uo pipefail if ! cd "$(git rev-parse --show-toplevel)"; then echo "pre-push: cannot find the repository root; refusing to let this push through" >&2 exit 1 fi if ! command -v make >/dev/null 2>&1; then echo "pre-push: make not found on PATH — the Lens pass cannot run, so the push is blocked" >&2 echo "pre-push: install make, or bypass deliberately with: git push --no-verify" >&2 exit 1 fi log=$(git rev-parse --git-dir)/lens-pass.log echo "pre-push: running the Lens pass (make verify) — full log: $log" set -o pipefail if make verify 2>&1 | tee "$log"; then echo "pre-push: Lens pass passed" exit 0 fi last_step=$(grep -E '^==> ' "$log" | tail -n 1) { echo echo "==================================================================" echo "pre-push: LENS PASS FAILED — push blocked" echo " last step started: ${last_step:-unknown (see log)}" echo " full log: $log" echo " triage the failure (real bug / environment-dependent test /" echo " design nit — see AGENTS.md), then re-run: make verify" echo " deliberate bypass: git push --no-verify" echo "==================================================================" } >&2 exit 1