Files
felhom-controller/.claude/rules/gates.md
T
admin 3c49dc8ea4
gates / gates (push) Successful in 12s
v0.228.0 — the off-site check reads the data; the debug page stops lying (R-399 + R-400)
R-399: monitoring.integrity.read_data_subset defaults to 100%. A pack damaged
without changing its size made plain `restic check` report "no errors were found"
on demo-hp 2026-08-30; every read-data form caught it. Cost on that 134 MB store:
35.0s structure vs 39.2s at 100%. "off" (any case) is the off token; empty means
not-configured, therefore the default; a malformed value falls back to the DEFAULT,
never to structure. A completed check over 5 minutes logs a WARN naming the
duration, the depth and R-401 — operator log only, no hub event, no depth change.
The depth is now recorded with the verdict (LastIntegrityDepth; empty = NOT
RECORDED, never "structure").

R-400: 24 debug-page references, 17 dispatched, 7 dead — three of which fetched on
page LOAD, so those panels were permanently blank. backup/crossdrive implemented;
backup/infra, hub/infra-push, dr/infra-status, storage/watchdog-status and both
storage/simulate-* deleted with their panels and JavaScript.
scripts/debug_route_gate.py fails in both directions and is registered after the
seven were resolved. 18 referenced, 18 dispatched, none orphaned.

Corrections: the dead-field warning in report/types.go said the controller runs no
integrity check and the notifiers are called from nowhere — both false since
v0.227.0. controller.yaml.example gains its missing integrity: block.
integrityCheckTimeout's "ships OFF" comment rewritten.
2026-08-31 10:24:29 +02:00

3.3 KiB

paths
paths
controller/**/*.go
controller/**/*.html
controller/**/*.css
controller/scripts/**

Gates and logging — felhom-controller

The ONE entry point

Run python3 controller/scripts/controller_gates.py (from controller/) after ANY change in this repo. It runs the local gates — template_id_gate, emoji_gate, native_confirm_gate, offbox_rename_gate, app_row_dedup_gate, mojibake_gate, docker_run_volume_path_gate, secret_in_markup_gate, retrieval_promise_gate, debug_route_gate — plus reuse_refs_check, instructions_gate and observations_gate on the repo root, streaming each gate's own output and exiting non-zero if any fails. The runner's GATES table is the list; this sentence is a pointer to it, not a second copy — it has already drifted once (it said "seven" while nine were registered).

  • --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.
  • The shared reuse_refs_check.py and instructions_gate.py live in felhom.eu/scripts/ and are never copied here — a copy would recreate the drift they detect; an absent sibling clone FAILS.
  • 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 — CI re-runs the same entry point on every push and emails the operator on failure, so a bypass is noticed even though it is not blocked (R-168, CLOSED 2026-08-02).

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: felhom.eu/documentation/runbooks/logging-conventions.md.

Health checks issue no block I/O

A probe that touches a wedged device enters uninterruptible sleep, survives SIGKILL, and cannot be recovered until the device returns or the host reboots — so systemctl restart hangs too. A timeout protects the caller's control flow and nothing else: the blocked thread remains. Liveness is decided from /proc and kernel state, never by reading or writing the filesystem.