From 3e1fe673893f661e19edf4cb4ed79ec1dc095c9b Mon Sep 17 00:00:00 2001 From: Marsita the Ultra Date: Sat, 19 Sep 2026 00:07:19 +0100 Subject: [PATCH 1/5] always all: a pre-push hook that runs the whole suite and refuses red Marsita, 2026-09-19: "'always all' is simpler :) (as opposed to deciding what to run)". GitHub Actions already runs everything after the push and main now requires the `tests` and `audit` checks green to merge a PR. This is the same gate one step earlier, on the machine: 66 s on Gaia, 14 s on the NUC, and a red commit never leaves. First real run, against the live checkout, blocked a push on a failure that turned out to be someone's uncommitted work-in-progress; the same test passes on clean main. That is the hook doing its job. Escape hatch stays visible: `git push --no-verify`. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01AmAXMHTsfEdyB4H4tjkiQN --- githooks/pre-push | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100755 githooks/pre-push diff --git a/githooks/pre-push b/githooks/pre-push new file mode 100755 index 0000000..f8270de --- /dev/null +++ b/githooks/pre-push @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Always all. The whole suite runs before every push; red means no push. +# +# Marsita, 2026-09-19: "'always all' is simpler :) (as opposed to deciding +# what to run)". 66 s on Gaia, 14 s on the NUC. Deciding which tests a change +# touches costs more thought than the run and is wrong often enough to matter. +# +# GitHub Actions runs the same suite after the push and main requires it green +# to merge a PR. This hook is the earlier, cheaper copy of that gate: it stops +# the red commit leaving the machine at all. +# +# Escape hatch, on purpose and visible: `git push --no-verify`. +set -uo pipefail +REPO="$(git rev-parse --show-toplevel)" +cd "$REPO" || exit 1 + +PY="" +for v in .venv .venv311 .venv312 .venv313; do + [[ -x "$REPO/$v/bin/pytest" ]] && { PY="$REPO/$v/bin/pytest"; break; } +done +if [[ -z "$PY" ]]; then + echo "pre-push: no venv pytest under $REPO — pushing untested" >&2 + exit 0 +fi + +echo "→ pre-push: full test suite (always all)" +if "$PY" tests -q -x -p no:cacheprovider 2>&1 | tail -3; then + exit 0 +fi +echo " ✗ red. Nothing was pushed. Fix it, or push --no-verify and own it." >&2 +exit 1 From 6d96cd2146a028cac824ae150a43751d14a193d4 Mon Sep 17 00:00:00 2001 From: Marsita the Ultra Date: Sat, 19 Sep 2026 00:11:46 +0100 Subject: [PATCH 2/5] pre-push: report-only pushes skip the suite, judged on content not caller Marsita, 2026-09-19: "for pushing reports no test required? it's just plain text... I'm comfy with risk -> document the rule -> but someone can override it and attach extra files to report job?" The rule is now in the hook and in the diff, not in who runs it: the files between the remote sha and the pushed sha are listed, and only if every one is under docs/report/ does the push go out untested. One extra file anywhere else, or a new branch with no remote point to judge from, gets the full suite. No env var, no script name, no caller trust. Simulated: report-only range -> skipped by rule (4 files); a range that also carries code -> full suite; a new branch -> full suite. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01AmAXMHTsfEdyB4H4tjkiQN --- githooks/pre-push | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/githooks/pre-push b/githooks/pre-push index f8270de..2b87539 100755 --- a/githooks/pre-push +++ b/githooks/pre-push @@ -5,6 +5,15 @@ # what to run)". 66 s on Gaia, 14 s on the NUC. Deciding which tests a change # touches costs more thought than the run and is wrong often enough to matter. # +# ONE exception, and it is about the CONTENT of the push, never the caller: +# a push whose every changed file is under docs/report/ is plain text the +# daily report job generates, and it goes out untested. Marsita, 2026-09-19: +# "for pushing reports no test required? it's just plain text... I'm comfy +# with risk". The rule is judged on `git diff --name-only` between what the +# remote has and what is being pushed, so a job that is hijacked to carry one +# extra file outside docs/report/ gets the full suite like everyone else. +# Nothing about who is pushing, which script, or which env var is trusted. +# # GitHub Actions runs the same suite after the push and main requires it green # to merge a PR. This hook is the earlier, cheaper copy of that gate: it stops # the red commit leaving the machine at all. @@ -14,6 +23,29 @@ set -uo pipefail REPO="$(git rev-parse --show-toplevel)" cd "$REPO" || exit 1 +REPORT_ONLY_PREFIX="docs/report/" +ZERO="0000000000000000000000000000000000000000" + +# stdin: , one line per ref. +# Collect every file any pushed commit touches. A deleted ref pushes nothing. +changed="" +while read -r _lref lsha _rref rsha; do + [[ "$lsha" == "$ZERO" ]] && continue + if [[ "$rsha" == "$ZERO" ]]; then + # A new branch has no remote point to diff from. The rule cannot be + # judged, so the rule does not apply: full suite. + changed+="?new-branch"$'\n' + else + changed+="$(git diff --name-only "$rsha" "$lsha" 2>/dev/null || echo "?unknown")"$'\n' + fi +done +changed="$(printf '%s' "$changed" | sed '/^$/d')" + +if [[ -n "$changed" ]] && ! printf '%s\n' "$changed" | grep -qv "^$REPORT_ONLY_PREFIX"; then + echo "→ pre-push: report-only push ($(printf '%s\n' "$changed" | wc -l | tr -d ' ') files under $REPORT_ONLY_PREFIX), no tests by rule" + exit 0 +fi + PY="" for v in .venv .venv311 .venv312 .venv313; do [[ -x "$REPO/$v/bin/pytest" ]] && { PY="$REPO/$v/bin/pytest"; break; } From e01a97a6755a1a210f59690d1a7e530dde81f709 Mon Sep 17 00:00:00 2001 From: Marsita the Ultra Date: Sat, 19 Sep 2026 00:14:37 +0100 Subject: [PATCH 3/5] pre-push: Marsita's note on the report rule "this sounds like it will be exploited one day, please be smart when using it :)" Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01AmAXMHTsfEdyB4H4tjkiQN --- githooks/pre-push | 3 +++ 1 file changed, 3 insertions(+) diff --git a/githooks/pre-push b/githooks/pre-push index 2b87539..bf217c3 100755 --- a/githooks/pre-push +++ b/githooks/pre-push @@ -14,6 +14,9 @@ # extra file outside docs/report/ gets the full suite like everyone else. # Nothing about who is pushing, which script, or which env var is trusted. # +# Marsita, 2026-09-19: "this sounds like it will be exploited one day, +# please be smart when using it :)" +# # GitHub Actions runs the same suite after the push and main requires it green # to merge a PR. This hook is the earlier, cheaper copy of that gate: it stops # the red commit leaving the machine at all. From 4521b41b9d9f0f76fd26816fb733122848ccd928 Mon Sep 17 00:00:00 2001 From: Marsita the Ultra Date: Sat, 19 Sep 2026 01:44:53 +0100 Subject: [PATCH 4/5] pre-push: one log line per use of the report loophole "this is a loophole, might be abused, trust me bro", with the commit and the file list, in fleet/logs/pre-push.log. The post-mortem is a grep, not a guess. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01AmAXMHTsfEdyB4H4tjkiQN --- githooks/pre-push | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/githooks/pre-push b/githooks/pre-push index bf217c3..c15a6ee 100755 --- a/githooks/pre-push +++ b/githooks/pre-push @@ -45,7 +45,15 @@ done changed="$(printf '%s' "$changed" | sed '/^$/d')" if [[ -n "$changed" ]] && ! printf '%s\n' "$changed" | grep -qv "^$REPORT_ONLY_PREFIX"; then - echo "→ pre-push: report-only push ($(printf '%s\n' "$changed" | wc -l | tr -d ' ') files under $REPORT_ONLY_PREFIX), no tests by rule" + n="$(printf '%s\n' "$changed" | wc -l | tr -d ' ')" + echo "→ pre-push: report-only push ($n files under $REPORT_ONLY_PREFIX), no tests by rule" + # The receipt for the post-mortem. One line per use of the loophole: + # when, which commit, which files. Marsita, 2026-09-19, on the wording: + # "I like reporting: this is a loophole, might be abused, trust me bro". + mkdir -p "$REPO/fleet/logs" + printf '%s loophole: report-only push, might be abused, trust me bro | %s | %s\n' \ + "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$(git rev-parse --short HEAD)" \ + "$(printf '%s' "$changed" | tr '\n' ' ')" >> "$REPO/fleet/logs/pre-push.log" exit 0 fi From 54d3e692491cb822fa9988b9a4b72337576eaede Mon Sep 17 00:00:00 2001 From: Marsita the Ultra Date: Sat, 19 Sep 2026 02:04:50 +0100 Subject: [PATCH 5/5] pre-push: always all, no exceptions The report-only skip is gone, with its log and its warning label. Marsita, 2026-09-19: "no footguns. Github actions, commit, run tests, by default, not skip... No footguns, no loopholes, no asking for trouble." Every push runs the whole suite. The report job included: 66 s on Gaia once a day is nothing, and a red suite is a reason the report should not go out either. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01AmAXMHTsfEdyB4H4tjkiQN --- githooks/pre-push | 43 ------------------------------------------- 1 file changed, 43 deletions(-) diff --git a/githooks/pre-push b/githooks/pre-push index c15a6ee..f8270de 100755 --- a/githooks/pre-push +++ b/githooks/pre-push @@ -5,18 +5,6 @@ # what to run)". 66 s on Gaia, 14 s on the NUC. Deciding which tests a change # touches costs more thought than the run and is wrong often enough to matter. # -# ONE exception, and it is about the CONTENT of the push, never the caller: -# a push whose every changed file is under docs/report/ is plain text the -# daily report job generates, and it goes out untested. Marsita, 2026-09-19: -# "for pushing reports no test required? it's just plain text... I'm comfy -# with risk". The rule is judged on `git diff --name-only` between what the -# remote has and what is being pushed, so a job that is hijacked to carry one -# extra file outside docs/report/ gets the full suite like everyone else. -# Nothing about who is pushing, which script, or which env var is trusted. -# -# Marsita, 2026-09-19: "this sounds like it will be exploited one day, -# please be smart when using it :)" -# # GitHub Actions runs the same suite after the push and main requires it green # to merge a PR. This hook is the earlier, cheaper copy of that gate: it stops # the red commit leaving the machine at all. @@ -26,37 +14,6 @@ set -uo pipefail REPO="$(git rev-parse --show-toplevel)" cd "$REPO" || exit 1 -REPORT_ONLY_PREFIX="docs/report/" -ZERO="0000000000000000000000000000000000000000" - -# stdin: , one line per ref. -# Collect every file any pushed commit touches. A deleted ref pushes nothing. -changed="" -while read -r _lref lsha _rref rsha; do - [[ "$lsha" == "$ZERO" ]] && continue - if [[ "$rsha" == "$ZERO" ]]; then - # A new branch has no remote point to diff from. The rule cannot be - # judged, so the rule does not apply: full suite. - changed+="?new-branch"$'\n' - else - changed+="$(git diff --name-only "$rsha" "$lsha" 2>/dev/null || echo "?unknown")"$'\n' - fi -done -changed="$(printf '%s' "$changed" | sed '/^$/d')" - -if [[ -n "$changed" ]] && ! printf '%s\n' "$changed" | grep -qv "^$REPORT_ONLY_PREFIX"; then - n="$(printf '%s\n' "$changed" | wc -l | tr -d ' ')" - echo "→ pre-push: report-only push ($n files under $REPORT_ONLY_PREFIX), no tests by rule" - # The receipt for the post-mortem. One line per use of the loophole: - # when, which commit, which files. Marsita, 2026-09-19, on the wording: - # "I like reporting: this is a loophole, might be abused, trust me bro". - mkdir -p "$REPO/fleet/logs" - printf '%s loophole: report-only push, might be abused, trust me bro | %s | %s\n' \ - "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$(git rev-parse --short HEAD)" \ - "$(printf '%s' "$changed" | tr '\n' ' ')" >> "$REPO/fleet/logs/pre-push.log" - exit 0 -fi - PY="" for v in .venv .venv311 .venv312 .venv313; do [[ -x "$REPO/$v/bin/pytest" ]] && { PY="$REPO/$v/bin/pytest"; break; }