#!/usr/bin/env bash set -euo pipefail ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" cd "$ROOT" RUN_LIVE_SHADOW=0 RUN_GOLDEN=0 RUN_CAD_PARITY=0 DEFAULT_CAD_PARITY_HOST="${CAD_PARITY_HOST:-http://localhost:8888}" DEFAULT_CAD_PARITY_EMAIL="${CAD_PARITY_EMAIL:-admin@hartomat.com}" DEFAULT_CAD_PARITY_PASSWORD="${CAD_PARITY_PASSWORD:-Admin1234!}" DEFAULT_CAD_PARITY_ID="${CAD_PARITY_ID:-7c214057-9982-4d6e-aa87-43bfabfdb709}" usage() { cat <<'EOF' Usage: ./scripts/workflow_sequential_gates.sh [options] Options: --with-live-shadow Also run the live still-smoke harness in shadow mode. --with-golden Also run the live golden suite after the other gates. --with-cad-parity Also verify live CAD scene-manifest/model part-key parity. -h, --help Show this help. Behavior: Runs the current minimum workflow verification gates sequentially to avoid RAM spikes from parallel test execution. EOF } parse_args() { while [ "$#" -gt 0 ]; do case "$1" in --with-live-shadow) RUN_LIVE_SHADOW=1 ;; --with-golden) RUN_GOLDEN=1 ;; --with-cad-parity) RUN_CAD_PARITY=1 ;; -h|--help) usage exit 0 ;; *) echo "Unknown option: $1" >&2 usage >&2 exit 1 ;; esac shift done } log() { printf '\n[%s] %s\n' "$(date '+%H:%M:%S')" "$*" } die() { echo "[error] $*" >&2 exit 1 } require_command() { local binary="$1" local hint="$2" command -v "$binary" >/dev/null 2>&1 || die "$binary is required. $hint" } require_path() { local path="$1" local hint="$2" [ -e "$path" ] || die "$path is missing. $hint" } preflight() { log "Preflight checks" require_command curl "Install curl or run this script from the normal development shell." require_command python3 "Install python3 or activate the expected local toolchain." require_path backend/.venv/bin/pytest "Create the backend venv first, for example via the normal backend setup flow." require_path frontend/node_modules "Run 'cd frontend && npm install' first." require_path frontend/node_modules/.bin/vitest "Frontend test dependencies are incomplete. Re-run 'cd frontend && npm install'." require_path scripts/compare_live_cad_parity.py "The live CAD parity gate script is missing." } run_step() { local label="$1" shift log "$label" "$@" } parse_args "$@" preflight run_step "Frontend health" curl -fsSI http://localhost:5173 run_step "Backend health" curl -fsS http://localhost:8888/health run_step "Runtime config regression tests" backend/.venv/bin/pytest backend/tests/test_config_runtime_resolution.py -q run_step "Workflow runtime regression tests" backend/.venv/bin/pytest backend/tests/domains/test_workflow_runtime_services.py -q run_step \ "Workflow editor/frontend regression tests" \ bash -lc "cd frontend && npx vitest run src/__tests__/components/workflowEditorUi.test.tsx src/__tests__/api/outputTypes.test.ts --pool forks --poolOptions.forks.singleFork=true" if [ "$RUN_CAD_PARITY" -eq 1 ]; then run_step \ "Live CAD manifest/model parity" \ python3 scripts/compare_live_cad_parity.py \ --host "$DEFAULT_CAD_PARITY_HOST" \ --email "$DEFAULT_CAD_PARITY_EMAIL" \ --password "$DEFAULT_CAD_PARITY_PASSWORD" \ --cad-id "$DEFAULT_CAD_PARITY_ID" fi if [ "$RUN_LIVE_SHADOW" -eq 1 ]; then run_step \ "Live still smoke harness (shadow)" \ python3 scripts/test_render_pipeline.py --workflow-still-smoke --execution-mode shadow fi if [ "$RUN_GOLDEN" -eq 1 ]; then run_step "Live golden suite" python3 scripts/test_render_pipeline.py --workflow-golden-suite fi log "Sequential workflow gates completed"