Files
rose-ash/lib/host/live-check.sh
giles bbb8528352
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 19s
tooling+plan: harness SX_SERVING_JIT=1 fix, conformance timeout bump, specialised editors
- live-check.sh + run-picker-check.sh now set SX_SERVING_JIT=1 to MATCH THE CONTAINER:
  that env gates the http-listen IO resolver, so without it perform-heavy paths (the is-a/
  tags picker's reach-down BFS) falsely raise VmSuspended -> 500 in the harness while the
  live site is fine (confirmed live is-a picker = 200). Harness must mirror what the
  container runs.
- conformance.sh: 600s -> 1200s cap (overridable via SX_CONF_TIMEOUT). A sibling loop at
  load ~6 pushed the Datalog-heavy blog suite past 600s -> false 'no suite results parsed'.
- plan: types can specify SPECIALISED EDITORS — a type's :editor slot = a content-addressed
  editor component (WYSIWYG, map picker) shipped to the client like ~relate-picker. Generic
  form is the default, not the ceiling; spectrum = generic -> per-field widget -> :editor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 12:18:34 +00:00

75 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Non-browser live-check for the host: spins up an EPHEMERAL host server (this
# worktree's binary + lib + web, a temp persist dir), logs in, seeds one post, then
# runs a sequence of HTTP checks printing status | content-type | body-head for each.
# Catches what conformance can't — the real http-listen serving path (serving-JIT
# divergence, VmSuspended renders, content-type regressions) — without a browser and
# without touching live data. The non-Playwright counterpart to run-picker-check.sh.
#
# bash lib/host/live-check.sh # default smoke: /health /posts /feed / /<seeded>/
# bash lib/host/live-check.sh /tags /article/ # check specific GET paths instead
#
# Asserts: reads are text/sx (the SX-native wire), pages are non-empty, no 5xx.
# Requires the OCaml binary built (hosts/ocaml/_build/default/bin/sx_server.exe).
set -uo pipefail
cd "$(git rev-parse --show-toplevel)"
PORT="${LIVE_PORT:-8914}"
USER="admin"; PASS="live-check-pw"; SECRET="live-check-secret"
PDIR=$(mktemp -d); JAR=$(mktemp); LOG=$(mktemp); HDR=$(mktemp)
BASE="http://127.0.0.1:$PORT"
RC=0
cleanup() {
local pid
pid=$(ss -lptn "sport = :$PORT" 2>/dev/null | grep -oE 'pid=[0-9]+' | head -1 | cut -d= -f2)
[ -n "$pid" ] && kill "$pid" 2>/dev/null
rm -f "$JAR" "$LOG" "$HDR"; rm -rf "$PDIR"
}
trap cleanup EXIT
echo "== booting ephemeral host on :$PORT (persist=$PDIR) =="
# SX_SERVING_JIT=1 to MATCH THE CONTAINER: it gates the http-listen IO resolver, so
# without it perform-heavy paths (e.g. reach-down's BFS over the type graph — the is-a/
# tags picker) falsely raise VmSuspended -> 500. The live container sets it; the harness
# must too, or it reports false 500s the live site never shows.
SX_SERVING_JIT=1 HOST_PORT="$PORT" SX_PERSIST_DIR="$PDIR" \
SX_ADMIN_USER="$USER" SX_ADMIN_PASSWORD="$PASS" SX_SESSION_SECRET="$SECRET" \
bash lib/host/serve.sh >"$LOG" 2>&1 &
for i in $(seq 1 60); do
curl -sf -o /dev/null "$BASE/health" 2>/dev/null && break
sleep 1; [ "$i" = "60" ] && { echo "server never came up:"; cat "$LOG"; exit 1; }
done
echo "== up =="
# Log in + seed one post (also exercises the form-ingest write path).
curl -s -c "$JAR" -o /dev/null -X POST "$BASE/login" --data "username=$USER&password=$PASS"
curl -s -b "$JAR" -o /dev/null -X POST "$BASE/new" \
--data 'title=Live Check Post&sx_content=(article (h1 "Live Check Post") (p "ok"))&status=published'
# A GET check: prints "<status> <content-type> | <body-head>" and flags problems.
check() {
local path="$1" body ct code
body=$(curl -s -b "$JAR" -D "$HDR" "$BASE$path")
code=$(awk 'NR==1{print $2}' "$HDR")
ct=$(grep -i '^content-type:' "$HDR" | head -1 | tr -d '\r' | sed 's/content-type: *//I')
printf ' %-20s %s %-26s | %s\n' "$path" "${code:-???}" "${ct:-?}" "$(printf '%s' "$body" | tr '\n' ' ' | cut -c1-70)"
case "$code" in 5*) echo " !! 5xx"; RC=1 ;; esac
[ -z "$body" ] && { echo " !! empty body"; RC=1; }
# data endpoints must be SX, never JSON
case "$path" in
/posts|/feed) echo "$ct" | grep -qi 'text/sx' || { echo " !! expected text/sx, got '$ct'"; RC=1; }
printf '%s' "$body" | grep -q '"ok":' && { echo " !! JSON leaked"; RC=1; } ;;
esac
}
echo "== checks =="
if [ "$#" -gt 0 ]; then
for p in "$@"; do check "$p"; done
else
for p in /health /posts /feed / /live-check-post/; do check "$p"; done
fi
echo "== done (rc $RC) =="
exit $RC