engine: boosted forms post text/sx, not urlencoded (SX-native write wire)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 34s

build-request-body's POST-form branch now serialises the form fields to a text/sx
body via the serialize primitive (content-type text/sx), instead of FormData ->
URLSearchParams -> urlencoded. A hydrated page posts SX; the host reads it via
host/sx-body / host/field (the server already accepts both — urlencoded stays the
no-engine / login-bootstrap fallback). Recompiled the web stack -> .sxbc.

Verified client-agnostically (no DOM, the user's preference): a new sxtp suite test
proves the wire contract serialize(engine) <-> host/sx-body(server) round-trips a
field dict losslessly, INCLUDING sx_content full of quotes/parens that would break a
naive encoder, plus host/field's content-type discrimination + urlencoded fallback
(sxtp 43/43). The DOM field-read (dom-query-all + .value) is the one irreducibly-
browser bit — left to a targeted Playwright smoke.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 11:14:21 +00:00
parent 999249b944
commit 9293366cb4
4 changed files with 57 additions and 10 deletions

View File

@@ -119,6 +119,29 @@
(dream-status (sxtp/to-dream (sxtp/forbidden "no")))
403)
;; ── engine<->server write wire: serialize (engine) <-> host/sx-body (server) ──
;; A boosted form posts (serialize {field->value}) as text/sx; the server reads it
;; back with host/sx-body. This is the SX write wire, verified with NO DOM (client-
;; agnostic): what the engine's serialize emits, host/sx-body must parse back
;; losslessly — including sx_content full of the quotes/parens that would break a
;; naive encoder. (The server side is what conformance can prove; the DOM field-read
;; is the one irreducibly-browser bit, left to a Playwright smoke.)
(define host-sx-wire-content "(article (h1 \"Title\") (p \"He said \\\"hi\\\" (x)\"))")
(define host-sx-wire-req
(dream-request "POST" "/x" {:content-type "text/sx"}
(serialize {:title "Hi there" :sx_content host-sx-wire-content :status "published"})))
(host-sx-test "sx-body round-trips a serialized field dict"
(get (host/sx-body host-sx-wire-req) "title") "Hi there")
(host-sx-test "sx-body preserves quoted/parenthesised sx_content losslessly"
(get (host/sx-body host-sx-wire-req) "sx_content") host-sx-wire-content)
(host-sx-test "field reads a text/sx body by content-type"
(host/field host-sx-wire-req "status") "published")
(host-sx-test "field falls back to urlencoded form (the no-engine path)"
(host/field (dream-request "POST" "/x"
{:content-type "application/x-www-form-urlencoded"}
"title=From+Form&status=draft") "title")
"From Form")
(define
host-sx-tests-run!
(fn