9bd1a54d71
A census of all thirteen gate scripts across the four felhom repos on 2026-08-02 found one clean correlation: every check a CLAUDE.md tells a person to run was passing, and two of the four nobody is told to run were failing — one since 14 July. Neither failure was harmful in effect (checked line by line); nothing would have said so if they had been. The fix is not more gates, it is one place to run them from. repo_gates.py runs site + hostinstall + hub-confirm + manifest-bearer + reuse-refs, streams each gate's own output, and exits worst-wins non-zero. A missing gate script is a FAILURE and prints the path tried — fail-closed, because a runner that quietly skips a gate is the inert-seam failure this project has shipped four times. It copies catalog_gates.py (R-161), NOT site_gates.py, which is a gate and not a runner. .githooks/pre-push runs it with --fast and refuses the push. Honest limits are written into the hook itself: per-clone (core.hooksPath is local config), and --no-verify bypasses it on purpose. Any manual run WARNS when the clone is unarmed. Measured on git 2.47.3: a relative core.hooksPath resolves correctly and the hook's cwd is the repo root from any subdirectory. test_repo_gates.py is a SEAM test — it asserts each member gate's own distinctive stdout, not the runner's summary line, which an inert runner prints while calling nothing. Red-proofed: replacing run_gate's body with 'return 0' still prints 'all felhom.eu gates OK' and exits 0, and turns the seam test red.
48 lines
2.4 KiB
Bash
Executable File
48 lines
2.4 KiB
Bash
Executable File
#!/bin/sh
|
|
# pre-push — refuse a push that carries a broken gate. (2026-08-02, R-29 leg (b) first half.)
|
|
#
|
|
# Runs this repo's ONE gate entry point in --fast mode: only checks that touch no network and no
|
|
# container runtime, so a push stays a push and never pulls images or starts containers. The slow
|
|
# gates stay deliberate periodic runs; a hook that takes minutes gets bypassed within a week and
|
|
# the bypass becomes the habit.
|
|
#
|
|
# BOTH LINES BELOW ARE DELIBERATE. An absent log line is not evidence a hook ran — a silent pass is
|
|
# equally consistent with "gates green" and "hook never fired", so a passing push says so out loud.
|
|
#
|
|
# HONEST LIMITS, stated so this is not mistaken for enforcement it cannot provide:
|
|
# * per-clone — core.hooksPath is local config and a clone does not carry it. Arm a clone once:
|
|
# git config core.hooksPath .githooks
|
|
# Any manual entry-point run WARNS when the clone is unarmed.
|
|
# * skippable — `git push --no-verify` bypasses this entirely. That is on purpose: an escape
|
|
# hatch that cannot be reached is one that gets removed the first time it is
|
|
# inconvenient. USING IT MUST BE STATED IN THE SESSION REPORT.
|
|
# The half that is neither per-clone nor skippable is CI — felhom.eu OPEN-ITEMS.md R-168.
|
|
#
|
|
# Measured 2026-08-02 (git 2.47.3): a relative core.hooksPath resolves correctly and the hook's cwd
|
|
# is the repo root whether `git push` is issued from the root or from any subdirectory. The
|
|
# explicit rev-parse below does not depend on that.
|
|
set -u
|
|
|
|
root=$(git rev-parse --show-toplevel 2>/dev/null) || {
|
|
echo "pre-push: FAIL - cannot resolve the repo root (git rev-parse --show-toplevel)." >&2
|
|
exit 1
|
|
}
|
|
cd "$root" || exit 1
|
|
|
|
if ! command -v python3 >/dev/null 2>&1; then
|
|
echo "pre-push: FAIL - python3 not found, so the gates CANNOT run. This is a failure, never a" >&2
|
|
echo " pass by default. Install python3, or push with --no-verify and say so." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "pre-push [felhom.eu]: running scripts/repo_gates.py --fast ..."
|
|
python3 "scripts/repo_gates.py" --fast
|
|
rc=$?
|
|
if [ "$rc" -ne 0 ]; then
|
|
echo "pre-push [felhom.eu]: PUSH REFUSED - gates exited $rc. Fix the finding above, or bypass with" >&2
|
|
echo " 'git push --no-verify' and state that you did in the session report." >&2
|
|
else
|
|
echo "pre-push [felhom.eu]: gates OK - push proceeding."
|
|
fi
|
|
exit $rc
|