feat: add pos system health, lib/notify.sh, and daily Telegram digest timer

- bin/pos-system-health: host dashboard (disk, RAM, failed units, backup age,
  fail2ban, docker); exits 1 on any FAIL; --send/--markdown via Telegram
- lib/notify.sh: self-contained opt-in alerting helper; silent-fails, wired
  into pos-system-backup (success + ERR trap) and pos-system-firewall
- systemd/pos-health.{service,timer}: 08:00 digest as installing user;
  postinstall enables timer once telegram.env exists, now copies *.timer
- AGENT_TODO.md: worklist with Now/Next/Later/Done history; linked from AGENTS.md
This commit is contained in:
Your Name
2026-08-06 02:25:23 -04:00
parent cf36780c0f
commit 9a94329dd0
16 changed files with 460 additions and 22 deletions
+32 -3
View File
@@ -5,6 +5,7 @@ The units installed and enabled by `postinstall.sh`, plus the `pos` bash complet
- [Services](#services)
- [`autostart.service`](#autostartservice)
- [`ssh-agent.service`](#ssh-agentservice)
- [`pos-health.service`](#pos-healthservice)
- [Feature-flag gating](#feature-flag-gating)
- [Bash completion](#bash-completion)
@@ -12,7 +13,7 @@ The units installed and enabled by `postinstall.sh`, plus the `pos` bash complet
## Services
`postinstall.sh` copies every `systemd/*.service` to `/etc/systemd/system/`, runs `systemctl daemon-reload`, then enables each one (see the gating rule below).
`postinstall.sh` copies every `systemd/*.service` (and `systemd/*.timer`) to `/etc/systemd/system/`, runs `systemctl daemon-reload`, then enables each one (see the gating rule below).
### autostart.service
@@ -59,20 +60,48 @@ WantedBy=multi-user.target
**Configuration:** socket at `/run/ssh-agent/socket` (world-readable/writable). `~/.bashrc` (set by `postinstall.sh`) exports `SSH_AUTH_SOCK` to it. Not gated on any feature flag.
### pos-health.service
**Purpose:** daily "health digest" — runs `pos system health --send --markdown` at 08:00 and sends the report to Telegram.
```ini
[Unit]
Description=POS Health digest (daily report via Telegram)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=__POS_USER__
ExecStart=/usr/local/bin/pos system health --send --markdown
[Timer]
OnCalendar=*-*-* 08:00:00
Persistent=true
```
The service is `Type=oneshot` and is driven **only** by its companion `pos-health.timer` (`WantedBy=timers.target`); the service itself is never enabled directly.
**Configuration:** `postinstall.sh` substitutes `__POS_USER__` with the installing user (`${SUDO_USER:-$USER}`) so the digest uses that user's real Telegram config. The timer is enabled only when `~/.config/linux_post_install/telegram.env` already exists — otherwise postinstall warns and skips; re-run postinstall after configuring Telegram (`pos communication telegram config set TELEGRAM_*`) to install it.
---
## Feature-flag gating
The systemd loop in `postinstall.sh` special-cases `autostart.service`:
The systemd loop in `postinstall.sh` special-cases two units:
```bash
if [ "$svc_name" = "autostart.service" ] && ! flag_is_set autostart; then
warn "autostart feature not installed — skipping autostart.service (run ./install.sh --feature)"
continue
fi
if [ "$svc_name" = "pos-health.service" ]; then
# substitute User= and enable pos-health.timer only if Telegram is configured
fi
```
Set the flag with `./install.sh --feature` (or `flag-set autostart`). See [SCRIPTS.md → lib/flags.sh](SCRIPTS.md#libflagssh--feature-flags).
- `autostart.service` is **enabled** only when the `autostart` feature flag is set (`./install.sh --feature` or `flag-set autostart`). See [SCRIPTS.md → lib/flags.sh](SCRIPTS.md#libflagssh--feature-flags).
- `pos-health.service` is **not** enabled at all — `postinstall.sh` enables `pos-health.timer` instead, and only when a Telegram config already exists.
---