From bbb852835218c326a06967a1591c139133947cea Mon Sep 17 00:00:00 2001 From: giles Date: Tue, 30 Jun 2026 12:18:34 +0000 Subject: [PATCH] tooling+plan: harness SX_SERVING_JIT=1 fix, conformance timeout bump, specialised editors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- lib/host/conformance.sh | 9 +++++---- lib/host/live-check.sh | 6 +++++- lib/host/playwright/run-picker-check.sh | 4 +++- plans/relations-as-posts.md | 10 ++++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/host/conformance.sh b/lib/host/conformance.sh index b979bde2..15060561 100755 --- a/lib/host/conformance.sh +++ b/lib/host/conformance.sh @@ -142,10 +142,11 @@ emit_eval () { echo "(epoch $EPOCH)"; echo "(eval \"$1\")"; EPOCH=$((EPOCH+1)); done } > "$TMPFILE" -# 600s: the blog suite drives the relations graph hard (every is-a/types-of/ -# instances-of query re-saturates the Datalog db), so it's CPU-bound and slower -# under shared-box contention. 300s was tripping a false truncation. -OUTPUT=$(timeout 600 "$SX_SERVER" < "$TMPFILE" 2>&1 || true) +# 1200s: the blog suite drives the relations graph hard (every is-a/types-of/ +# instances-of query re-saturates the Datalog db), so it's CPU-bound and much slower +# under shared-box contention (a sibling loop at load ~6 pushed it past 600s -> false +# "no suite results parsed" truncation). Override with SX_CONF_TIMEOUT for a tighter cap. +OUTPUT=$(timeout "${SX_CONF_TIMEOUT:-1200}" "$SX_SERVER" < "$TMPFILE" 2>&1 || true) # Fail LOUD on any load/eval error. A test file that errors mid-load silently # truncates its suite — the runner returns only the tests that ran before the diff --git a/lib/host/live-check.sh b/lib/host/live-check.sh index 4a0b9c51..c71867b8 100755 --- a/lib/host/live-check.sh +++ b/lib/host/live-check.sh @@ -29,7 +29,11 @@ cleanup() { trap cleanup EXIT echo "== booting ephemeral host on :$PORT (persist=$PDIR) ==" -HOST_PORT="$PORT" SX_PERSIST_DIR="$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 diff --git a/lib/host/playwright/run-picker-check.sh b/lib/host/playwright/run-picker-check.sh index 4de0372c..d3e9d420 100755 --- a/lib/host/playwright/run-picker-check.sh +++ b/lib/host/playwright/run-picker-check.sh @@ -35,7 +35,9 @@ cleanup() { trap cleanup EXIT echo "== starting ephemeral host server on :$PORT (persist=$PDIR) ==" -HOST_PORT="$PORT" SX_PERSIST_DIR="$PDIR" \ +# SX_SERVING_JIT=1 matches the live container (gates the http-listen IO resolver); +# without it, perform-heavy paths (e.g. the is-a/tags picker's reach-down) falsely 500. +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 >"$SERVE_LOG" 2>&1 & SVPID=$! diff --git a/plans/relations-as-posts.md b/plans/relations-as-posts.md index e723c725..61df017b 100644 --- a/plans/relations-as-posts.md +++ b/plans/relations-as-posts.md @@ -145,6 +145,16 @@ Honest layer: the **render template is data** (editable, meta-circular); only th **widgets** (the date-picker, the image-uploader) are platform pieces, and `value-type` is what *selects* the widget — the same decidable-core / fenced-frontier line as everywhere else. +**The generic form is the default, not the ceiling — types can specify specialised editors.** +A UI doesn't just *fall out* of the types; it can be **customised**. A type may declare an +`:editor` slot — a registered, **content-addressed editor *component*** (a WYSIWYG for rich body, +a map picker for geo, a colour picker) that replaces or augments the input-per-field form, shipped +to the client by hash like `~relate-picker`. So the editing spectrum per type is: **generic +field-form** (data, free) → **per-field widget override** (`value-type`/`:widget`) → **whole +specialised editor component** (the escape hatch, e.g. WYSIWYG). The metamodel picks the level per +type — `:editor` if set, else the generic form. Same decidable-core / fenced-frontier shape: the +declarative form covers the 95%, a code component handles the cases that need real interaction. + **Refined build order** (this is what `/meta` is the on-ramp to): 1. `/meta` overview — DONE (the *see*; `host/blog-type-defs` + `host/blog-meta-index`). 2. **Slice 8 — typed fields** `{name, value-type, widget}` on a type — the **keystone** (drives form + template).