gates: one entry point (controller/scripts/controller_gates.py) + pre-push hook

A census of all thirteen gate scripts across the four felhom repos on 2026-08-02 found that
every check a CLAUDE.md names was passing and two of the four nobody is told to run were
failing. This repo had seven gates and CLAUDE.md named two; four more were reachable only via
a line in REUSE.md, and docker_run_volume_path_gate.py — RED at census time — through one line
in REUSE.md and nothing else.

controller_gates.py runs all seven plus reuse_refs_check on the repo root, streams each gate's
own output, and exits worst-wins non-zero. The shared reuse checker stays in felhom.eu/scripts/
and is invoked across the workspace — never copied here, which would recreate the drift it
detects; an absent sibling clone FAILS the gate and prints the path tried.

.githooks/pre-push runs it with --fast and refuses the push. Per-clone and --no-verify-able,
both stated in the hook itself; a manual run WARNS when the clone is unarmed.

test_controller_gates.py is a SEAM test — it asserts each member gate's own distinctive stdout,
not the runner's summary line. Red-proofed: an inert run_gate still prints 'all controller
gates OK' and exits 0, and turns the seam test red.

Tooling only: no Go change, no image build, no deploy, no version bump.
This commit is contained in:
2026-08-02 15:22:53 +02:00
parent c432f701dd
commit 8cb3d7af91
4 changed files with 267 additions and 2 deletions
+17 -2
View File
@@ -84,8 +84,23 @@ Per-package helpers/seams/traps: **`REUSE.md`** (maintained same-commit as helpe
are implemented during the supervised session itself, on `main`; if a fix can't be verified/shipped,
revert + report — never park on a branch.
- Code quality: double-check for bugs/edge cases; add debug logging; **ask rather than guess**.
- All UI text is Hungarian (Budapest timezone). Design tokens/gates: use the `felhom-ui-design`
skill; templates must pass `controller/scripts/template_id_gate.py` + `emoji_gate.py`.
- All UI text is Hungarian (Budapest timezone). Design tokens/gates: use the `felhom-ui-design` skill.
- **Run `python3 controller/scripts/controller_gates.py` (from `controller/`) after ANY change in
this repo.** It is the ONE entry point and runs all seven local gates — `template_id_gate`,
`emoji_gate`, `native_confirm_gate`, `offbox_rename_gate`, `app_row_dedup_gate`, `mojibake_gate`,
`docker_run_volume_path_gate` — plus `reuse_refs_check` on the repo root, streaming each gate's
own output and exiting non-zero if any fails. `--fast` selects the gates that touch no network and
no container runtime; today that is all of them. A missing gate script is a FAILURE, never a skip.
**Why a runner and not seven invocations** (2026-08-02, R-29): a census of all thirteen gates
across the four repos found that every check a `CLAUDE.md` names was passing, and two of the four
nobody is told to run were failing. This file used to name two of the seven; the other five were
reachable only through a line in `REUSE.md`, and `docker_run_volume_path_gate.py` was RED.
**The shared `reuse_refs_check.py` lives in `felhom.eu/scripts/` and is never copied here**
a copy would recreate the drift it detects; an absent sibling clone FAILS the gate.
**The pre-push hook** (`.githooks/pre-push`) runs it with `--fast` and refuses a failing push. It
is per-clone — switch it on once with `git config core.hooksPath .githooks`, and a manual run
WARNS when this clone is unarmed. `git push --no-verify` bypasses it deliberately; **say so in the
session report when you use it.** Both facts are why CI is still owed (`OPEN-ITEMS.md` R-168).
- Testing doctrine (non-hollow tests, red-proofs, seams): use the `felhom-testing` skill.
- **Logging**: new leveled lines use `internal/logx` (DEBUG always reaches the debug ring; stdout
respects `logging.level`); English, keys-never-values, durations on outcomes — full rules in