#!/usr/bin/env bash
# tests/claude-guard/run-tests.sh -- offline harness for the Claude Code
# PreToolUse guard (.claude/hooks/guard-destructive.py). Proves each NEVER
# rule blocks (exit 2) and normal ops pass (exit 0), including the malformed-
# input fail-open-to-permission-rules contract. ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HOOK="$(cd "$HERE/../.." && pwd)/.claude/hooks/guard-destructive.py"
PASS=0; FAIL=0
run() { # run <want_rc> <label> <json-or-raw>
local rc
printf '%s' "$3" | python3 "$HOOK" >/dev/null 2>&1; rc=$?
if [ "$rc" = "$1" ]; then echo " PASS $2"; PASS=$((PASS+1))
else echo " FAIL $2 (rc=$rc want=$1)"; FAIL=$((FAIL+1)); fi
}
cmd() { printf '{"tool_input":{"command":"%s"}}' "$1"; }
run 2 "vault operator init blocked" "$(cmd 'vault operator init > /tmp/x 2>&1')"
run 2 "vault operator rekey blocked" "$(cmd 'VAULT_ADDR=x vault operator rekey')"
run 2 "destroy-controller blocked" "$(cmd 'juju destroy-controller maas-controller')"
run 2 "maas list blocked (DOCFIX-016)" "$(cmd 'maas list')"
run 2 "force-push blocked" "$(cmd 'git push --force origin main')"
run 2 "secret read blocked (vault-init)" "$(cmd 'cat ~/vault-init/unseal-keys.txt')"
run 2 "secret read blocked (appcred)" "$(cmd 'head -1 /home/j/tenant-acme/acme-svc-appcred.txt')"
run 2 "catastrophic rm blocked" "$(cmd 'rm -rf /')"
# extended reader set: text tools + python3/openssl on secret paths
run 2 "grep on tenant cred blocked" "$(cmd 'grep password= /home/j/tenant-acme/acme-svc-cred.txt')"
run 2 "awk on tenant cred blocked" "$(cmd "awk -F= '/^password=/{print \$2}' \$HOME/tenant-acme/acme-svc-cred.txt")"
run 2 "sed on vault-init blocked" "$(cmd 'sed -n 1p ~/vault-init/unseal-keys.txt')"
run 2 "openssl on tenant key .pem blocked" "$(cmd 'openssl rsa -in ~/tenant-acme/acme-key.pem -check')"
run 2 "python3 on as-executed blocked" "$(cmd "python3 -c \\\"print(open('/home/j/as-executed/log.txt').read())\\\"")"
run 2 "cat on bare .pem blocked" "$(cmd 'cat ./testco-key.pem')"
run 2 "tail on home tenant dir blocked" "$(cmd 'tail -5 /home/jessea123/tenant-acme/notes.txt')"
run 0 "juju status passes" "$(cmd 'juju status -m openstack --format=json')"
run 0 "cloud-assert passes" "$(cmd 'bash scripts/cloud-assert.sh')"
run 0 "vault status (non-one-shot) passes" "$(cmd 'juju ssh vault/0 -- vault status')"
run 0 "maas admin read passes (not maas list)" "$(cmd 'maas admin machines read')"
# precision: quoted PROSE mentions and non-secret files stay allowed
run 0 "grep for quoted .pem string passes" "$(cmd 'grep -rn \"vault-ca-root.pem\" scripts/')"
run 0 "awk on non-secret file passes" "$(cmd "awk '{print \$1}' /tmp/inventory.txt")"
run 0 "cat on repo tests/tenant-* dir passes" "$(cmd 'cat tests/tenant-offboard/run-tests.sh')"
run 0 "grep in repo tenant script passes" "$(cmd 'grep -n auth_url scripts/tenant-onboard.sh')"
run 0 "openssl on non-pem cert passes" "$(cmd 'openssl x509 -in /tmp/test-ca.crt -noout -dates')"
run 0 "malformed input -> no opinion (rc 0)" 'not-json-at-all'
echo; echo "RESULT: PASS=$PASS FAIL=$FAIL"
[ "$FAIL" -eq 0 ] && { echo "ALL PASS"; exit 0; } || exit 1