chore(config): enforce the parse sweep at the push gate, ahead of the suite

Placed in the pre-push hook rather than /pr-process, because the hook is where
enforcement actually lives — and notably the hook never ran godot-cold-parse
at all, so until now nothing enforced "does this script parse" for any file
outside the startup path.

Ordered BEFORE the test suite deliberately. That makes failures cheaper rather
than the gate slower: a script that does not parse is caught in ~4s instead of
after ~135s of tests that could never have covered it. A clean push pays 3.7s;
a broken one saves over two minutes.

Not redundant with the suite. gdUnit4 reports the suites that DID load as a
clean pass, so an unparseable file reads as success — guarded now in
tests/run-godot, but only for test files. The sweep covers all 226 scripts,
including the roughly half of the codebase no test ever loads.

/pr-process gains a scope note instead of a second invocation: cold-parse sees
only the startup path and filters "Cannot infer the type" (which hid a
genuinely broken file for five months), so it must not be read as a general
parse check. Per team-patterns.md the skill does not duplicate the gate.

Hooks run from .config/hooks via core.hooksPath, so this is live without an
install step.

Pair session with Jeroen, 2026-07-27.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-27 00:42:19 +02:00
co-authored by Claude
parent a005e48405
commit bf1976613f
2 changed files with 38 additions and 0 deletions
+15
View File
@@ -123,6 +123,21 @@ always an autoload-order issue (see `CLAUDE.md` → GDScript conventions →
Autoload parse-order rule) — fix the ordering, don't just rebuild the cache
to mask it locally (the same error resurfaces post-merge).
**Scope, so you don't over-trust it:** `godot-cold-parse` only ever sees
scripts on the **startup path** — autoloads and the main scene chain. That is
exactly right for the registration-ORDER bug it exists to catch, and far
narrower than the name suggests: it reports `clean` for a syntactically
broken UI script or test file that startup never loads (verified 2026-07-27
by breaking one of each). It also filters `"Cannot infer the type"`, which
hid a genuinely unparseable file for five months.
**"Does every script parse?" is a different question, and the pre-push hook
now answers it** — `tooling/godot-parse-sweep` opens all ~226 project scripts
and blocks the push on any that don't, running *before* the test suite so a
parse failure costs 4s instead of 135s. It is enforced by the gate, so do
**not** run it here as well (`team-patterns.md`: don't duplicate the push
gate). Run it manually only when you want that answer early.
Any lines it reports are new errors introduced by this branch. Fix them
before pushing.
+23
View File
@@ -75,6 +75,29 @@ if [ "$CLIENT_CHANGED" -gt 0 ] && command -v gdformat >/dev/null 2>&1 && [ -d "$
fi
fi
# --- GDScript parse sweep — blocking, and deliberately BEFORE the suite ---
# Every project .gd must parse. ~3.7s against the suite's ~135s, and it runs
# first because that ordering makes failures CHEAPER, not the gate slower: a
# script that does not parse is now caught in 4s instead of after two minutes
# of tests that could never have covered it. A clean push pays 3.7s; a broken
# one saves over two minutes.
#
# Not redundant with the suite. gdUnit4 reports the suites that DID load as a
# clean pass, so a file that fails to parse reads as success (guarded now in
# tests/run-godot, but only for test files). This covers all 226 scripts,
# including the ~half of the codebase no test ever loads. It is also the only
# gate that covers them at all: godot-cold-parse is skill-only (never invoked
# by this hook) and sees only the startup path regardless.
if [ "$CLIENT_CHANGED" -gt 0 ] && [ -x "$REPO_ROOT/tooling/godot-parse-sweep" ]; then
echo "pre-push: sweeping GDScript parse (tooling/godot-parse-sweep)..."
if ! "$REPO_ROOT/tooling/godot-parse-sweep"; then
echo "pre-push: parse sweep FAILED — a script does not parse"
ERRORS=$((ERRORS + 1))
else
echo "pre-push: parse sweep — OK"
fi
fi
# --- Godot client test suite (gdUnit4) — blocking (T-1065) ---
# The push gate is the only automatic verification (no CI). The suite is
# ~100s, 300s-capped, and was made fully green by the T-973 debt clearance;