#!/usr/bin/env bash # verify.sh — read-only drift detection (§5.3, §5.8). # # Runs as the operator account, never root: almost everything here is # user-scoped, and as root it would read root's configuration and report # confidently on the wrong user. # # Reports PASS / FAIL / SKIP. Only one assertion may SKIP; every other one # that cannot run is a FAIL. A run that skipped everything must NOT look # healthy — that is the cheapest possible way to disable this whole layer. set -uo pipefail cd "$(dirname "$0")" || exit 1 # This script is entered three ways — over ssh from phase_11_verify() (a # non-login shell), from the verify systemd timer (no shell profile at all), # and by hand — and the first two never reach the `mise activate` line at the # end of ~/.bashrc: Ubuntu's ~/.bashrc returns on its first line when the # shell is not interactive. mise, rustup, pnpm, claude and pass-cli all live # behind that PATH, and so does the pnpm binary the store-dir check below # shells out to. Set it explicitly instead of hoping an rc file does, # matching the PATH job-wrapper.sh and 20-toolchains.sh's as_user() already # build for the same reason (§13.2, environment). export PATH="$HOME/.local/bin:$HOME/.local/share/mise/shims:$HOME/.cargo/bin:$HOME/.local/share/pnpm/bin:$PATH" # shellcheck source=lib/common.sh source lib/common.sh # for vault_get, used by the backup-escrow section below; # also sets FLIT_NAME and FLIT_USER # shellcheck source=lib/jobs.sh source lib/jobs.sh # the committed table the timers section below loops over : "${NO_EXTERNAL_STATE:=0}" # set by drills; relaxes timer-enabled assertions : "${FLIT_USER:=dev}" # the operator account; bootstrap.sh passes this # over ssh, and this is the fallback for runs # triggered locally by the verify timer P=0; F=0; S=0 declare -a FAILED=() SKIPPED=() pass() { printf ' PASS %s\n' "$1"; P=$((P+1)); } fail() { printf ' FAIL %s — %s\n' "$1" "${2:-}"; F=$((F+1)); FAILED+=("$1"); } # skip() is deliberately available to only one call site (see §5.3). skip() { printf ' SKIP %s — %s\n' "$1" "${2:-}"; S=$((S+1)); SKIPPED+=("$1"); } # check — non-skippable by construction: # if the command cannot run, that is a FAIL, not a SKIP. check() { local name=$1 expected=$2; shift 2 local actual if ! actual=$("$@" 2>&1); then fail "$name" "could not evaluate: ${actual:0:120}" return fi [[ "$actual" == "$expected" ]] && pass "$name" \ || fail "$name" "expected '$expected', got '${actual:0:80}'" } check_true() { local name=$1; shift if "$@" >/dev/null 2>&1; then pass "$name"; else fail "$name" "command reported false"; fi } # tmux_conf_value