# wall-watch — presence alert for the mirror wall Runs on the **mirror server host**, not on the kiosk. Once a minute it reads the service's own `/healthz` and pages you over ntfy when nobody is watching, or when the service stops answering — and tells you when the wall comes back. Rationale and the incident that produced it: [`../kiosk-silverblue.md`](../kiosk-silverblue.md) → *"The wall went quiet and nobody noticed"*. ## Install (on the server host) ```bash scp -r docs/wall-watch server:/var/tmp/ && ssh server \ 'cd /var/tmp/wall-watch && sudo sh install-wall-watch.sh' sudo vi /etc/mirror-wall-watch.env # set NTFY_TOKEN ``` ## Operate ```bash systemctl status mirror-wall-watch.timer # is it still ticking? journalctl -u mirror-wall-watch.service -f # one line per check, forever sudo sh /usr/local/libexec/mirror-wall-watch.sh # run it by hand # Page yourself on purpose, without touching the wall's real state. WALL_DRILL=1 # makes the notification say "[drill]" and drop to priority 3, so a test can never # be mistaken for an outage: sudo sh -c '. /etc/mirror-wall-watch.env; WALL_DRILL=1 WALL_HEALTH_URL=https://127.0.0.1/nope \ WALL_THRESHOLD=1 WALL_STATE_DIR=/tmp/wall-watch-test \ sh /usr/local/libexec/mirror-wall-watch.sh' ``` ## Files | File | Lands at | |---|---| | `wall-watch.sh` | `/usr/local/libexec/mirror-wall-watch.sh` | | `mirror-wall-watch.service` / `.timer` | `/etc/systemd/system/` | | `wall-watch.env.example` | `/etc/mirror-wall-watch.env` (0600, seeded once, never overwritten) | | everything here | `/usr/local/share/mirror-wall-watch/` | ## Deliberate choices - **Probes `/healthz` over loopback**, because that endpoint is exempt from the address gate — the same exemption that lets the container healthcheck work from loopback when `MIRROR_ALLOW_CIDRS` excludes it. - **First run cannot alert.** Installing a watcher must not page you about a wall that was already down before you had one. - **A failed notification fails the unit** and does *not* bank the re-notify timestamp, so an ntfy outage is retried on the next tick instead of eating the alert. - **A drill is labelled as one.** `WALL_DRILL=1` prefixes the title with `[drill]`, lowers the priority and says "nothing is wrong" in the body. A test page that is indistinguishable from an incident teaches people to ignore the page. - **It cannot detect the server being down.** It lives there. That gap belongs to whatever monitors this host.