Brainstorm outcome (forks locked with the developer): - TLS: proxy-terminated (nginx/caddy gives browsers TLS+ALPN+h2; the framework speaks HTTP/1.1 behind it) — zero TLS in the toolchain, no doctrine fight; homegrown TLS refused outright. - Dependencies: a real mini package manager — wo.toml [deps] with exact-rev git deps, wo.lock, .wo-deps cache, `use <dep>` as a module root; fetch by shelling to the git binary (no network code in woc); flat-only v1. - HTTP/2: v1 is HTTP/1.1 keep-alive; h2c is the parked successor behind iterations 8/9f/11 (multiplexing needs a scheduler to pay off); the bytes/buffer type rides with it, not v1. - Handler model: no function values by doctrine, so Handler/Middleware are structural interfaces (ICALL dispatch, WO-E205-checked); middleware returns ?Resp and rides the shipped ?T narrowing. - Incubation: framework at docs/examples/writeonce-framework/, consuming storefront at docs/examples/web-app/ importing it THROUGH [deps] — the sample exercises fetch -> lock -> build -> serve -> durable-restart. - Iteration 10 relationship: service blocks later LOWER ONTO this library. Files: specs/2026-08-18-web-framework-design.md (A deps normative, B framework normative, C h2c parked); stories 15-deps-package-manager.md + 16-web-framework.md; roadmap + board rows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3.5 KiB
Iteration 16 — the web framework: a .wo library, HTTP/1.1 behind a proxy
Format: fiberloom
product/story-iteration-template. Part of Story — one language, one runtime, one database, one binary.Inserted 2026-08-18. The framework is written IN writeonce and imported like any dependency (iteration 15 is the prerequisite). TLS terminates at a reverse proxy — browsers get TLS+ALPN+h2 from nginx/caddy while the framework speaks HTTP/1.1 keep-alive behind it, so no TLS exists anywhere in the toolchain. h2c is the parked successor (after iterations 8/9f/11, when multiplexing has a scheduler to pay off on).
Spec exists:
2026-08-18-web-framework-design.mdsections B (normative) and C (the parked h2c successor).
Goals
- The framework, incubated at
docs/examples/writeonce-framework/: an HTTP/1.1 keep-alive server core (extracted from the soak-proven log-watchermcppattern), a method+path router with:paramcaptures,Req/Resprecords with builder helpers, and the no-function-values handler model —Handler/Middlewarestructural interfaces dispatched by ICALL, with WO-E205 making a non-conforming handler a compile error and?Respmiddleware short-circuiting on the shipped?Tnarrowing. - The consuming app,
docs/examples/web-app/: a small storefront (Product/Orderas@tableclasses, list/show/create routes, one auth middleware, JSON responses) that imports the framework through[deps]— the sample exercises the whole chain: fetch → lock → build → serve → durable data across restart. - Honest limits stated where users read them: single-threaded blocking (concurrency arrives underneath via iterations 8/11), no chunked encoding, no WebSockets, JSON-first (no templates — the removed UI track stays removed).
- Relationship to iteration 10 recorded in both:
serviceblocks later lower onto this library — compiler sugar over the same router, never a rival stack.
Acceptance Criteria
- Given the web-app sample, when
just web-appruns, then deps fetch, the app builds, serves list/show/create with@tablepersistence across a process restart, answers 404/400 correctly, a deliberately trapping handler returns 500 while the server survives, and SIGTERM stops it cleanly — fd- and resident-flat under the opt-in soak. - Given a handler class missing
handle, when the app compiles, then WO-E205 names the class and interface. - Given nginx in front (documented config), when a browser hits it, then the browser negotiates h2 with the proxy while the backend link is HTTP/1.1 — proving the TLS/h2 story without TLS in writeonce.
- Given the framework extracted to its own repository, when the app's
[deps]URL is updated, then nothing else changes (success criterion 4 of the spec).
Out Of Scope
TLS in the toolchain (proxy-terminated by decision); HTTP/2 + the bytes/buffer type (parked to the h2c successor, after 8/9f/11); chunked transfer encoding; WebSockets/SSE; templates/SSR; multipart uploads; performance work beyond the soak's flatness gate (benchmarks belong to 9e's measurement backbone).
Proposed Solution
Framework modules http/, router/, app.wo as spec §B lays out; the
web-app acceptance script is the gate (curl matrix + restart + stop + soak);
just web-app wires fetch-build-serve-verify into one command. Plan follows
after this iteration is approved on the board.