← back to Govarbitrage
apps/mobile/device-proof-evidence/readiness-probe.sh
74 lines
#!/bin/bash
# TK-10279 — consolidated submit-readiness probe. Read-only, $0 local.
# Emits one JSON object of every gate GovArbitrage's 2.1 response depends on.
# PASS overall == everything but the physical recording + the (gated) Apple send is ready.
# Usage: ./readiness-probe.sh [path-to-recording.mov] (recording arg optional)
set -uo pipefail
cd "$(dirname "$0")"
REC="${1:-}"
BASE="https://auctions.agentabrams.com"
json_bool(){ [ "$1" = "1" ] && echo true || echo false; }
# --- GATE: backend (reviewer hits this) ---
b_root=$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 "$BASE" 2>/dev/null)
b_priv=$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 "$BASE/privacy" 2>/dev/null)
b_list_code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 20 "$BASE/api/listings" 2>/dev/null)
b_total=$(curl -s --max-time 20 "$BASE/api/listings" 2>/dev/null | sed -n 's/.*"total":\([0-9]*\).*/\1/p' | head -1)
backend_ok=0; [ "$b_root" = 200 ] && [ "$b_priv" = 200 ] && [ "$b_list_code" = 200 ] && [ "${b_total:-0}" -gt 0 ] 2>/dev/null && backend_ok=1
# --- GATE: reply-text source accuracy (must name every live source enum) ---
reply_ok=1
for s in GovDeals GovPlanet "GSA Auctions" "Public Surplus" GoIndustry; do
grep -qi "$s" ../ASC-PASTE-KIT.md || reply_ok=0
done
# --- GATE: verifier tooling present + executable ---
tool_ok=0; [ -x ./verify-recording.sh ] && tool_ok=1
# --- GATE: physical recording + manual privacy review ---
rec_status="ABSENT"; rec_file=""; privacy_status="ABSENT"
[ -z "$REC" ] && REC=$(ls -t ./govarbitrage-DEVICE-*.mov ./govarbitrage-DEVICE-*.mp4 2>/dev/null | head -1)
if [ -n "$REC" ] && [ -f "$REC" ] && [[ "$(basename "$REC")" == govarbitrage-DEVICE-* ]]; then
rec_file="$REC"
if [ -x ./verify-recording.sh ] && ./verify-recording.sh "$REC" >/dev/null 2>&1; then
rec_status="TECH_PASS_PRIVACY_PENDING"
if [ -f "$REC.privacy-reviewed.sha256" ] && (cd "$(dirname "$REC")" && shasum -a 256 -c "$(basename "$REC").privacy-reviewed.sha256") >/dev/null 2>&1; then
privacy_status="PASS"
rec_status="PASS"
fi
else
rec_status="FAIL"
fi
elif [ -n "$REC" ] && [ -f "$REC" ]; then
rec_file="$REC"
rec_status="REJECTED_NOT_DEVICE_NAMED"
fi
rec_ok=0; [ "$rec_status" = PASS ] && rec_ok=1
# --- GATE: ASC artifact state (read-only; best-effort) ---
asc_line=$(ASC_KEY_PATH="${ASC_KEY_PATH:-$HOME/.appstoreconnect/private_keys/AuthKey_72Y2TZT54R.p8}" \
ASC_KEY_ID="${ASC_KEY_ID:-72Y2TZT54R}" \
timeout 90 node "$HOME/.claude/skills/ipa-status/scripts/ipa-status.mjs" --ready 2>/dev/null | grep -i GovArbitrage | head -1)
asc_ok=0; printf '%s' "$asc_line" | grep -qi "SUBMIT-READY" && asc_ok=1
# overall = everything automatable green (recording is the human gate, reported separately)
auto_ok=0; [ $backend_ok = 1 ] && [ $reply_ok = 1 ] && [ $tool_ok = 1 ] && [ $asc_ok = 1 ] && auto_ok=1
cat <<JSON
{
"ticket": "TK-10279",
"ts": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"gates": {
"backend": { "ok": $(json_bool $backend_ok), "root": "$b_root", "privacy": "$b_priv", "listings": "$b_list_code", "total": ${b_total:-0} },
"reply_text":{ "ok": $(json_bool $reply_ok), "note": "names GovDeals/GovPlanet/GSA/Public Surplus/GoIndustry" },
"verifier": { "ok": $(json_bool $tool_ok), "path": "verify-recording.sh" },
"asc": { "ok": $(json_bool $asc_ok), "state": "$(printf '%s' "$asc_line" | sed 's/^[^A-Za-z]*//; s/"/'"'"'/g' | tr -s ' ')" },
"recording": { "ok": $(json_bool $rec_ok), "status": "$rec_status", "privacy_review": "$privacy_status", "file": "$rec_file", "note": "physical iPhone capture; requires technical validation + matching manual privacy-review SHA-256 sidecar" }
},
"automatable_ready": $(json_bool $auto_ok),
"human_gated_remaining": ["physical-device recording", "ASC Resolution Center reply+upload"],
"verdict": "$( [ $auto_ok = 1 ] && [ $rec_ok = 1 ] && echo READY_TO_SEND || { [ $auto_ok = 1 ] && echo READY_EXCEPT_RECORDING || echo NOT_READY; } )"
}
JSON