3c49dc8ea4
gates / gates (push) Successful in 12s
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.
57 lines
3.3 KiB
Markdown
57 lines
3.3 KiB
Markdown
---
|
|
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).
|
|
|
|
<!--
|
|
WHY A RUNNER AND NOT SEVEN INVOCATIONS (2026-08-02, R-29) — rationale, not a directive.
|
|
A census of all thirteen gates across the four repos found that every check a CLAUDE.md named was
|
|
passing, and two of the four nobody is told to run were failing. This repo's CLAUDE.md 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 single-entry-point shape is the only one that
|
|
demonstrably gets run. app-catalog-felhom.eu/scripts/catalog_gates.py is the canonical version of
|
|
the runner (R-161); repo_gates.py copies it. site_gates.py is a *gate*, not a runner — do not model
|
|
new work on it.
|
|
-->
|
|
|
|
## 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.
|
|
|
|
<!--
|
|
Measured, R-117 spike §6.3 (felhom.eu/documentation/audits/SPIKE-r117-bind-liveness-2026-07-30.md):
|
|
a probe stayed in D state 3m50s after kill -9; a buffered write with no fsync blocked too (O_CREAT
|
|
needs journal access); and statfs/getdents returned HEALTHY on a namespace that EIOs every byte —
|
|
fast, and wrong.
|
|
-->
|