#!/usr/bin/env bash
set -euo pipefail
umask 077
E="/home/cube/projects/richard/traning coach/.omo/evidence/task26/task26-certification-deployment-4a8627af8f9b931d537e17dbd3e357b7a0f2b2abffdbf28f6ad19a8d32893ec0-v2-st_01a00b39"
C="/home/cube/projects/richard/traning coach/.omo/evidence/task26/task26-token-rotation-successor-4a8627af8f9b931d537e17dbd3e357b7a0f2b2abffdbf28f6ad19a8d32893ec0"
R="/home/cube/projects/richard/hermes-agent"; P="/home/cube/.hermes/profiles/dualcoachtest"; S="$P/workspace/checkin_cli"
PY="$R/.venv/bin/python"; W="$C/artifacts/physique_checkin_cli-0.1.0-py3-none-any.whl"; D="4a8627af8f9b931d537e17dbd3e357b7a0f2b2abffdbf28f6ad19a8d32893ec0"
mkdir -p "$E/artifacts" "$E/receipts"; chmod 700 "$E" "$E/artifacts" "$E/receipts"
record(){
 local n="$1";shift;local o="$E/artifacts/$n" s e rc;mkdir -p "$o";chmod 700 "$o";printf '%q ' "$@">"$o/command.txt";echo>>"$o/command.txt";env -0|sort -z>"$o/launcher-environment.nul";date -u +%Y-%m-%dT%H:%M:%S.%NZ>"$o/started-at-utc.txt";s=$(date +%s%N);set +e;"$@">"$o/stdout.txt" 2>"$o/stderr.txt";rc=$?;set -e;e=$(date +%s%N);date -u +%Y-%m-%dT%H:%M:%S.%NZ>"$o/ended-at-utc.txt";echo "$rc">"$o/exit-code.txt";echo "$(((e-s)/1000000))">"$o/duration-ms.txt";(cd "$o"&&sha256sum command.txt launcher-environment.nul started-at-utc.txt ended-at-utc.txt exit-code.txt duration-ms.txt stdout.txt stderr.txt>files.sha256);chmod 600 "$o"/*;return "$rc"
}
snapshot(){
 local x="$1";sha256sum "$P/customers/registry.json" "$P/data/onboarding/telegram-customer-bootstrap-v1/ledger.json">"$E/artifacts/customer-authority-$x.sha256";find "$P/data/customers/task26_live_2e_r2_20260815_8527916639" -type f ! -name '*.lock' -print0|sort -z|xargs -0 sha256sum>"$E/artifacts/customer-tree-$x.sha256";find "$S/checkin_cli" -type f -name '*.py' -print0|sort -z|xargs -0 sha256sum>"$E/artifacts/profile-package-$x.sha256";systemctl --user show hermes-gateway-dualcoachtest.service -p ActiveState -p SubState -p MainPID -p Result>"$E/artifacts/service-$x.txt"
 "$PY" - "$P">"$E/artifacts/live-state-$x.json" <<'PY'
import json,sys
from pathlib import Path
p=Path(sys.argv[1]);r=json.loads((p/'customers/registry.json').read_text());b=json.loads((p/'data/onboarding/telegram-customer-bootstrap-v1/ledger.json').read_text());z=json.loads((p/'data/customers/task26_live_2e_r2_20260815_8527916639/nutrition-onboarding/readiness-receipt-v1.json').read_text());c=next(x for x in r['customers'] if x['customer_key']=='task26_live_2e_r2_20260815_8527916639');s=next(x for x in b['sessions'] if x['generation']==5);print(json.dumps({'customer_enabled':c['enabled'],'adaptive_activation':z['activation_enabled'],'adaptive_delivery':z['delivery_enabled'],'bootstrap_generation':s['generation'],'bootstrap_state':s['state']},sort_keys=True,separators=(',',':')))
PY
}
case "${1:-}" in
 baseline)
  snapshot before;sha256sum "$C/candidate-manifest.json" "$C/hash-inventory.json" "$C/bindings/source-delta.json" "$W">"$E/artifacts/candidate-pins-before.sha256";record candidate-baseline-verify "$PY" "$C/verify_candidate.py" "$C";;
 gate18)
  record gate18-candidate-verify "$PY" "$C/verify_candidate.py" "$C"
  record gate18-source-wheel-parity "$PY" - "$S" "$W" "$D" <<'PY'
import hashlib,json,sys,zipfile
from pathlib import Path
s,w,d=Path(sys.argv[1]),Path(sys.argv[2]),sys.argv[3];ps=['checkin_cli/customer_admin.py','checkin_cli/activation_token_rotation_policy.py'];rows=[]
with zipfile.ZipFile(w) as z:
 for p in ps:
  a=(s/p).read_bytes();b=z.read(p);rows.append({'path':p,'source_sha256':hashlib.sha256(a).hexdigest(),'wheel_sha256':hashlib.sha256(b).hexdigest(),'byte_identical':a==b})
o={'candidate_digest':d,'modules':rows,'status':'PASS' if all(x['byte_identical'] for x in rows) else 'FAIL'};print(json.dumps(o,sort_keys=True,separators=(',',':')));raise SystemExit(o['status']!='PASS')
PY
  record gate18-golden bwrap --die-with-parent --unshare-net --ro-bind / / --bind "$E" "$E" --tmpfs /tmp --dev /dev --proc /proc --setenv HOME /tmp --setenv TMPDIR /tmp --setenv PYTHONDONTWRITEBYTECODE 1 --chdir "$S" "$PY" -B -W error -m pytest -q -p no:cacheprovider --junitxml="$E/artifacts/gate18-golden.junit.xml" tests/test_customer_admin.py -k activation_token_rotation_waiver;;
 gate19)
  record gate19-predecessor bwrap --die-with-parent --unshare-net --ro-bind / / --bind "$E" "$E" --ro-bind "$C/source-delta/before/checkin_cli/customer_admin.py" "$S/checkin_cli/customer_admin.py" --ro-bind "$C/source-delta/before/tests/test_customer_admin.py" "$S/tests/test_customer_admin.py" --tmpfs /tmp --dev /dev --proc /proc --setenv HOME /tmp --setenv TMPDIR /tmp --setenv PYTHONDONTWRITEBYTECODE 1 --chdir "$S" "$PY" -B -W error -m pytest -q -p no:cacheprovider --junitxml="$E/artifacts/gate19-predecessor.junit.xml" tests/test_customer_admin.py
  record gate19-successor bwrap --die-with-parent --unshare-net --ro-bind / / --bind "$E" "$E" --tmpfs /tmp --dev /dev --proc /proc --setenv HOME /tmp --setenv TMPDIR /tmp --setenv PYTHONDONTWRITEBYTECODE 1 --chdir "$S" "$PY" -B -W error -m pytest -q -p no:cacheprovider --junitxml="$E/artifacts/gate19-successor.junit.xml" tests/test_customer_admin.py;;
 gate20)
  record gate20-candidate-verify "$PY" "$C/verify_candidate.py" "$C";record gate20-ruff "$R/.venv/bin/ruff" check --no-cache "$S/checkin_cli/customer_admin.py" "$S/checkin_cli/activation_token_rotation_policy.py" "$S/tests/test_customer_admin.py"
  record gate20-compile "$PY" -B -c 'import sys;from pathlib import Path;[compile(p.read_bytes(),str(p),"exec",dont_inherit=True) for p in Path(sys.argv[1]).rglob("*.py")]' "$S/checkin_cli"
  record gate20-full-gateway env -u TMPDIR HOME=/home/cube PYTHONPATH="$R:$S" PYTHONDONTWRITEBYTECODE=1 "$PY" -B -m pytest -q -p no:cacheprovider --junitxml="$E/artifacts/gate20-full-gateway.junit.xml" "$R/tests/gateway"
  record gate20-source-package env -u TMPDIR HOME=/home/cube PYTHONPATH="$S" PYTHONDONTWRITEBYTECODE=1 "$PY" -B -m pytest -q -p no:cacheprovider --junitxml="$E/artifacts/gate20-source-package.junit.xml" "$S/tests"
  I="$E/artifacts/installed-profile-wheel-root";mkdir -p "$I";record gate20-wheel-install "$PY" -m pip install --no-deps --no-compile --target "$I" "$W";cp -a "$S/tests" "$E/artifacts/installed-profile-tests"
  record gate20-installed-package env -C /tmp -u TMPDIR HOME=/home/cube PYTHONPATH="$I" PYTHONDONTWRITEBYTECODE=1 "$PY" -B -m pytest -q -p no:cacheprovider --junitxml="$E/artifacts/gate20-installed-package.junit.xml" "$E/artifacts/installed-profile-tests"
  record gate20-installed-imports env -C /tmp -u TMPDIR HOME=/home/cube PYTHONPATH="$I" PYTHONDONTWRITEBYTECODE=1 "$PY" -B - "$I" "$D" <<'PY'
import hashlib,importlib,json,sys
from pathlib import Path
r=Path(sys.argv[1]).resolve();rows=[]
for n in ['checkin_cli.customer_admin','checkin_cli.activation_token_rotation_policy']:
 m=importlib.import_module(n);p=Path(m.__file__).resolve();rows.append({'module':n,'path':str(p),'inside_wheel':p.is_relative_to(r),'sha256':hashlib.sha256(p.read_bytes()).hexdigest()})
o={'candidate_digest':sys.argv[2],'modules':rows,'status':'PASS' if all(x['inside_wheel'] for x in rows) else 'FAIL'};print(json.dumps(o,sort_keys=True,separators=(',',':')));raise SystemExit(o['status']!='PASS')
PY
  ;;
 after)
  snapshot after-gates;sha256sum "$C/candidate-manifest.json" "$C/hash-inventory.json" "$C/bindings/source-delta.json" "$W">"$E/artifacts/candidate-pins-after-gates.sha256";;
 *) echo "usage: $0 {baseline|gate18|gate19|gate20|after}" >&2;exit 64;;
esac
