Orchestrata Ultimate › Gates › pre-push-guards

Gate: pre-push-guards

Purpose Refuse a push the suite must not run for, skip one whose exact source already passed, and bound the rest to the commits being pushed
Where it runs scripts/hooks/pre-push (tracked, wired by core.hooksPath = scripts/hooks)
Trigger git push without --no-verify (deploy/ship.sh pushes with --no-verify only after running the same work itself)
Exact command the hook; its test step is .venv/bin/python scripts/run_tests.py --affected "origin/master...<sha being pushed>"
Blocks Exit 1 on a protected branch, on a missing origin/master, or when run_tests.py fails; exit 0 on an already-verified source or an empty range
Ruling / ADR RUL-040 (fail closed, never a silent full run); RUL-032 and the 2026-09-21 ruling "no test that passes must run twice" (the skip); RUL-021 (the venv python)

The guards, in order

  1. Protected-branch guard. master or main checked out in the pushing worktree refuses with "refusing to run the test suite". Why (hook header): a full-suite run from a worktree with master checked out once drove real git writes against the live repository; commit 854bc6d97 (2026-07-27) records 16 commits landing on master, one reaching GitLab. The same commit added tests/plugins/git_sentinel.py, which fails a test that changes the live repo's HEAD, refs or config.
  2. Already-verified skip. _ship_source_id hashes the tracked files outside reports/ plus the untracked names; if it equals the first field of reports/.ship-verified and reports/run-tests-latest.json is green (failed == 0, no errors, passed > 0) at the stamped head_commit, the suite is skipped. It replicates deploy/ship.sh's functions, and the comment says to keep the two in sync.
  3. Base check. origin/master must resolve, or the hook refuses: "Refusing to run anything (fail-closed, RUL-040: never a silent full run)". The old arm that ran the full suite here was replaced in 2669f4882 (2026-10-21), as item D2b of the P-RUL040 brief (231ec39c1) asked.
  4. Range from the pushed commit. The hook reads git's ref update from stdin and uses origin/master...<local sha>, so a chunked push verifies each chunk (e27c12b50, 2026-10-21). The three-dot range covers only committed commits, never working-tree files. An empty diff exits 0 with "nothing to verify".
  5. The run. The venv python runs scripts/run_tests.py --affected "$RANGE" (not uv run, since 949c1628c, 2026-10-21: uv run re-synced the package editable and the source-provenance gate refused). See affected-selection.
  6. Self-stamp. A green run whose report matches HEAD writes <source id> <HEAD> to reports/.ship-verified, so a re-push of identical source skips.

Diagram projects-orchestrata-ultimate-gates-pre-push-guards-1

Typical failures and how to fix them

Message Fix
refusing to run the test suite — this worktree has protected branch 'master' checked out Push from a feature-branch worktree. The hook names git push --no-verify as the operator's own risk
origin/master not found — cannot bound the blast radius git fetch origin, or pass an explicit --affected-decision to run_tests.py
The suite was skipped and you wanted it "touch any tracked file, or delete that stamp, to force a re-run"
A run refusal read the named stage: freshness, affected-refusal, infrastructure, gates; see the workflow's push gate