Multi-shot delimited continuations: 868/870 passing
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 9m5s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 9m5s
Continuations are now multi-shot — k can be invoked multiple times. Each invocation runs the captured frames via nested cek-run and returns the result to the caller's continuation. Fix: continue-with-call runs ONLY the captured delimited frames (not rest-kont), so the continuation terminates and returns rather than escaping to the outer program. Fixed 4 continuation tests: - shift with multiple invokes: (list (k 10) (k 20)) → (11 21) - k returned from reset: continuation callable after escaping - invoke k multiple times: same k reusable - k in data structure: store in list, retrieve, invoke Remaining 2 failures: scope/provide across shift boundaries. These need scope state tracked in frames (not imperative push/pop). JS 747/747, Full 868/870, Python 679/679. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -366,6 +366,131 @@
|
||||
"The only interpreter in the system is the CPU."))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Security model
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Security Model" :id "security"
|
||||
|
||||
(p "Compiled SX running as WASM is " (em "more secure") " than plain JavaScript, "
|
||||
"not less. JS has ambient access to the full browser API. "
|
||||
"WASM + the platform layer means compiled SX code has "
|
||||
(strong "zero ambient capabilities") " \u2014 every capability is explicitly granted.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Five defence layers")
|
||||
|
||||
(div :class "overflow-x-auto rounded border border-stone-200 mb-4"
|
||||
(table :class "w-full text-left text-sm"
|
||||
(thead (tr :class "border-b border-stone-200 bg-stone-100"
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Layer")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Enforced by")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "What it prevents")))
|
||||
(tbody
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "1. WASM sandbox")
|
||||
(td :class "px-3 py-2 text-stone-700" "Browser")
|
||||
(td :class "px-3 py-2 text-stone-600" "Memory isolation, no system calls, no DOM access except via explicit imports. Validated before execution."))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "2. Platform capabilities")
|
||||
(td :class "px-3 py-2 text-stone-700" (code "sx-platform.js"))
|
||||
(td :class "px-3 py-2 text-stone-600" "Compiled code can only call functions you register. No fetch? Can't fetch. No localStorage? Can't read storage. The platform is a capability system."))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "3. Content-addressed verification")
|
||||
(td :class "px-3 py-2 text-stone-700" "CID determinism")
|
||||
(td :class "px-3 py-2 text-stone-600" "Compiler is deterministic: same source \u2192 same CID. Client can re-compile and verify. Tampered WASM produces wrong CID \u2192 reject."))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "4. Per-component attenuation")
|
||||
(td :class "px-3 py-2 text-stone-700" "Platform scoping")
|
||||
(td :class "px-3 py-2 text-stone-600" "Different components get different capability subsets. User-generated content gets a locked-down platform \u2014 can render DOM but can't fetch or listen to events."))
|
||||
(tr
|
||||
(td :class "px-3 py-2 text-stone-700" "5. Source-first fallback")
|
||||
(td :class "px-3 py-2 text-stone-700" "Client compiler")
|
||||
(td :class "px-3 py-2 text-stone-600" "Don't trust precompiled WASM? Compile from source locally. The client has the compiler. Precompilation is an optimisation, not a trust requirement.")))))
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Content-addressed tamper detection")
|
||||
(p "The server sends both SX source and precompiled WASM CID. The client can verify:")
|
||||
|
||||
(~docs/code :code (highlight ";; Server sends:\nContent-Type: application/wasm\nX-Sx-Source-Cid: bafyrei..source\nX-Sx-Compiled-Cid: bafyrei..compiled\n\n;; Client verifies (optional, configurable):\n1. Hash the WASM binary \u2192 matches X-Sx-Compiled-Cid?\n2. Compile source locally \u2192 produces same compiled CID?\n3. Check manifest of pinned CIDs \u2192 CID is expected?\n\n;; Any mismatch = tampered = reject" "text"))
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Capability attenuation per component")
|
||||
(p "The platform scopes capabilities per evaluator instance. "
|
||||
"App shell gets full access. Third-party or user-generated content gets the minimum:")
|
||||
|
||||
(~docs/code :code (highlight "// Full capabilities for the app shell\nplatform.registerAll(appShellCompiler);\n\n// Restricted for user-generated content\nplatform.registerSubset(userContentCompiler, {\n allow: [\"dom-create-element\", \"dom-set-attr\", \"dom-append\",\n \"dom-create-text-node\", \"dom-set-text\"],\n deny: [\"fetch\", \"localStorage\", \"dom-listen\",\n \"dom-set-inner-html\", \"eval\"]\n});\n\n// The restricted compiler's WASM module literally doesn't\n// have imports for the denied functions. Not just blocked\n// at runtime \u2014 absent from the binary." "javascript"))
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Component manifests")
|
||||
(p "The app ships with a manifest of expected CIDs for its core components. "
|
||||
"Like subresource integrity (SRI) but for compiled code:")
|
||||
|
||||
(~docs/code :code (highlight ";; Component manifest (shipped with the app, signed)\n{\n \"~card\": \"bafyrei..abc\"\n \"~header\": \"bafyrei..def\"\n \"~nav-item\": \"bafyrei..ghi\"\n}\n\n;; On navigation: server sends component update\n;; Client compiles \u2192 checks CID against manifest\n;; Match = trusted, execute\n;; Mismatch = tampered, reject and report" "text"))
|
||||
|
||||
(p "The security model is " (em "structural") ", not bolt-on. "
|
||||
"WASM isolation, platform capabilities, content-addressed verification, "
|
||||
"and per-component attenuation all arise naturally from the architecture. "
|
||||
"The platform layer that enables Rust/OCaml interop is the same layer "
|
||||
"that enforces security boundaries."))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Isomorphic rendering + SEO
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "Isomorphic Rendering" :id "isomorphic"
|
||||
|
||||
(p "WASM is invisible to search engines. But SX is already isomorphic \u2014 "
|
||||
"the same spec, the same components, rendered to HTML on the server "
|
||||
"and to DOM on the client. Compiled WASM doesn't change this. "
|
||||
"It makes the client side faster without affecting what crawlers see.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "The rendering pipeline")
|
||||
|
||||
(~docs/code :code (highlight "Crawler visits:\n GET /page\n \u2192 Server compiles SX (native OCaml)\n \u2192 render-to-html (adapter-html.sx)\n \u2192 Full static HTML with semantic markup\n \u2192 Google indexes it\n\nUser first visit:\n GET /page\n \u2192 Server renders HTML (same as crawler)\n \u2192 Browser displays immediately (no JS needed)\n \u2192 Client loads sx-compiler.wasm + sx-platform.js\n \u2192 Hydrates: attaches event handlers, activates islands\n \u2192 Page is interactive\n\nUser navigates (SPA):\n sx-get /next-page\n \u2192 Server sends SX wire format (aser)\n \u2192 Client compiles + renders via WASM\n \u2192 Morph engine patches the DOM" "text"))
|
||||
|
||||
(p "The server and client have the " (em "same compiler") " from the " (em "same spec") ". "
|
||||
(code "adapter-html.sx") " produces HTML strings. "
|
||||
(code "adapter-dom.sx") " produces DOM nodes. "
|
||||
"Two rendering modes of one evaluator. The compiled WASM version "
|
||||
"makes hydration and SPA navigation faster, but the initial HTML "
|
||||
"is always server-rendered.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "What crawlers see")
|
||||
(ul :class "list-disc list-inside space-y-1 mt-2"
|
||||
(li "Fully rendered HTML \u2014 no \"loading...\" skeleton, no JS-dependent content")
|
||||
(li "Semantic markup \u2014 " (code "<h1>") ", " (code "<nav>") ", " (code "<article>") ", " (code "<a href>")
|
||||
" \u2014 all from the SX component tree")
|
||||
(li "Meta tags, canonical URLs, structured data \u2014 rendered server-side by " (code "shell.sx"))
|
||||
(li "No WASM, no JS required \u2014 the HTML is the page, complete on first byte"))
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Content-addressed prerendering")
|
||||
(p "The server can prerender every page to static HTML, hash it, "
|
||||
"and cache it at the CDN edge:")
|
||||
|
||||
(~docs/code :code (highlight "Page source CID \u2192 Rendered HTML CID\nbafyrei..source \u2192 bafyrei..html\n\n\u2022 Crawler hits CDN \u2192 instant HTML, no server round-trip\n\u2022 Page content changes \u2192 new source CID \u2192 new HTML CID \u2192 CDN invalidated\n\u2022 Same CID = same HTML forever \u2192 infinite cache, zero revalidation" "text"))
|
||||
|
||||
(p "This is the same content-addressed caching as compiled WASM, "
|
||||
"applied to the HTML output. Both the compiled client code and "
|
||||
"the server-rendered HTML are cached by CID. "
|
||||
"The entire delivery pipeline is content-addressed.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Progressive enhancement")
|
||||
(p "The page works at every level:")
|
||||
(div :class "overflow-x-auto rounded border border-stone-200 mb-4"
|
||||
(table :class "w-full text-left text-sm"
|
||||
(thead (tr :class "border-b border-stone-200 bg-stone-100"
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Client capability")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Experience")))
|
||||
(tbody
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "No JS (crawler, reader mode)")
|
||||
(td :class "px-3 py-2 text-stone-600" "Full HTML. Links work. Forms submit. Content is complete."))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "JS, no WASM")
|
||||
(td :class "px-3 py-2 text-stone-600" "Falls back to js_of_ocaml evaluator or interpreted JS. SPA navigation, islands, signals all work."))
|
||||
(tr
|
||||
(td :class "px-3 py-2 text-stone-700" "JS + WASM")
|
||||
(td :class "px-3 py-2 text-stone-600" "Full compiled pipeline. JIT compilation, cached WASM functions, near-native rendering speed."))))))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; How this changes existing plans
|
||||
;; -----------------------------------------------------------------------
|
||||
@@ -397,7 +522,7 @@
|
||||
(td :class "px-3 py-2 text-stone-700"
|
||||
(a :href "/sx/(etc.(plan.wasm-bytecode-vm))" "WASM Bytecode VM"))
|
||||
(td :class "px-3 py-2 text-stone-600"
|
||||
"Complementary. OCaml gives tree-walking CEK. Bytecode VM is a future optimization on top."))
|
||||
"Subsumed as Tier 1. Bytecodes become an intermediate step on the path to native WASM compilation. The dispatch loop is Tier 1; JIT to WASM functions is Tier 2; AOT is Tier 3."))
|
||||
(tr
|
||||
(td :class "px-3 py-2 text-stone-700"
|
||||
(a :href "/sx/(etc.(plan.self-hosting-bootstrapper))" "Self-Hosting Bootstrapper"))
|
||||
@@ -436,15 +561,18 @@
|
||||
(~docs/section :title "Outcome" :id "outcome"
|
||||
(p "After completion:")
|
||||
(ul :class "list-disc list-inside space-y-2 mt-2"
|
||||
(li "SX core evaluator compiled from spec via OCaml \u2014 native + WASM from one codebase.")
|
||||
(li "SX core compiled from spec via OCaml \u2014 native + WASM from one codebase.")
|
||||
(li "Python web framework calls native " (code "sx_core.so") " for rendering \u2014 "
|
||||
"100\u20131000x faster than interpreted Python.")
|
||||
(li "Browser loads " (code "sx_core.wasm") " \u2014 same evaluator, same spec, near-native speed.")
|
||||
(li "Browser loads " (code "sx_core.wasm") " \u2014 same compiler, same spec, near-native speed.")
|
||||
(li "Server sends SX, client JIT-compiles to WASM functions and caches by CID.")
|
||||
(li "Entire apps AOT-compiled to " (code ".wasm") " binaries. "
|
||||
"Platform provides DOM/fetch. Everything else is machine code.")
|
||||
(li "Content-addressed compilation cache: compile once, cache by CID, serve from CDN/IPFS forever.")
|
||||
(li "Concurrent CEK runs on OCaml 5 fibers/domains \u2014 true parallelism for Art DAG.")
|
||||
(li "Linear effects validated by SX type system, enforced by OCaml one-shot continuations.")
|
||||
(li "Self-hosting compiler: SX compiles itself to machine code. OCaml scaffolding removed.")
|
||||
(li "The architecture proof: one language, one compiled evaluator, "
|
||||
"every platform just provides effects."))
|
||||
(li "The only interpreter in the system is the CPU."))
|
||||
|
||||
(p :class "text-stone-500 text-sm italic mt-12"
|
||||
"The Mother Language was always SX. We just needed to find the right scaffolding to stand it up."))))
|
||||
|
||||
Reference in New Issue
Block a user