#!/usr/bin/env bash
# tests/render-drift/run-tests.sh
#
# R9's RULED render-drift gate (D-119 AMENDMENT, 2026-07-27): "a render-drift check that
# fails the gauntlet on divergence", mirroring the D-137 creds-manifests derive-plus-drift
# pattern already proven in this repo.
#
# WHY IT EXISTS: until 2026-07-29 the ONLY byte-compare in the tree targeted the dc1
# overlay. dc0's -- the artifact `scripts/preflight.sh` P2 actually feeds to the deploy
# gate -- was reproducible by nobody, and `render/values/` was referenced by ZERO scripts
# and ZERO harnesses. A chain audit executed two wrong-but-green attacks straight through
# that hole: hand-transposing two apps' octets in the dc0 overlay, and flipping ONE WORD
# (`family: dual` -> `v4`) to silently de-dual-stack dc0 against R2's ruling. Both passed
# every gate. This closes that class for every values file, present and future.
#
# It iterates render/values/*.yaml, so a NEW per-DC values file is gated the moment it is
# committed -- no harness edit required.
#
# Exit: 0 all pass | 1 any drift.  ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO="$(cd "$HERE/../.." && pwd)"
R="$REPO/scripts/render-dc-overlays.py"
VALDIR="$REPO/render/values"
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
PASS=0; FAIL=0
ok()  { echo "  PASS  $1"; PASS=$((PASS+1)); }
bad() { echo "  FAIL  $1"; FAIL=$((FAIL+1)); }

echo "== render-drift: every committed values file still renders its committed overlay =="

[ -d "$VALDIR" ] || { echo "  FAIL  render/values/ missing"; echo "RESULT: PASS=0 FAIL=1"; exit 1; }
n=0
for v in "$VALDIR"/*.yaml; do
  [ -e "$v" ] || continue
  n=$((n+1))
  rel="${v#$REPO/}"
  # The values file NAMES its own output; that field was inert until now.
  out="$(python3 -c "import yaml,sys;print(yaml.safe_load(open(sys.argv[1])).get('output',''))" "$v" 2>/dev/null)"
  if [ -z "$out" ]; then bad "$rel declares no output: path"; continue; fi
  tgt="$REPO/$out"
  if [ ! -r "$tgt" ]; then bad "$rel -> $out (target missing)"; continue; fi
  if python3 "$R" check "$v" --against "$tgt" >"$TMP/d" 2>&1; then
    ok "$rel renders $out byte-for-byte"
  else
    bad "$rel DRIFTED from $out -- re-render, do not hand-edit the overlay"
    sed 's/^/        /' "$TMP/d" | head -8
  fi
done
# A zero-floor: an empty values dir must not read as a clean gate.
if [ "$n" -eq 0 ]; then bad "no values files found -- a drift gate over zero files is not a gate"; else ok "$n values file(s) checked (non-zero floor)"; fi

# PROVEN ABLE TO FAIL: tamper with a COPY and require the same check to go red. A drift
# gate only ever observed passing is exactly what this file exists to replace.
probe="$(ls -1 "$VALDIR"/*.yaml 2>/dev/null | head -1)"
if [ -n "$probe" ]; then
  cp "$probe" "$TMP/t.yaml"
  python3 - "$TMP/t.yaml" <<'PY'
import sys, yaml
v = yaml.safe_load(open(sys.argv[1]))
v["apps"][0]["octet"] = int(v["apps"][0]["octet"]) + 40   # in-band, unique, plausible
yaml.safe_dump(v, open(sys.argv[1], "w"), sort_keys=False, width=4096)
PY
  out="$(python3 -c "import yaml,sys;print(yaml.safe_load(open(sys.argv[1]))['output'])" "$probe")"
  if python3 "$R" check "$TMP/t.yaml" --against "$REPO/$out" >/dev/null 2>&1; then
    bad "PROOF-OF-TEETH: a mutated values file still matched -- this gate cannot fail"
  else
    ok "PROOF-OF-TEETH: a mutated values file is detected"
  fi
fi

echo
echo "RESULT: PASS=$PASS FAIL=$FAIL"
[ "$FAIL" -eq 0 ] && { echo "ALL PASS"; exit 0; } || exit 1
