Library
REF 09 Cheat Sheet · Reference

Granular check pattern

Independent assertions, each with its own remediation message. Turns a failed Check button into actionable feedback rather than a generic "something is wrong."

Anatomy Skeleton — copy and adapt
#!/bin/bash set -euo pipefail # Each assertion is independent. Specific fail message points # the learner at the exact next thing to do. if ! getent passwd analyst >/dev/null; then fail-message "User 'analyst' does not exist. Run: createuser analyst" exit 1 fi if [[ "$(id -u analyst)" == "0" ]]; then fail-message "User 'analyst' is a superuser. It must not be." exit 1 fi if ! psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='analyst' AND rolcanlogin" | grep -q 1; then fail-message "User 'analyst' cannot log in. Run: ALTER USER analyst WITH LOGIN;" exit 1 fi set-status "User analyst exists, is non-superuser, and can log in." exit 0
Auto-counted assertions Progress fraction

Count fail-message calls in the script and prefix each with [Check N/$TOTAL].

TOTAL=$(grep -Ec \ "\bfail-message\b" "$0") COUNT=0 next() { COUNT=$((COUNT+1)); } next; if ! cond_a; then fail-message \ "[Check $COUNT/$TOTAL] Reason..." exit 1 fi # ... repeat ...
Live-truth check Re-execute, compare

Don't hardcode the expected answer. Re-run the same query the learner ran and compare to their submitted value.

EXPECTED=$(psql -tAc \ "SELECT count(*) FROM orders \ WHERE status='pending'") SUBMITTED=$(cat /tmp/answer) if [[ "$EXPECTED" != "$SUBMITTED" ]]; then fail-message \ "Got $SUBMITTED, expected $EXPECTED." exit 1 fi
Side-effect-triggering Visible failure

On first failure, perform a visible action so the learner gets something concrete to observe rather than an opaque "wrong."

if ! curl -fsS \ http://api/health >/dev/null; then echo "API not reachable — sending" echo "a debug request to surface" echo "the upstream error:" curl -v http://api/health || true fail-message "API is not running. Start it with: ./start-api.sh" exit 1 fi
Trap-based cleanup For checks that provision

When a check must create temporary state to validate (a session, an environment), trap to guarantee teardown on every exit path.

cleanup() { rm -f /tmp/check-* ; } trap cleanup EXIT # idempotent re-create ctm env delete check-env \ >/dev/null 2>&1 || true ctm env add check-env "$URL" \ "$TOKEN" # ... assertions follow ...
Anti-patterns