host: scope Phase 5 — generic interactive SX-page serving (host SSR)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 31s

Frame the editor as one instance of a general gap: the host serves JSON + static
content but cannot serve interactive SX component/island pages. Scope the generic
capability — reuse the kernel's existing shell pipeline (~shared:shell/
sx-page-shell + http_inject_shell_statics + http_render_page) rather than
reinvent — in 5 gated sub-steps: page-render from a handler, shell statics,
static-asset serving, island hydration, editor POC. Documents why render-to-html
alone fails (mangles evaluated-component attributes) and that component SSR is
slow until the JIT loop lands. Modern editor = SX reactive island (defisland +
signals) over a content-on-sx model; replace the legacy Lexical/Koenig editor,
don't resurrect it (the POST /new ingest already speaks sx_content).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 20:04:24 +00:00
parent e201eef686
commit 8e817e974f

View File

@@ -192,6 +192,67 @@ lib/host/sxtp.sx subsystem APIs (feed/search/commerce/…
- [ ] (gated) adopt `dream-on-sx` session/CSRF ergonomics; re-home external
adapters as native where replacements land.
## Phase 5 — Generic interactive SX-page serving (host SSR)
**The generic gap.** A host serves three classes: (1) JSON/data endpoints —
DONE; (2) static content pages — DONE (`render-to-html` on *parsed* markup, e.g.
blog post `sx_content`); (3) **interactive UI pages** — component/island trees
with attributes + client behaviour — **the host cannot do this at all.** The
"editor problem" is one instance; dashboards, account, market-browse, any admin
screen are the same gap. The capability — not the editor — is the deliverable.
**Why `render-to-html` alone is insufficient (proven).** `render-to-html` on
parsed markup handles attributes (`<div id="x">`); but an *evaluated* component
tree mangles them (`(form :id ..)``<form>idpost-new-form…`) because in the
host preload tags don't collect keyword args as attrs. The `--http` docs server
already does this correctly via its component-render + shell pipeline. So: reuse
that pipeline, don't reinvent or patch per-component.
**Reuse, don't rebuild.** The kernel already has: `~shared:shell/sx-page-shell`
(emits `<!doctype>` + inlined component/island defs in `<script type="text/sx">`
+ CSS + `sx-browser.js` + page SX for hydration), `http_inject_shell_statics`
(gathers defs/CSS/asset-hashes into the env), and `http_render_page`. These power
`sx.rose-ash.com`. The job is to make them reachable from the `http-listen`
serving path.
Sub-steps (each independently gated/verified):
- [ ] **5.1 Page render from a host handler.** Expose the kernel's
component-render + shell so an `http-listen` handler can return a full SX
page (correct attributes, not the mangling `render-to-html` path). Likely a
small `hosts/` addition: a `render-page`-style entry callable from the
handler, or a `host/page` route the server renders via the page pipeline.
Gate: `~editor/form` (or any attributed component) renders to correct HTML.
- [ ] **5.2 Shell statics in the host env.** Run `http_inject_shell_statics` for
the host's loaded components so the shell can inline defs/CSS/asset-hashes.
Gate: a full page shell emits with component defs inlined.
- [ ] **5.3 Static-asset serving.** Serve `/scripts/*.js`, `/*.css`, `/wasm/*`
from `shared/static`. Host has none today — needs a kernel file-serving
route in the `http-listen` server (or a file-read prim + SX static handler).
Interim option to defer: reference assets by absolute URL from the existing
static host. Gate: `sx-browser.js`/CSS load for a host-served page.
- [ ] **5.4 Island hydration.** Confirm a trivial island page boots + hydrates
client-side (sx-browser.js) when served by the host. Gate: a counter island
increments in the browser.
- [ ] **5.5 Editor POC.** Serve an editor page as the FIRST interactive consumer,
its form/island posting to the existing `POST /new` ingest (already proven).
Gate: visual edit → publish → renders, end-to-end in a browser. (The POC
validates the *capability*; the editor itself is replaced next — see below.)
**Note:** component SSR is interpreted → slow until the `sx-vm-extensions` JIT
loop lands; correctness first, speed follows. Scope spans `hosts/` (page-render
exposure + static serving) + `lib/host` (page route type + page handlers).
**Modern editor — language.** A WYSIWYG editor is a *reactive UI*, so it should be
an **SX reactive island** (`defisland` + signals/lakes — the platform's native UI
primitive), NOT a guest language (Datalog/Prolog/APL/Haskell are logic/data/array
— wrong tool) and NOT a JS lib (Lexical/Koenig, the legacy baggage). The document
*model* it edits is **content-on-sx** (structured blocks, CvRDT-ready for
collaboration). So: **SX islands for the UI, content-on-sx for the model** — SX
all the way down, dogfooding the reactive runtime + content-on-sx + this new
page-serving capability. (Legacy `blog/sx/editor.sx` is Lexical/Koenig/Quart-CSRF
era — replace, don't resurrect; the `POST /new` ingest already speaks the
`sx_content` contract any new editor emits.)
## Progress log
- **Phase 1 (DONE, 28/28).** `lib/host/{handler,router,feed}.sx` + three test