aide-pre-push-gate · git:20260908.f6b4048 · 2026-09-08 · sha256 6703aecd6eb8d5eb
aide-pre-push-gate git:20260908.f6b4048A
Immutable. This exact content is served forever at /api/v1/blob/6703aecd6eb8d5eb.
--- name: aide-pre-push-gate description: The versioned root-level git pre-push gate that enforces AIDE's full verification battery before a feature push. Because `git config core.hooksPath` = repo root, a tracked `pre-push` file at the root is picked up automatically by every clone and push. Set AIDE_FULL_BATTERY=1 to run all arch tests before push (Windows-safe: no --test-force-exit locally, since that flag native-asserts on win32; CI/ubuntu uses scripts/run-arch.mjs). Without the env var the gate stays lightweight (staged .mjs syntax + secret scan parity with pre-commit). Use whenever anyone adds a gate rule, moves the hook, pushes a feature/main slice that must be battery-verified, or CI/push behavior around verification changes. --- # AIDE Versioned Pre-Push Gate — Verified Recipe ## Status: VERIFIED (2026-09-08) - Root-level `pre-push` file at the repo root, versioned in git, auto-picked-up by git because `core.hooksPath` = repo root. - Verified in REAL execution: `git push <bare> main` ran the hook (packed multi-line echo observable), passed, and pushed. Blocking branch proven: a nonzero arch-battery exit -> `error: failed to push some refs`, exit 1. - Full arch battery: **346/346 pass, exit 0** (Windows-safe invocation of the same command the gate runs). ## Why a versioned hook (not .git/hooks) `git config core.hooksPath` is `E:\aide-sovern-workbench` (the repo root) on this machine — so git looks for hooks AT THE ROOT FIRST, falling back to `.git/hooks` when a root-level file is absent. Putting `pre-push` under the root means: - It is tracked -> every clone/push, every developer, enforces the same gate. - It is not lost when `.git` is recreated. - The existing `.git/hooks/pre-commit` and commit-msg are untracked local hooks — do NOT copy them to root; keep them local. ## Behavior matrix | AIDE_FULL_BATTERY | What the gate does | |---|---| | `1` | Full arch battery (all `tests/arch/*.test.ts`). Windows: runs without `--test-force-exit` (native abort trap). Non-Windows: `node scripts/run-arch.mjs`. Fails -> push blocked (exit 1). | | unset / anything else | Lightweight: `node --check` on staged `.mjs` (same syntax check as pre-commit). Always runs, independent of the battery branch. | ## Gate file layout (keep in sync) ```sh #!/bin/sh GIT_ROOT=$(git rev-parse --show-toplevel) # 1. lightweight check: node --check on staged .mjs (always) # 2. if AIDE_FULL_BATTERY = 1: # cd "$GIT_ROOT" # case "$(uname -s)" in # MINGW*|MSYS*|CYGWIN*) # Windows -> battery WITHOUT --test-force-exit # node --experimental-strip-types --no-warnings \ # --import ./scripts/http-close-shim.mjs \ # --test --test-concurrency=1 --test-timeout=240000 \ # $(find tests/arch -name '*.test.ts' | tr '\n' ' ') # ;; # *) node scripts/run-arch.mjs ;; # esac # FAILED -> echo + EXIT=1 # 3. EXIT nonzero -> "checks failed. Fix errors above and try again." + exit 1 ``` Rules: - Always `cd "$GIT_ROOT"` before the battery (relative `find`/node args need the repo as cwd). - The `.mjs` lightweight pass runs regardless of battery branch — orthogonal gates. - Keep the echo contract stable (CI/log greps may rely on `pre-push:` prefixes). - On Windows the hook's `grep/tr/find` resolve because git puts Git for Windows `usr/bin` on PATH when it spawns hooks. Testing the hook directly from PowerShell requires prepending `C:\Program Files\Git\usr\bin` to PATH before running `sh ./pre-push`. ## Verification procedure (reproduce both branches) 1. Lightweight + pickup (fast): ```pwsh git init --bare E:\pip_temp\opencode\pushgate-test.git git push E:\pip_temp\opencode\pushgate-test.git main # observe "pre-push: checks passed" git --git-dir=E:\pip_temp\opencode\pushgate-test.git rev-parse --verify main # == local HEAD ``` 2. Blocking branch (battery forced to fail) — mutate ONLY the Windows branch's first node line to `node -e "process.exit(9)" ...`, push, expect exit 1 + "failed to push some refs", then restore. Never run the real 346/346 battery to prove blocking. 3. Full battery (the gate's actual command) — see aide-closed-loop-wiring. Cleanup after verification: delete the bare repo + any out.log/backup. Set `AIDE_FULL_BATTERY=''` (not just removed) in the test shell or stale env leaks into later pushes. ## Design intent Ordinary pushes stay fast (no battery). Feature/UI pushes opt into full verification via `AIDE_FULL_BATTERY=1`. The gate never silently weakens CI — it defaults to no-op heavy work and enforces hard when asked. The battery's canonical gate remains CI (run-arch.mjs uses `--test-force-exit`, which is correct on ubuntu and native-crashes on win32 — do NOT modify run-arch.mjs for Windows).