|
| 1 | +#!/usr/bin/env bash |
| 2 | +# SPDX-License-Identifier: MPL-2.0 |
| 3 | +set -uo pipefail |
| 4 | +# |
| 5 | +# Wave-0 "kill the false green" regression test. |
| 6 | +# |
| 7 | +# Every validator fixed in Wave 0 must be able to FAIL — a check that cannot |
| 8 | +# fail is not a check. This exercises each one's success AND failure path so a |
| 9 | +# future regression that reintroduces a vacuous pass is caught here. |
| 10 | +# |
| 11 | +# Covers: |
| 12 | +# * a2ml/scripts/check-6scm.sh (obsolete no-op / orphan drift / out-of-sync) |
| 13 | +# * scripts/check-mustfile-structure.sh (valid Mustfile / hollow check) |
| 14 | +# * rhodium-standard-repositories/rsr-audit.sh (bad format exits 4 / --format json works) |
| 15 | +# * audit-contractiles.sh (loud error on zero repos) |
| 16 | + |
| 17 | +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" |
| 18 | +TMP="$(mktemp -d)" |
| 19 | +trap 'rm -rf "$TMP"' EXIT |
| 20 | + |
| 21 | +pass=0 fail=0 |
| 22 | +ok() { echo " ✅ $1"; pass=$((pass + 1)); } |
| 23 | +bad() { echo " ❌ $1"; fail=$((fail + 1)); } |
| 24 | +# expect <wanted-code> <actual-code> <label> |
| 25 | +expect() { if [ "$2" -eq "$1" ]; then ok "$3 (exit $2)"; else bad "$3 (wanted $1, got $2)"; fi; } |
| 26 | + |
| 27 | +echo "== check-6scm.sh ==" |
| 28 | +SIX="$ROOT/a2ml/scripts/check-6scm.sh" |
| 29 | +# (1) obsolete no-op: no sources, no mirror -> exit 0 |
| 30 | +w="$TMP/six-obsolete"; mkdir -p "$w/.machine_readable/6a2"; cp "$SIX" "$w/check.sh" |
| 31 | +( cd "$w" && bash check.sh >/dev/null 2>&1 ); expect 0 $? "obsolete no-op passes" |
| 32 | +# (2) orphan drift: mirror files but no sources -> exit 1 |
| 33 | +w="$TMP/six-orphan"; mkdir -p "$w/.machine_readable/6scm"; echo x > "$w/.machine_readable/6scm/STATE.scm"; cp "$SIX" "$w/check.sh" |
| 34 | +( cd "$w" && bash check.sh >/dev/null 2>&1 ); expect 1 $? "orphan-mirror drift fails" |
| 35 | +# (3) out-of-sync: source present, mirror differs -> exit 1 |
| 36 | +w="$TMP/six-desync"; mkdir -p "$w/.machine_readable/6scm" |
| 37 | +printf 'a\n' > "$w/.machine_readable/STATE.scm"; printf 'b\n' > "$w/.machine_readable/6scm/STATE.scm"; cp "$SIX" "$w/check.sh" |
| 38 | +( cd "$w" && bash check.sh >/dev/null 2>&1 ); expect 1 $? "out-of-sync mirror fails" |
| 39 | +# (4) in-sync: source present, mirror identical -> exit 0 |
| 40 | +w="$TMP/six-sync"; mkdir -p "$w/.machine_readable/6scm" |
| 41 | +printf 'a\n' > "$w/.machine_readable/STATE.scm"; printf 'a\n' > "$w/.machine_readable/6scm/STATE.scm"; cp "$SIX" "$w/check.sh" |
| 42 | +( cd "$w" && bash check.sh >/dev/null 2>&1 ); expect 0 $? "in-sync mirror passes" |
| 43 | + |
| 44 | +echo "== check-mustfile-structure.sh ==" |
| 45 | +MS="$ROOT/scripts/check-mustfile-structure.sh" |
| 46 | +# valid: the repo's real Mustfile -> exit 0 |
| 47 | +bash "$MS" "$ROOT/.machine_readable/contractiles/must/Mustfile.a2ml" >/dev/null 2>&1 |
| 48 | +expect 0 $? "real Mustfile is structurally valid" |
| 49 | +# hollow: a check with neither run nor verification -> exit 1 |
| 50 | +hf="$TMP/hollow.a2ml"; printf '### hollow\n- description: nothing runnable\n- severity: high\n' > "$hf" |
| 51 | +bash "$MS" "$hf" >/dev/null 2>&1; expect 1 $? "hollow check fails" |
| 52 | +# governance: a check with verification (no run) is accepted -> exit 0 |
| 53 | +gf="$TMP/gov.a2ml"; printf '### gov\n- description: manual\n- verification: reviewed by owner\n- severity: high\n' > "$gf" |
| 54 | +bash "$MS" "$gf" >/dev/null 2>&1; expect 0 $? "verification-only check accepted" |
| 55 | +# missing file -> exit 2 |
| 56 | +bash "$MS" "$TMP/nope.a2ml" >/dev/null 2>&1; expect 2 $? "missing Mustfile errors" |
| 57 | + |
| 58 | +echo "== rsr-audit.sh (standards#387 arg parsing) ==" |
| 59 | +RSR="$ROOT/rhodium-standard-repositories/rsr-audit.sh" |
| 60 | +# bad format -> exit 4 (no longer silently defaults to text) |
| 61 | +bash "$RSR" . --format xml >/dev/null 2>&1; expect 4 $? "invalid --format errors loudly" |
| 62 | +# documented --format json now produces JSON. Capture first: rsr-audit's exit |
| 63 | +# code encodes the grade (non-zero for < Gold), so piping into grep under |
| 64 | +# `pipefail` would mask a successful match — assert on the captured text. |
| 65 | +json_out="$(bash "$RSR" . --format json 2>/dev/null || true)" |
| 66 | +case "$json_out" in |
| 67 | + *'"compliance_level"'*) ok "--format json emits JSON report" ;; |
| 68 | + *) bad "--format json did not emit JSON" ;; |
| 69 | +esac |
| 70 | +# bare positional 'text' (Justfile backward-compat) still works: grade code 0-3 |
| 71 | +bash "$RSR" . text >/dev/null 2>&1; rc=$? |
| 72 | +if [ "$rc" -ge 0 ] && [ "$rc" -le 3 ]; then ok "bare positional 'text' returns a grade code ($rc)"; else bad "bare positional 'text' returned $rc"; fi |
| 73 | + |
| 74 | +echo "== audit-contractiles.sh ==" |
| 75 | +AC="$ROOT/audit-contractiles.sh" |
| 76 | +# Runs against an explicit repo path with no hardcoded owner (/var/mnt/...) paths. |
| 77 | +# Capture the output first (avoid pipefail masking the script's own exit code). |
| 78 | +ac_out="$(bash "$AC" "$ROOT" 2>&1 || true)" |
| 79 | +case "$ac_out" in |
| 80 | + *"Contractile System Audit"*) ok "runs against an explicit repo path (no hardcoded owner paths)" ;; |
| 81 | + *) bad "did not run against explicit repo path" ;; |
| 82 | +esac |
| 83 | +# No hardcoded owner path is USED (a quoted absolute /var/mnt/... array element); |
| 84 | +# a prose mention in a comment is fine, an actual code path is not. |
| 85 | +if grep -qE '^[[:space:]]*"/var/mnt/' "$AC"; then |
| 86 | + bad "hardcoded owner path still used in code" |
| 87 | +else |
| 88 | + ok "no hardcoded owner path used in code" |
| 89 | +fi |
| 90 | + |
| 91 | +echo |
| 92 | +echo "Wave-0 false-green regression: $pass passed, $fail failed" |
| 93 | +[ "$fail" -eq 0 ] |
0 commit comments