clawdie-ai/scripts/bhyve-evidence.sh
Mevy Assistant b8fd655f02 Refactor V2 identity and platform ownership model
Make the multitenant branch use a clean PLATFORM_*/TENANT_* model, remove active AGENT_NAME runtime usage, collapse hostd ownership into the shared platform, add operator audit surfaces, and add read-only tenant lifecycle commands.

---
Build: pass | Tests: pass — 151 passed (14 files)
2026-04-24 07:49:09 +02:00

112 lines
3.7 KiB
Bash
Executable file

#!/usr/bin/env bash
# bhyve-evidence.sh — Collect deployment evidence from inside a bhyve guest.
# Runs preflight, tsc check, and screenshot capture, then emits a single
# JSON bundle to stdout. Designed to be copy-pasted to another agent.
#
# Usage:
# sudo bash scripts/bhyve-evidence.sh # full run
# sudo bash scripts/bhyve-evidence.sh --quick # skip preflight (tsc + screenshot only)
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
if [ -f "$PROJECT_DIR/.env" ]; then
set -a
# shellcheck disable=SC1091
. "$PROJECT_DIR/.env"
set +a
fi
TENANT_ID="${TENANT_ID:-clawdie}"
PLATFORM_ID="${PLATFORM_ID:-clawdie}"
PLATFORM_SERVICE_NAME="${PLATFORM_SERVICE_NAME:-${PLATFORM_ID}}"
TIMESTAMP="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
HOSTNAME="$(hostname)"
QUICK=false
for arg in "$@"; do
[ "$arg" = "--quick" ] && QUICK=true
done
# ── 1. Preflight ────────────────────────────────────────────────────────────
PREFLIGHT_STATUS="skipped"
PREFLIGHT_JSON="{}"
if [ "$QUICK" = false ]; then
echo "==> Running preflight..." >&2
cd "$PROJECT_DIR"
if npm run preflight-check 2>&1 | tee "$PROJECT_DIR/logs/preflight-latest.log" >&2; then
PREFLIGHT_STATUS="pass"
else
PREFLIGHT_STATUS="fail"
fi
# Find the most recent summary.json (preflight writes to tmp/preflight/)
SUMMARY="$(ls -t "$PROJECT_DIR"/tmp/preflight/*/summary.json 2>/dev/null | head -1)"
if [ -n "$SUMMARY" ]; then
PREFLIGHT_JSON="$(cat "$SUMMARY")"
fi
fi
# ── 2. TypeScript compile check ─────────────────────────────────────────────
echo "==> Running tsc --noEmit..." >&2
cd "$PROJECT_DIR"
if npx tsc --noEmit 2>&1 >&2; then
TSC_STATUS="pass"
else
TSC_STATUS="fail"
fi
# ── 3. Screenshot capture ───────────────────────────────────────────────────
SCREENSHOT_JSON="{}"
SCREENSHOT_STATUS="skipped"
SCREENSHOT_SCRIPT="$PROJECT_DIR/.agent/skills/tmux-screenshot/tmux-screenshot.py"
if [ -f "$SCREENSHOT_SCRIPT" ] && command -v python3 >/dev/null 2>&1; then
echo "==> Capturing screenshot..." >&2
CAPTURE_OUTPUT="$(python3 "$SCREENSHOT_SCRIPT" \
--session "$PLATFORM_SERVICE_NAME" \
--publish 2>&1)" || true
# Extract the per-capture JSON if it exists
CAPTURE_DIR="$PROJECT_DIR/tmp/screenshots"
LATEST_JSON="$(ls -t "$CAPTURE_DIR"/*.json 2>/dev/null | grep -v manifest | head -1)"
if [ -n "$LATEST_JSON" ]; then
SCREENSHOT_JSON="$(cat "$LATEST_JSON")"
SCREENSHOT_STATUS="pass"
else
SCREENSHOT_STATUS="fail"
fi
else
echo "WARN: screenshot script or python3 not found, skipping" >&2
fi
# ── 4. Emit bundle ──────────────────────────────────────────────────────────
cat <<ENDJSON
{
"evidence_version": 1,
"tenant_id": "${TENANT_ID}",
"hostname": "${HOSTNAME}",
"collected_at": "${TIMESTAMP}",
"codebase_version": "$(grep '"version"' "$PROJECT_DIR/package.json" | head -1 | sed 's/.*: *"//;s/".*//')",
"checks": {
"preflight": {
"status": "${PREFLIGHT_STATUS}",
"summary": ${PREFLIGHT_JSON}
},
"tsc": {
"status": "${TSC_STATUS}"
},
"screenshot": {
"status": "${SCREENSHOT_STATUS}",
"capture": ${SCREENSHOT_JSON}
}
}
}
ENDJSON