Design + ops scaffolding for the next phase of work, none of it touching
substrate or guest code.
lib-guest.md: rewrites Architectural framing as a 5-layer stack
(substrate → lib/guest → languages → shared/ → applications),
recursive dependency-direction rule, scaled two-consumer rule. Adds
Phase B (long-running stratification) with sub-layer matrix
(core/typed/relational/effects/layout/lazy/oo), language profiles, and
the long-running-discipline section. Preserves existing Phase A
progress log and rules.
ocaml-on-sx.md: scope reduced to substrate validation + HM + reference
oracle. Phases 1-5 + minimal stdlib slice + vendored testsuite slice.
Dream carved out into dream-on-sx.md; Phase 8 (ReasonML) deferred.
Records lib-guest sequencing dependency.
datalog-on-sx.md: adds Phase 4 built-in predicates + body arithmetic,
Phase 6 magic sets, safety analysis in Phase 3, Non-goals section.
New chisel plans (forward-looking, not yet launchable):
kernel-on-sx.md — first-class everything, env-as-value endgame
idris-on-sx.md — dependent types, evidence chisel
probabilistic-on-sx.md — weighted nondeterminism + traces
maude-on-sx.md — rewriting as primitive
linear-on-sx.md — resource model, artdag-relevant
Loop briefings (4 active, 1 cold):
minikanren-loop.md, ocaml-loop.md, datalog-loop.md, elm-loop.md, koka-loop.md
Restore scripts mirror the loop pattern:
restore-{minikanren,ocaml,datalog,jit-perf,lib-guest}.sh
Each captures worktree state, plan progress, MCP health, tmux status.
Includes the .mcp.json absolute-path patch instruction (fresh worktrees
have no _build/, so the relative mcp_tree path fails on first launch).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.3 KiB
Dream-on-SX: OCaml's Dream web framework on the SX CEK
[deferred — depends on ocaml-on-sx + a target user]
Carved out of plans/ocaml-on-sx.md. The OCaml-on-SX plan was scoped down to substrate validation + HM + reference oracle (Phases 1–5 + minimal stdlib slice). Dream is the practical alternative-stack story — the opposite framing — and only makes sense if a real user wants to write rose-ash apps in OCaml/Dream.
Do not start without:
- OCaml-on-SX Phases 1–5 + Phase 6 minimal stdlib green.
- A concrete target user. "OCaml programmers in general" is not a target. "Person X wants to write feature Y on rose-ash in Dream" is.
If those conditions are not met, this plan stays cold.
Why this might be worth doing (when the time comes)
Dream is the cleanest middleware-shaped HTTP framework in any language:
handler = request -> response promisemiddleware = handler -> handlerm1 @@ m2 @@ handler— left-fold composition
It maps onto SX with almost no impedance — @@ is function composition, request → response promise is (perform (:http-respond ...)), middleware chain is plain SX function composition. So the integration cost is low if the OCaml-on-SX foundation is in place.
The user-facing story: rose-ash users who'd never touch s-expressions might write Dream/OCaml apps that integrate with the same federation, auth, and storage primitives. Demo: a Dream app serving sx.rose-ash.com — the framework that describes the runtime it runs on.
Dream semantic mappings
| Dream construct | SX mapping |
|---|---|
handler = request -> response promise |
(fn (req) (perform (:http-respond ...))) |
middleware = handler -> handler |
(fn (next) (fn (req) ...)) |
Dream.router [routes] |
(ocaml-dream-router routes) — dispatch on method+path |
Dream.get "/path" h |
route record {:method "GET" :path "/path" :handler h} |
Dream.scope "/p" [ms] [rs] |
prefix mount with middleware chain |
Dream.param req "name" |
path param extracted during routing |
m1 @@ m2 @@ handler |
(m1 (m2 handler)) — left-fold composition |
Dream.session_field req "k" |
(perform (:session-get req "k")) |
Dream.set_session_field req "k" v |
(perform (:session-set req "k" v)) |
Dream.flash req |
(perform (:flash-get req)) |
Dream.form req |
(perform (:form-parse req)) — returns Ok/Error ADT |
Dream.websocket handler |
(perform (:websocket handler)) |
Dream.run handler |
starts SX HTTP server with handler as root |
Roadmap
The five types: request, response, handler = request -> response, middleware = handler -> handler, route. Everything else is a function over these.
- Core types in
lib/dream/types.sx: request/response records, route record. - Router in
lib/dream/router.sx: -dream-get path handler,dream-post path handler, etc. for all HTTP methods. -dream-scope prefix middlewares routes— prefix mount with middleware chain. -dream-router routes— dispatch tree, returns handler; no match → 404. - Path param extraction::namesegments,**wildcard. -dream-param req name— retrieve matched path param. - Middleware in
lib/dream/middleware.sx: -dream-pipeline middlewares handler— compose middleware left-to-right. -dream-no-middleware— identity. - Logger:(dream-logger next req)— logs method, path, status, timing. - Content-type sniffer. - Sessions in
lib/dream/session.sx: - Cookie-backed session middleware. -dream-session-field req key,dream-set-session-field req key val. -dream-invalidate-session req. - Flash messages in
lib/dream/flash.sx: -dream-flash-middleware— single-request cookie store. -dream-add-flash-message req category msg. -dream-flash-messages req— returns list of(category, msg). - Forms + CSRF in
lib/dream/form.sx: -dream-form req— returns(Ok fields)or(Err :csrf-token-invalid). -dream-multipart req— streaming multipart form data. - CSRF middleware: stateless signed tokens, session-scoped. -dream-csrf-tag req— returns hidden input fragment for SX templates. - WebSockets in
lib/dream/websocket.sx: -dream-websocket handler— upgrades request; handler(fn (ws) ...). -dream-send ws msg,dream-receive ws,dream-close ws. - Static files:
dream-static root-path— serves files, ETags, range requests. dream-run: wires root handler into SX'sperform (:http-listen ...).- Demos in
lib/dream/demos/: -hello.ml→lib/dream/demos/hello.sx: "Hello, World!" route. -counter.ml→lib/dream/demos/counter.sx: in-memory counter with sessions. -chat.ml→lib/dream/demos/chat.sx: multi-room WebSocket chat. -todo.ml→lib/dream/demos/todo.sx: CRUD list with forms + CSRF. - Tests in
lib/dream/tests/: routing dispatch, middleware composition, session round-trip, CSRF accept/reject, flash read-after-write — 60+ tests.
Stdlib additions Dream will need
Dream pushes beyond OCaml-on-SX's Phase 6 minimal stdlib slice. When this plan activates, OCaml-on-SX gets a follow-on phase that adds at minimum:
Bytes(binary buffers — request bodies, websocket frames)Buffer(mutable string building)Format(full pretty-printer, not justPrintf.sprintf)- More
String(index_opt,contains,starts_with,ends_with,replace_all) Sys(argv,getenv_opt,getcwd)Hashtblextensions (iter,fold,length,remove)Map.Make/Set.Makefunctors
Confirm scope before starting; some of these may be addable as Dream-internal helpers rather than full stdlib modules.
Ground rules
- Scope: only
lib/dream/**andplans/dream-on-sx.md. Plus the stdlib additions listed above which land inlib/ocaml/runtime.sx. - Hard prerequisite: OCaml-on-SX Phases 1–5 + Phase 6 minimal stdlib. Verify scoreboard before starting.
- SX files:
sx-treeMCP tools only. - Don't reinvent the SX HTTP server. Dream wraps the existing
perform (:http-listen ...)— it does not implement its own listener loop.
Progress log
(awaiting activation conditions)
Blockers
(none yet — plan is cold)