From ffd791d05be17bf396e624fbae57e1a4514d2816 Mon Sep 17 00:00:00 2001 From: "shoney.arickathil" Date: Wed, 26 Aug 2026 19:36:34 +0200 Subject: [PATCH] refactor(porch): name the web framework `porch`, fix the wo.toml identifier claim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/examples/writeonce-serve -> docs/examples/porch (git mv, history kept); `[deps]` key and import are now `porch` / `porch/http` / `porch/router` - name history preserved on the library README, not rewritten into dated records: writeonce-framework -> writeonce-serve (08-25) -> porch (08-26). Stories, specs, plans and the audit reports keep the older name by the repo's own convention; only live docs and every path link were rewritten - left alone deliberately: `internal/serve.wo`, `pub fn serve`, `serve_conn`, `app.serve(...)` — those are functions, not the module name - web-app/wo.toml comment corrected: it claimed hyphens are not identifier characters and named a key this file never used. lexer.ml's `is_ident_cont` DOES accept `-` (an internal dash is part of the identifier, which is why binary minus needs spaces), so a hyphenated key would be legal too - site now teaches the name: package card, the two-deps chapter and the handlers-are-classes chapter say `porch`; site-accept asserted the old /packages/serve route and caught the rename, as a gate should - gates: web-app 46/0, site 21/0, deps-accept 8/0, oop-e2e 116/0, linkcheck 0 broken / 0 anchors; porch typechecks entry-less as kind=library Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 10 +++++----- docs/00-doc-audit.md | 4 ++-- .../{writeonce-serve => porch}/README.md | 20 +++++++++++++------ .../{writeonce-serve => porch}/app.wo | 0 .../{writeonce-serve => porch}/http/auth.wo | 0 .../{writeonce-serve => porch}/http/files.wo | 0 .../{writeonce-serve => porch}/http/form.wo | 0 .../http/multipart.wo | 0 .../{writeonce-serve => porch}/http/nego.wo | 0 .../{writeonce-serve => porch}/http/secure.wo | 0 .../{writeonce-serve => porch}/http/types.wo | 0 .../{writeonce-serve => porch}/http/ws.wo | 0 .../http/wsframe.wo | 0 .../internal/parse.wo | 0 .../internal/serve.wo | 0 .../router/router.wo | 0 .../{writeonce-serve => porch}/wo.toml | 4 ++-- docs/examples/shop/layout/app.wo | 2 +- docs/examples/shop/main.wo | 6 +++--- docs/examples/shop/orders/controller.wo | 2 +- docs/examples/shop/product_list/controller.wo | 2 +- docs/examples/shop/product_page/controller.wo | 2 +- docs/examples/shop/wo.toml | 2 +- docs/examples/site/README.md | 2 +- docs/examples/site/admin/controller.wo | 2 +- docs/examples/site/chapter/controller.wo | 2 +- docs/examples/site/content.wo | 10 +++++----- docs/examples/site/favicon/controller.wo | 2 +- docs/examples/site/health/controller.wo | 2 +- docs/examples/site/home/controller.wo | 2 +- docs/examples/site/install/controller.wo | 2 +- docs/examples/site/layout/app.wo | 2 +- docs/examples/site/main.wo | 8 ++++---- docs/examples/site/packages/controller.wo | 10 +++++----- docs/examples/site/wo.toml | 4 ++-- docs/examples/web-app/README.md | 2 +- docs/examples/web-app/main.wo | 8 ++++---- docs/examples/web-app/wo.toml | 15 +++++++++----- docs/plan/discarded.md | 2 +- .../plan/exploration/fiber/00-fiber-parity.md | 18 ++++++++--------- docs/stories/00-status.md | 4 ++-- .../language-runtime-database/00-story.md | 2 +- .../18-memory-db-features.md | 2 +- .../38-content-platform-capabilities.md | 4 ++-- .../39-web-framework-parity.md | 4 ++-- justfile | 4 ++-- scripts/site-accept.sh | 6 +++--- scripts/web-app-accept.sh | 8 ++++---- 48 files changed, 97 insertions(+), 84 deletions(-) rename docs/examples/{writeonce-serve => porch}/README.md (94%) rename docs/examples/{writeonce-serve => porch}/app.wo (100%) rename docs/examples/{writeonce-serve => porch}/http/auth.wo (100%) rename docs/examples/{writeonce-serve => porch}/http/files.wo (100%) rename docs/examples/{writeonce-serve => porch}/http/form.wo (100%) rename docs/examples/{writeonce-serve => porch}/http/multipart.wo (100%) rename docs/examples/{writeonce-serve => porch}/http/nego.wo (100%) rename docs/examples/{writeonce-serve => porch}/http/secure.wo (100%) rename docs/examples/{writeonce-serve => porch}/http/types.wo (100%) rename docs/examples/{writeonce-serve => porch}/http/ws.wo (100%) rename docs/examples/{writeonce-serve => porch}/http/wsframe.wo (100%) rename docs/examples/{writeonce-serve => porch}/internal/parse.wo (100%) rename docs/examples/{writeonce-serve => porch}/internal/serve.wo (100%) rename docs/examples/{writeonce-serve => porch}/router/router.wo (100%) rename docs/examples/{writeonce-serve => porch}/wo.toml (84%) diff --git a/README.md b/README.md index 1e8f2dd..6abc206 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ program ships as one file that depends only on the system C library. writeonce is a systems language whose distinguishing feature is the embedded database. HTTP/1.1 and WebSockets **do** work today — but as `.wo` libraries you -consume through `[deps]` (`writeonce-serve` for serving, `writeonce-view` for +consume through `[deps]` (`porch` for serving, `writeonce-view` for HTML), never as runtime features: the runtime stays framework-agnostic on purpose. TLS is always terminated by a proxy in front. If you have seen an older "writeonce" that served REST from `cargo run`, that was a separate, earlier @@ -282,13 +282,13 @@ dependencies, declared in the manifest: ```toml [deps] -serve = { git = "https://github.com/shoneyj/writeonce-serve", rev = "v0.1.0" } +porch = { git = "https://github.com/shoneyj/porch", rev = "v0.1.0" } ``` **The `[deps]` key IS the module name** `use` imports — the repository name never appears in your source. `woc` fetches each dep (via the `git` binary) -into `.wo-deps//`, pins the resolved commit in `wo.lock`, and `use serve` -(or `use serve/router`) imports its public names like any module. Builds never +into `.wo-deps//`, pins the resolved commit in `wo.lock`, and `use porch` +(or `use porch/router`) imports its public names like any module. Builds never touch the network once the lock is satisfied; a moved tag is reported, and `woc --update-deps myproject/` refreshes the lock deliberately. Flat dependencies only (a dep may not have its own `[deps]`) — honest and small, @@ -318,7 +318,7 @@ reading first: just employee # compile + run every mode against a durable database ``` -- **`docs/examples/writeonce-serve/` + `docs/examples/web-app/`** — a web +- **`docs/examples/porch/` + `docs/examples/web-app/`** — a web framework written in writeonce (HTTP/1.1 behind a TLS-terminating proxy, router with `:param` captures, interface-based handlers) and a storefront consuming it **as a `[deps]` dependency**, with `@table` persistence. Run: diff --git a/docs/00-doc-audit.md b/docs/00-doc-audit.md index edfa61c..e474c1e 100644 --- a/docs/00-doc-audit.md +++ b/docs/00-doc-audit.md @@ -65,13 +65,13 @@ Three of its six entries have shipped: > WebSockets, or a UI." Contradicted 30 lines later by its own §"Worked examples" (`:306-313`), which -describes `docs/examples/writeonce-serve/` as "a web framework written in +describes `docs/examples/porch/` as "a web framework written in writeonce (HTTP/1.1 …, router with `:param` captures, interface-based handlers)" and `just web-app` as its gate. Also contradicted by: - iteration 16 (web framework) and 37 (wo-html components), both `done/`; - `docs/examples/site/` — server-rendered pages, gated by `just site`; -- WebSockets: `docs/examples/writeonce-serve/http/ws.wo` (`ws_accept`, the 101 +- WebSockets: `docs/examples/porch/http/ws.wo` (`ws_accept`, the 101 hijack sentinel) and `http/wsframe.wo` (a pure-`.wo` RFC 6455 frame codec), both landed per `docs/in-progress/2026-08-23-chat-ws-lifecycle.md` (T6, T7). diff --git a/docs/examples/writeonce-serve/README.md b/docs/examples/porch/README.md similarity index 94% rename from docs/examples/writeonce-serve/README.md rename to docs/examples/porch/README.md index 4e40b99..b824521 100644 --- a/docs/examples/writeonce-serve/README.md +++ b/docs/examples/porch/README.md @@ -1,14 +1,22 @@ -# writeonce-serve -> Renamed 2026-08-25: this library was `writeonce-framework`, imported as -> `use framework`. Stories, specs and plans dated before that still say the -> old name — they are dated records and were left as written. +# porch — the writeonce web framework + +> **Named `porch` on 2026-08-26.** Rename history: `writeonce-framework` +> (`use framework`) → `writeonce-serve` (`use serve`, 2026-08-25) → **`porch`** +> (`use porch`). Stories, specs, plans and the audit reports dated before each +> change still say the older name — they are dated records and were left as +> written, which is the repo's convention. +> +> Why `porch`: the structure in front of the house you actually enter through, +> and in writeonce the house *is* the database. The name appears only in `use` +> lines and the `[deps]` key — names resolve bare through `use` edges, so no +> handler body mentions it. A web framework **written in writeonce**, consumed as a `[deps]` dependency (iteration 15). Spec: `docs/superpowers/specs/2026-08-18-web-framework-design.md` §B. ```toml [deps] -writeonce-serve = { git = "https://github.com/shoneyj/writeonce-serve", rev = "v0.1.0" } +porch = { git = "https://github.com/shoneyj/porch", rev = "v0.1.0" } ``` ## What it is @@ -184,7 +192,7 @@ naming the kind, unless a demo `main` is added (lib+bin is allowed). - **`internal/` — not importable by a consumer.** The connection-level request parser and carry-state record (`parse.wo`) and the serve loop, status text, and response serializer (`serve.wo`) live here. A consuming app that writes - `use writeonce-serve/internal` gets **WO-E108** at that `use`. The rule + `use porch/internal` gets **WO-E108** at that `use`. The rule is Go's: a path segment named `internal` is refused across the `[deps]` boundary only — the framework's own modules import it freely. diff --git a/docs/examples/writeonce-serve/app.wo b/docs/examples/porch/app.wo similarity index 100% rename from docs/examples/writeonce-serve/app.wo rename to docs/examples/porch/app.wo diff --git a/docs/examples/writeonce-serve/http/auth.wo b/docs/examples/porch/http/auth.wo similarity index 100% rename from docs/examples/writeonce-serve/http/auth.wo rename to docs/examples/porch/http/auth.wo diff --git a/docs/examples/writeonce-serve/http/files.wo b/docs/examples/porch/http/files.wo similarity index 100% rename from docs/examples/writeonce-serve/http/files.wo rename to docs/examples/porch/http/files.wo diff --git a/docs/examples/writeonce-serve/http/form.wo b/docs/examples/porch/http/form.wo similarity index 100% rename from docs/examples/writeonce-serve/http/form.wo rename to docs/examples/porch/http/form.wo diff --git a/docs/examples/writeonce-serve/http/multipart.wo b/docs/examples/porch/http/multipart.wo similarity index 100% rename from docs/examples/writeonce-serve/http/multipart.wo rename to docs/examples/porch/http/multipart.wo diff --git a/docs/examples/writeonce-serve/http/nego.wo b/docs/examples/porch/http/nego.wo similarity index 100% rename from docs/examples/writeonce-serve/http/nego.wo rename to docs/examples/porch/http/nego.wo diff --git a/docs/examples/writeonce-serve/http/secure.wo b/docs/examples/porch/http/secure.wo similarity index 100% rename from docs/examples/writeonce-serve/http/secure.wo rename to docs/examples/porch/http/secure.wo diff --git a/docs/examples/writeonce-serve/http/types.wo b/docs/examples/porch/http/types.wo similarity index 100% rename from docs/examples/writeonce-serve/http/types.wo rename to docs/examples/porch/http/types.wo diff --git a/docs/examples/writeonce-serve/http/ws.wo b/docs/examples/porch/http/ws.wo similarity index 100% rename from docs/examples/writeonce-serve/http/ws.wo rename to docs/examples/porch/http/ws.wo diff --git a/docs/examples/writeonce-serve/http/wsframe.wo b/docs/examples/porch/http/wsframe.wo similarity index 100% rename from docs/examples/writeonce-serve/http/wsframe.wo rename to docs/examples/porch/http/wsframe.wo diff --git a/docs/examples/writeonce-serve/internal/parse.wo b/docs/examples/porch/internal/parse.wo similarity index 100% rename from docs/examples/writeonce-serve/internal/parse.wo rename to docs/examples/porch/internal/parse.wo diff --git a/docs/examples/writeonce-serve/internal/serve.wo b/docs/examples/porch/internal/serve.wo similarity index 100% rename from docs/examples/writeonce-serve/internal/serve.wo rename to docs/examples/porch/internal/serve.wo diff --git a/docs/examples/writeonce-serve/router/router.wo b/docs/examples/porch/router/router.wo similarity index 100% rename from docs/examples/writeonce-serve/router/router.wo rename to docs/examples/porch/router/router.wo diff --git a/docs/examples/writeonce-serve/wo.toml b/docs/examples/porch/wo.toml similarity index 84% rename from docs/examples/writeonce-serve/wo.toml rename to docs/examples/porch/wo.toml index 3428f49..739f562 100644 --- a/docs/examples/writeonce-serve/wo.toml +++ b/docs/examples/porch/wo.toml @@ -1,4 +1,4 @@ -name = "writeonce-serve" +name = "porch" kind = "library" version = "0.1.0" description = "A web framework written in writeonce: HTTP/1.1 keep-alive server core, router with :param captures, Handler/Middleware structural interfaces (iteration 16)" @@ -9,4 +9,4 @@ wo = ">= 0.1" # A LIBRARY project (declared above since iteration 17): no `fn main` here — # the consuming app owns the entry. `woc ` typechecks the whole project. # Apps import this repo through `wo.toml [deps]` (iteration 15) and -# `use serve` / `use serve/http` / `use serve/router`. +# `use porch` / `use porch/http` / `use porch/router`. diff --git a/docs/examples/shop/layout/app.wo b/docs/examples/shop/layout/app.wo index 309a3c7..9d0309c 100644 --- a/docs/examples/shop/layout/app.wo +++ b/docs/examples/shop/layout/app.wo @@ -2,7 +2,7 @@ -- wrapping every page with the shared header and footer. Styles are NOT -- inlined — pages link /assets/style.css (served by static_files), so -- markup and styling stay separate files. -use serve/http +use porch/http use view -- The app shell as a COMPONENT (writeonce-view's `Component`: fields in, Text diff --git a/docs/examples/shop/main.wo b/docs/examples/shop/main.wo index 1bacd3d..07672c5 100644 --- a/docs/examples/shop/main.wo +++ b/docs/examples/shop/main.wo @@ -4,9 +4,9 @@ -- -- WO_DATA=./data ./target/shop 8080 (run from the shop directory: -- /assets/* serves from ./assets) -use serve -use serve/http -use serve/router +use porch +use porch/http +use porch/router use product_list use product_page use orders diff --git a/docs/examples/shop/orders/controller.wo b/docs/examples/shop/orders/controller.wo index 54906f9..edfc2e4 100644 --- a/docs/examples/shop/orders/controller.wo +++ b/docs/examples/shop/orders/controller.wo @@ -1,7 +1,7 @@ -- orders/controller.wo — the buying flow: stock-checked order creation -- (decrement + insert are each WAL-committed before they acknowledge) -- and the orders list (ref navigation: o.product.name). -use serve/http +use porch/http use layout use time diff --git a/docs/examples/shop/product_list/controller.wo b/docs/examples/shop/product_list/controller.wo index 05006ca..da69d39 100644 --- a/docs/examples/shop/product_list/controller.wo +++ b/docs/examples/shop/product_list/controller.wo @@ -3,7 +3,7 @@ -- directory = one module, view and controller together. The @tables it -- queries live in the root module, which is fine: a CLASS is reachable -- across module lines (only free `fn`s are module-scoped). -use serve/http +use porch/http use layout pub class ListProducts { diff --git a/docs/examples/shop/product_page/controller.wo b/docs/examples/shop/product_page/controller.wo index 4933572..f7ac6e6 100644 --- a/docs/examples/shop/product_page/controller.wo +++ b/docs/examples/shop/product_page/controller.wo @@ -1,5 +1,5 @@ -- product_page/controller.wo — the CONTROLLER for /p/:sku. -use serve/http +use porch/http use layout pub class ShowProduct { diff --git a/docs/examples/shop/wo.toml b/docs/examples/shop/wo.toml index 56b0879..7f1b0a2 100644 --- a/docs/examples/shop/wo.toml +++ b/docs/examples/shop/wo.toml @@ -8,5 +8,5 @@ wo = ">= 0.1" # Two library dependencies, the site sample's proven shape. The [deps] # KEY is the module name `use` imports. [deps] -serve = { git = "https://github.com/shoneyj/writeonce-serve", rev = "v0.1.0" } +porch = { git = "https://github.com/shoneyj/porch", rev = "v0.1.0" } view = { git = "https://github.com/shoneyj/writeonce-view", rev = "v0.1.0" } diff --git a/docs/examples/site/README.md b/docs/examples/site/README.md index 9b94bf8..eff6c72 100644 --- a/docs/examples/site/README.md +++ b/docs/examples/site/README.md @@ -7,7 +7,7 @@ the whole thing is chapter 9's own example. ``` [deps] -serve = { git = "https://github.com/shoneyj/writeonce-serve", rev = "v0.1.0" } +porch = { git = "https://github.com/shoneyj/porch", rev = "v0.1.0" } view = { git = "https://github.com/shoneyj/writeonce-view", rev = "v0.1.0" } ``` diff --git a/docs/examples/site/admin/controller.wo b/docs/examples/site/admin/controller.wo index 7a7153b..244a7bb 100644 --- a/docs/examples/site/admin/controller.wo +++ b/docs/examples/site/admin/controller.wo @@ -2,7 +2,7 @@ -- form-encoded, bearer-gated. Mechanism (bearer_token, constant-time -- ct_eq) is the framework's; POLICY — which routes, which token — is -- this app's, right here. No rendering: the answer is a redirect. -use serve/http +use porch/http pub class AdminEdit { token: Text diff --git a/docs/examples/site/chapter/controller.wo b/docs/examples/site/chapter/controller.wo index bba391d..36493f0 100644 --- a/docs/examples/site/chapter/controller.wo +++ b/docs/examples/site/chapter/controller.wo @@ -1,7 +1,7 @@ -- chapter/controller.wo — the CONTROLLER for `/ch/:slug`. It queries the -- model and fills the view components that sit beside it in this module; -- a view receives VALUES, never a cursor. -use serve/http +use porch/http use layout pub class ShowChapter { diff --git a/docs/examples/site/content.wo b/docs/examples/site/content.wo index 885af22..1d0486a 100644 --- a/docs/examples/site/content.wo +++ b/docs/examples/site/content.wo @@ -33,7 +33,7 @@ fn ch_containers() -> Text { fn ch_classes() -> Text { let b = el("p", "leading-relaxed mb-4", - "Classes hold fields and methods. There are NO function values and NO closures — a " .. "deliberate doctrine: behavior travels as a class satisfying an interface, and " .. "satisfaction is structural (same method name and shape, Go-style, no " .. "implements). This is how the web framework takes handlers."); + "Classes hold fields and methods. There are NO function values and NO closures — a " .. "deliberate doctrine: behavior travels as a class satisfying an interface, and " .. "satisfaction is structural (same method name and shape, Go-style, no " .. "implements). This is how porch, the web framework, takes handlers."); b = b .. code_block("interface Handler {\n fn handle(req: Req) -> Resp\n}\n\nclass Hello {\n greeting: Text\n fn handle(req: Req) -> Resp {\n return ok_text(\"\${self.greeting}, \${req.path}\");\n }\n}\n\n-- any class with a matching handle() satisfies Handler\napp.get(\"/hello\", Hello { greeting: \"hi\" });"); return b; } @@ -61,14 +61,14 @@ fn ch_actors() -> Text { fn ch_deps() -> Text { let b = el("p", "leading-relaxed mb-4", - "Dependencies are git repositories pinned in wo.toml; wo.lock " .. "records the exact revision, and locked builds work offline. The [deps] KEY names the " .. "module you use. This site has two: the web framework, and the writeonce-view " .. "library that rendered the page you are reading."); + "Dependencies are git repositories pinned in wo.toml; wo.lock " .. "records the exact revision, and locked builds work offline. The [deps] KEY names the " .. "module you use. This site has two: porch, the writeonce web framework, and the writeonce-view " .. "library that rendered the page you are reading."); b = b .. code_block(` [deps] - serve = { git = "https://github.com/shoneyj/writeonce-serve", rev = "v0.1.0" } + porch = { git = "https://github.com/shoneyj/porch", rev = "v0.1.0" } view = { git = "https://github.com/shoneyj/writeonce-view", rev = "v0.1.0" }`); b = b .. code_block(` - use serve - use serve/http + use porch + use porch/http use view -- html's builders + tailwind-style utilities, zero JS, no build step: diff --git a/docs/examples/site/favicon/controller.wo b/docs/examples/site/favicon/controller.wo index f6654a6..18b8dc6 100644 --- a/docs/examples/site/favicon/controller.wo +++ b/docs/examples/site/favicon/controller.wo @@ -1,6 +1,6 @@ -- favicon/controller.wo — GET /favicon.svg. The one route that answers -- something other than HTML or text, so it builds its own Resp. -use serve/http +use porch/http use layout pub class Favicon { diff --git a/docs/examples/site/health/controller.wo b/docs/examples/site/health/controller.wo index 80ebdd7..dac52b2 100644 --- a/docs/examples/site/health/controller.wo +++ b/docs/examples/site/health/controller.wo @@ -1,6 +1,6 @@ -- health.controller.wo — GET /health: the liveness probe the accept -- script and any proxy poll. Text, not HTML, on purpose. -use serve/http +use porch/http pub class Health { fn handle(req: Req) -> Resp { diff --git a/docs/examples/site/home/controller.wo b/docs/examples/site/home/controller.wo index 05f6234..d5e16a4 100644 --- a/docs/examples/site/home/controller.wo +++ b/docs/examples/site/home/controller.wo @@ -5,7 +5,7 @@ -- It reaches the chapter nav through `use chapter` and the query through -- the model's `Chapters.links()` static — a class crosses module lines, -- a free fn does not. -use serve/http +use porch/http use layout use chapter diff --git a/docs/examples/site/install/controller.wo b/docs/examples/site/install/controller.wo index 8ef9cc7..cd86c80 100644 --- a/docs/examples/site/install/controller.wo +++ b/docs/examples/site/install/controller.wo @@ -1,6 +1,6 @@ -- install/controller.wo — GET /install. Nothing to query: the page is -- static copy, so the controller only wraps it in the shell. -use serve/http +use porch/http use layout pub class ShowInstall { diff --git a/docs/examples/site/layout/app.wo b/docs/examples/site/layout/app.wo index 28fcdd6..cb17852 100644 --- a/docs/examples/site/layout/app.wo +++ b/docs/examples/site/layout/app.wo @@ -6,7 +6,7 @@ -- The only thing that varies between pages is the container width, so -- that is the one extra slot — and the two widths are named once, here, -- instead of as class strings scattered through the controllers. -use serve/http +use porch/http use view pub class AppShell { diff --git a/docs/examples/site/main.wo b/docs/examples/site/main.wo index c3edbe8..fe3f66a 100644 --- a/docs/examples/site/main.wo +++ b/docs/examples/site/main.wo @@ -1,5 +1,5 @@ -- site — writeonce.de: the language tutorial, served BY the language. --- Full stack in one binary: writeonce-serve ([deps]) for HTTP/routing/ +-- Full stack in one binary: porch ([deps]) for HTTP/routing/ -- auth, writeonce-view ([deps]) for server-rendered pages with Tailwind-style -- utilities, @table + WAL for the chapters themselves. The site is its own -- final chapter: /ch/serving shows this file's shape. @@ -15,9 +15,9 @@ -- model is types.wo; every feature is a directory holding its view and -- its controller. use env -use serve -use serve/http -use serve/router +use porch +use porch/http +use porch/router use home use chapter use install diff --git a/docs/examples/site/packages/controller.wo b/docs/examples/site/packages/controller.wo index 2634ec4..311c56c 100644 --- a/docs/examples/site/packages/controller.wo +++ b/docs/examples/site/packages/controller.wo @@ -3,7 +3,7 @@ -- The catalogue is static data, not rows, so it lives here on the DATA -- side of the feature rather than in the view: the components are handed -- values exactly as they would be if this were a table one day. -use serve/http +use porch/http use view use layout @@ -54,9 +54,9 @@ fn catalogue() -> multi PackageInfo { let out: multi PackageInfo = []; push(out, PackageInfo { - name: "serve", - summary: "The web framework: an HTTP/1.1 keep-alive server core, a router with :param captures, and Handler/Middleware structural interfaces.", - git: "https://github.com/shoneyj/writeonce-serve", + name: "porch", + summary: "The writeonce web framework: an HTTP/1.1 keep-alive server core, a router with :param captures, and Handler/Middleware structural interfaces. Imported as use porch.", + git: "https://github.com/shoneyj/porch", rev: "v0.1.0", what: `
    @@ -67,7 +67,7 @@ fn catalogue() -> multi PackageInfo {
  • Auth MECHANISM only — bearer_token, basic_credentials, constant-time ct_eq. Which routes are gated stays your policy.
  • Bodies: form_values, multipart_parts, content negotiation, ETags, security headers, CORS, WebSocket frames.
`, - usage: code_block("use serve\nuse serve/http\nuse serve/router\n\nclass Hello {\n fn handle(req: Req) -> Resp {\n return ok_text(\"hello\");\n }\n}\n\nfn main(args: multi Text) -> Int {\n let app = App { middleware: [], routes: [] };\n app.use_mw(Mw { m: Logging {} });\n app.get(\"/\", Hello {});\n return app.serve(\"127.0.0.1\", 8080);\n}") + usage: code_block("use porch\nuse porch/http\nuse porch/router\n\nclass Hello {\n fn handle(req: Req) -> Resp {\n return ok_text(\"hello\");\n }\n}\n\nfn main(args: multi Text) -> Int {\n let app = App { middleware: [], routes: [] };\n app.use_mw(Mw { m: Logging {} });\n app.get(\"/\", Hello {});\n return app.serve(\"127.0.0.1\", 8080);\n}") }); push(out, PackageInfo { diff --git a/docs/examples/site/wo.toml b/docs/examples/site/wo.toml index 5f8648a..1ce7a92 100644 --- a/docs/examples/site/wo.toml +++ b/docs/examples/site/wo.toml @@ -6,8 +6,8 @@ description = "writeonce.de — the language tutorial served by the language: fr wo = ">= 0.1" # Two real dependencies (the gate substitutes file:// remotes built from -# docs/examples/writeonce-serve and docs/examples/writeonce-view, so CI never +# docs/examples/porch and docs/examples/writeonce-view, so CI never # touches the network). The [deps] KEY is the module name `use` imports. [deps] -serve = { git = "https://github.com/shoneyj/writeonce-serve", rev = "v0.1.0" } +porch = { git = "https://github.com/shoneyj/porch", rev = "v0.1.0" } view = { git = "https://github.com/shoneyj/writeonce-view", rev = "v0.1.0" } diff --git a/docs/examples/web-app/README.md b/docs/examples/web-app/README.md index 05e9f29..54d68bb 100644 --- a/docs/examples/web-app/README.md +++ b/docs/examples/web-app/README.md @@ -1,7 +1,7 @@ # web-app — the storefront sample A small store: `Product`/`Order` as `@table` classes, JSON routes, one auth -middleware — built on [`writeonce-serve`](../writeonce-serve/), which +middleware — built on [`porch`](../porch/), which it imports **through `[deps]`** (iteration 15). This app is iteration 16's acceptance workload: `just web-app` runs the whole chain — fetch → lock → build → serve → curl matrix → restart persistence → SIGTERM. diff --git a/docs/examples/web-app/main.wo b/docs/examples/web-app/main.wo index 57bf79a..e43419b 100644 --- a/docs/examples/web-app/main.wo +++ b/docs/examples/web-app/main.wo @@ -1,4 +1,4 @@ --- web-app — the storefront: writeonce-serve (via [deps]) + @table +-- web-app — the storefront: porch (via [deps]) + @table -- persistence. Every handler is a class satisfying Handler; the auth gate is -- a Middleware; the data layer is the language's own database — no ORM, no -- separate process, one binary. @@ -6,9 +6,9 @@ use env use json use net use time -use serve -use serve/http -use serve/router +use porch +use porch/http +use porch/router -- decode target for POST /products, encode shape for every product answer typedef ProductView = { name: Text, price: Float, stock: Int } diff --git a/docs/examples/web-app/wo.toml b/docs/examples/web-app/wo.toml index 5fbad02..a7c00c6 100644 --- a/docs/examples/web-app/wo.toml +++ b/docs/examples/web-app/wo.toml @@ -1,6 +1,6 @@ name = "web-app" version = "0.1.0" -description = "Storefront sample: consumes writeonce-serve through [deps]; @table persistence; iteration 16's acceptance workload" +description = "Storefront sample: consumes porch through [deps]; @table persistence; iteration 16's acceptance workload" [runtime] wo = ">= 0.1" @@ -11,9 +11,14 @@ wo = ">= 0.1" # The framework is a real dependency, never a relative path — extraction of # the framework to its own repository changes only this URL. The acceptance # gate (scripts/web-app-accept.sh) substitutes a run-time file:// remote -# built from docs/examples/writeonce-serve, so CI never needs the +# built from docs/examples/porch, so CI never needs the # network and this repo never carries .wo-deps/wo.lock artifacts. -# The [deps] KEY is the module name `use` imports (hyphens are not identifier -# characters, so the key is `framework` while the repository keeps its name). +# The [deps] KEY is the module name `use` imports — here `porch`, so the source +# says `use porch`. The key must be a legal identifier, which per +# compiler/src/lexer.ml's `is_ident_cont` DOES include `-` (an internal dash is +# part of the identifier: `a-b` is one name, which is why binary minus needs +# spaces around it). So a hyphenated key like `wo-serve` would be legal too; +# `porch` is simply shorter. An earlier version of this comment claimed hyphens +# were illegal and named a key this file has never used — both wrong. [deps] -serve = { git = "https://github.com/shoneyj/writeonce-serve", rev = "v0.1.0" } +porch = { git = "https://github.com/shoneyj/porch", rev = "v0.1.0" } diff --git a/docs/plan/discarded.md b/docs/plan/discarded.md index cf619f7..edd5467 100644 --- a/docs/plan/discarded.md +++ b/docs/plan/discarded.md @@ -78,7 +78,7 @@ goes to find what took each one's place. | `08-sendfile-static-assets.md` | Nothing. `sendfile` is not exposed; static assets are served as `Text` through `net.write` | | `15-mcp-streamable-http.md` | [`28-skillhost-host-workload.md`](../stories/language-runtime-database/28-skillhost-host-workload.md) — MCP transport is that story's Blocker B | | `16-postgres-mirror.md` | Nothing — the mirror-is-backup doctrine holds, but no iteration owns it and there are no outbound sockets to reach a mirror with ([`refine/38`](../stories/language-runtime-database/38-content-platform-capabilities.md)) | -| `02-event-loop-epoll.md`, `03-hand-rolled-http.md` | `runtime/src/park.c` (io_uring with an epoll fallback) and the `.wo` framework `writeonce-serve` | +| `02-event-loop-epoll.md`, `03-hand-rolled-http.md` | `runtime/src/park.c` (io_uring with an epoll fallback) and the `.wo` framework `porch` | | `04-cutover-remove-tokio-axum.md` | Completed by the Rust-track removal itself — nothing left to cut over | | `runtime/database/03-inmemory-engine.md` | [`database/src/CODE-LOGIC.md`](../../database/src/CODE-LOGIC.md) + [`plan/oop-vm/04-db-binding.md`](oop-vm/04-db-binding.md) | | `runtime/database/02-wo-language.md` | [`docs/guides/language-surface.md`](../guides/language-surface.md) | diff --git a/docs/plan/exploration/fiber/00-fiber-parity.md b/docs/plan/exploration/fiber/00-fiber-parity.md index 503d6f1..650782d 100644 --- a/docs/plan/exploration/fiber/00-fiber-parity.md +++ b/docs/plan/exploration/fiber/00-fiber-parity.md @@ -1,14 +1,14 @@ -# Fiber parity study — what a mainstream Go web framework ships that `writeonce-serve` does not +# Fiber parity study — what a mainstream Go web framework ships that `porch` does not Reference: [gofiber/fiber](https://github.com/gofiber/fiber) **v3.5.0**, read 2026-08-26 from a shallow clone at `.dev/reference/fiber` (gitignored — re-clone with `git clone --depth 1 https://github.com/gofiber/fiber .dev/reference/fiber`). -Read against `docs/examples/writeonce-serve` as it stands the same day. +Read against `docs/examples/porch` as it stands the same day. Why Fiber and not Express or Axum: it is the closest structural analogue in the reference set. Compiled language, no runtime, one binary, an explicit `Ctx`-per-request, and middleware as an ordered chain — the same shape -`writeonce-serve` already has. Where it differs, the difference is a feature +`porch` already has. Where it differs, the difference is a feature decision rather than a paradigm gap, which is what makes the comparison useful. Express would have contributed mostly "you have no closures". @@ -17,8 +17,8 @@ What was actually read: `app.go` (routing methods, the 53-field `Config`), (binding), `hooks.go` (lifecycle), and the `Config` struct of every one of the **32** packages under `middleware/`. -**Headline: `writeonce-serve` is further along than its size suggests.** Of -Fiber's 32 middleware packages, 9 already have a working `writeonce-serve` +**Headline: `porch` is further along than its size suggests.** Of +Fiber's 32 middleware packages, 9 already have a working `porch` counterpart (CORS, basic auth, key/bearer auth, helmet-style security headers, ETag, static files, logger, host authorization, recover-as-500). The gaps are real but they are mostly *breadth*, and they cluster around four things: @@ -31,7 +31,7 @@ primitive nobody had noticed**. ## 0. The blocker the existing ledger gets wrong -`docs/examples/writeonce-serve/README.md`'s crypto row currently reads: +`docs/examples/porch/README.md`'s crypto row currently reads: > Unlocks (signed cookies, CSRF, session integrity, webhook verification, JWT > HS256) | ⬜ **UNBLOCKED** (the primitives exist since iteration 34) @@ -64,7 +64,7 @@ This is the study's most valuable single finding and it is the reason iteration ## 1. Cookies — absent, and foundational -`writeonce-serve` has **no cookie support in either direction**. `Req` has +`porch` has **no cookie support in either direction**. `Req` has `headers: map` and nothing parses `Cookie:`; `Resp` has `headers: map` and there is no `Set-Cookie` builder — and because `Resp.headers` is a *map*, it structurally cannot carry the two `Set-Cookie` @@ -75,7 +75,7 @@ Fiber, for comparison: `Req.Cookies(key)`, `Res.Cookie(*Cookie)` with `ClearCookie`, and a `Cookie` struct carrying Path, Domain, MaxAge, Expires, Secure, HTTPOnly, SameSite, Partitioned and SessionOnly. -| Piece | Fiber | writeonce-serve | +| Piece | Fiber | porch | | --- | --- | --- | | read request cookies | `Req.Cookies(key)` | — | | set a response cookie | `Res.Cookie(&Cookie{...})` | — | @@ -156,7 +156,7 @@ stdlib doing its job, not a defect. ## 5. Routing and response ergonomics — mostly sugar, cheap to close -| Gap | Fiber | writeonce-serve | +| Gap | Fiber | porch | | --- | --- | --- | | method helpers | Get/Post/Put/Delete/Patch/Head/Options/Trace/Connect/All/Add | `get`/`post`/`put`/`delete_` only — a `Route { method: "PATCH" }` literal works, so this is registration sugar, but its absence is felt | | route names + URL building | `Name()`, `GetRouteURL()` | — (no named routes, no reverse routing) | diff --git a/docs/stories/00-status.md b/docs/stories/00-status.md index f13bad8..c326c8c 100644 --- a/docs/stories/00-status.md +++ b/docs/stories/00-status.md @@ -227,7 +227,7 @@ sees through Interp; same corpus pin). Body-parsing hooks: all three ✅. Scope split (2026-08-20): the surface above plus the remaining transport/ routing/security gaps is **framework v1**, tracked item-by-item in the -[framework README's status ledger](../examples/writeonce-serve/README.md) +[framework README's status ledger](../examples/porch/README.md) (✅/🔶/⬜/⏸/🔧 per feature — timeouts and Unix sockets need `net` runtime seams, crypto hashes need C builtins since the language has no bitwise operators, streaming/cancellation park behind 8/11). The memory-rich @@ -348,7 +348,7 @@ that sequences its tasks. Read one, approve, then the next starts. | 33 | [Single-file store](language-runtime-database/33-single-file-db.md) | ⬜ off-chain, small — `WO_DATA=.db` file form; driver-only (story written 2026-08-22) | | 34 | [Crypto builtins](language-runtime-database/34-crypto-builtins.md) | 🔄 **code landed** as 24's T1 (`d14fa9f`): `sha1`/`sha256`/`hmac_sha256`, ids 85–87 in `wob.h`, `runtime/src/crypto.c`, RFC/FIPS vectors 18/0, corpus pin. The 24 gate that once needed it is cleared. Frontmatter keeps `status: refine` only until 24's T10 closeout sets it to `done` | | 38 | [Content platform capabilities](language-runtime-database/38-content-platform-capabilities.md) | ⬜ off-chain, needs a spec — the two capability families no iteration owns, confirmed against `runtime/src/wob.h`: `fs` mutation verbs (six fs builtins, ids 40–45; `append` creates-if-absent, so nothing is ever replaced, truncated, deleted or renamed) and `net.connect` (ids 51–55 + 91–95, no connect, and no `connect()` anywhere in `runtime/src/` — so no OIDC/SMTP/object-store/webhook/federation). Driven by a `docs/examples/vault` content-collaboration workload, in 28's mould. New builtins from 96 (89/90 reserved for 31); no `.wob` bump (`WOB_VERSION 6u`, last moved by 36). Story written 2026-08-26 from the "can it build a Nextcloud?" ask | -| 39 | [Web framework parity](language-runtime-database/39-web-framework-parity.md) | ⬜ off-chain, needs a spec — from [the Fiber v3.5.0 study](../plan/exploration/fiber/00-fiber-parity.md) (all 32 of its middleware read against `writeonce-serve`; **nine already have a counterpart**). Leads with a **random-bytes builtin**: the framework ledger claimed CSRF/sessions were unblocked by iteration 34's HMAC, but HMAC authenticates a token and cannot mint one — there is no RNG anywhere in the runtime. Then cookies (absent both ways; `Resp.headers` being a map cannot carry two `Set-Cookie` lines), then limiter/idempotency (cheapest wins — `@table` + `time.ticks`, nothing new), sessions, CSRF, and the routing/response sugar. Streaming/SSE/compression, `@derive` binding, TTL cache, `proxy` and metrics all excluded with owners named | +| 39 | [Web framework parity](language-runtime-database/39-web-framework-parity.md) | ⬜ off-chain, needs a spec — from [the Fiber v3.5.0 study](../plan/exploration/fiber/00-fiber-parity.md) (all 32 of its middleware read against `porch`; **nine already have a counterpart**). Leads with a **random-bytes builtin**: the framework ledger claimed CSRF/sessions were unblocked by iteration 34's HMAC, but HMAC authenticates a token and cannot mint one — there is no RNG anywhere in the runtime. Then cookies (absent both ways; `Resp.headers` being a map cannot carry two `Set-Cookie` lines), then limiter/idempotency (cheapest wins — `@table` + `time.ticks`, nothing new), sessions, CSRF, and the routing/response sugar. Streaming/SSE/compression, `@derive` binding, TTL cache, `proxy` and metrics all excluded with owners named | | 37 | [wo-html components](language-runtime-database/37-wo-html-components.md) | ✅ off-chain — LANDED 2026-08-25. Raw text literal (backtick, margin stripped at lex time, `{{ }}` auto-escapes) + the component layer: `Component`/`render_all`/`Layout` in wo-html, `ok_html` moved into the framework, site and shop both migrated | | 35 | [net runtime seams](language-runtime-database/35-net-runtime-seams.md) | ⬜ off-chain — fd deadlines on the park plane, Unix sockets, peer address; owns the ledger's three 🔧 rows (story written 2026-08-22) | | 20 | [Cross-program tables](language-runtime-database/20-cross-program-tables.md) | ⏸ hold (2026-08-21); channel done (branch ipc-attach keeps its manifest) | diff --git a/docs/stories/language-runtime-database/00-story.md b/docs/stories/language-runtime-database/00-story.md index abf1d65..56d55a4 100644 --- a/docs/stories/language-runtime-database/00-story.md +++ b/docs/stories/language-runtime-database/00-story.md @@ -121,7 +121,7 @@ still pending IS the runtime-concurrency chain; order: | 30 | 28 | [skillhost host workload](28-skillhost-host-workload.md) | host-shaped driving workload naming runtime gaps — demoted with the framework goal. *(was 14)* | | 31 | 29 | [Compile-time metaprogramming](29-compile-time-metaprogramming.md) | `@derive(...)` from class-table metadata; held with the parked drain by the 2026-08-08 scope directive. *(was 13)* | | 32 | 38 | [Content platform capabilities](38-content-platform-capabilities.md) | **NEW 2026-08-26** — the two capability families nothing owns, read off `wob.h`: `fs` mutation (`write`/`remove`/`rename`/`mkdir` — the table holds exactly six fs builtins, ids 40–45, where `append` creates-if-absent and grows, so a file is never replaced, truncated, deleted or renamed) and `net.connect` (ids 51–55 + 91–95, no connect; no `connect()` call in `runtime/src/` at all — which is every identity/notification/federation story at once; 35 deferred connect-side timeouts as "no workload asks yet" — this is the ask). Driven by a `docs/examples/vault` content-collaboration workload in 28's mould; WebDAV, CRDT editing, previews and FTS each get a written verdict instead of an implication. New builtins start at 96 (89/90 are 31's reserved holes); no `.wob` bump. Off-chain, wants a spec. | -| 33 | 39 | [Web framework parity](39-web-framework-parity.md) | **NEW 2026-08-26** — gofiber/fiber v3.5.0 added as the web-framework reference and read end to end ([the study](../../plan/exploration/fiber/00-fiber-parity.md)); nine of its 32 middleware already have a `writeonce-serve` counterpart, so the gaps are breadth, not foundations — with one exception. The study's sharpest finding: the framework's own ledger said CSRF and sessions were UNBLOCKED because iteration 34 landed HMAC, but **there is no source of randomness in the runtime at all**, and an HMAC over a guessable session id is a signed guess. So 39 leads with a random-bytes builtin, then cookies (absent in both directions; `Resp.headers: map` structurally cannot emit two `Set-Cookie` lines), then the store-backed chain — limiter and idempotency first since they need only `@table` + `time.ticks`. Off-chain, wants a spec. | +| 33 | 39 | [Web framework parity](39-web-framework-parity.md) | **NEW 2026-08-26** — gofiber/fiber v3.5.0 added as the web-framework reference and read end to end ([the study](../../plan/exploration/fiber/00-fiber-parity.md)); nine of its 32 middleware already have a `porch` counterpart, so the gaps are breadth, not foundations — with one exception. The study's sharpest finding: the framework's own ledger said CSRF and sessions were UNBLOCKED because iteration 34 landed HMAC, but **there is no source of randomness in the runtime at all**, and an HMAC over a guessable session id is a signed guess. So 39 leads with a random-bytes builtin, then cookies (absent in both directions; `Resp.headers: map` structurally cannot emit two `Set-Cookie` lines), then the store-backed chain — limiter and idempotency first since they need only `@table` + `time.ticks`. Off-chain, wants a spec. | | ✅ | 17 | [library projects + `internal/`](17-library-projects-internal.md) | **LANDED 2026-08-20** — `kind = "library"` + entry-less check mode (retires the `--emit` workaround) and Go's `internal/` rule as WO-E108 at the consumer's `use`; driver-only, VM/GC untouched. `just web-app` 26/0 | diff --git a/docs/stories/language-runtime-database/18-memory-db-features.md b/docs/stories/language-runtime-database/18-memory-db-features.md index 33bb87a..c193f24 100644 --- a/docs/stories/language-runtime-database/18-memory-db-features.md +++ b/docs/stories/language-runtime-database/18-memory-db-features.md @@ -7,7 +7,7 @@ status: hold > **Scope label (2026-08-20): this iteration is FRAMEWORK V2.** Framework > v1 is the transport/routing/body/security surface tracked in the -> [framework README's status ledger](../../examples/writeonce-serve/README.md); +> [framework README's status ledger](../../examples/porch/README.md); > v2 is what the embedded store adds on top. v1 gaps land before or > alongside v2 as slices, per the ledger. diff --git a/docs/stories/language-runtime-database/38-content-platform-capabilities.md b/docs/stories/language-runtime-database/38-content-platform-capabilities.md index 2ffd6b1..95aa4f7 100644 --- a/docs/stories/language-runtime-database/38-content-platform-capabilities.md +++ b/docs/stories/language-runtime-database/38-content-platform-capabilities.md @@ -30,7 +30,7 @@ status: refine authenticated users, folders and documents as `@table` classes related by `ref`/`backlink`, multipart upload intake, content-addressed blobs, share grants with expiry, a version chain per document, a trash bucket, an - activity feed, and a server-rendered UI over `writeonce-serve` + + activity feed, and a server-rendered UI over `porch` + `writeonce-view`. Everything above the storage line is expressible on today's toolchain and is the part that ships. - **`fs` grows the mutation verbs.** The gap is not ergonomic. A blob store @@ -150,7 +150,7 @@ iteration 36's opcodes 42–46; stdlib builtins are a table row, exactly as iteration 35's 91–95 were. What already exists and needs no new capability, verified against the tree: -`http/multipart` and `http/auth` in `writeonce-serve`; `sha1`/`sha256`/ +`http/multipart` and `http/auth` in `porch`; `sha1`/`sha256`/ `hmac_sha256` (builtin ids 85–87) for content addressing, ETags and session tokens; `base64_encode`/`decode` and the `Bytes` carrier; `ws_accept` plus the pure-`.wo` RFC 6455 frame codec for the activity feed; `Component`/ diff --git a/docs/stories/language-runtime-database/39-web-framework-parity.md b/docs/stories/language-runtime-database/39-web-framework-parity.md index fe0951e..4013c89 100644 --- a/docs/stories/language-runtime-database/39-web-framework-parity.md +++ b/docs/stories/language-runtime-database/39-web-framework-parity.md @@ -12,7 +12,7 @@ status: refine > find the basic features the web framework lacks). Derived from > [the Fiber v3.5.0 parity study](../../plan/exploration/fiber/00-fiber-parity.md), > which read Fiber's routing surface, `Req`/`Res` API, binder and all 32 of its -> `middleware/` packages against `docs/examples/writeonce-serve`. This iteration +> `middleware/` packages against `docs/examples/porch`. This iteration > takes that study's §0–§2 plus the cheap half of §5; the study names an owner > for everything it leaves out. @@ -124,7 +124,7 @@ excluded because someone else owns it — the study's §7 is the full map. Fiber v3.5.0, `.dev/reference/fiber` (gitignored; the study carries the clone command). Of its 32 middleware packages, **nine already have a working -`writeonce-serve` counterpart** — CORS, basic auth, key/bearer auth, +`porch` counterpart** — CORS, basic auth, key/bearer auth, helmet-style security headers, ETag, static files, logger, host authorization, and recover-as-500. The framework is further along than its size suggests; the gaps are breadth, not foundations, with the single exception of randomness. diff --git a/justfile b/justfile index 9d66433..bd73e63 100644 --- a/justfile +++ b/justfile @@ -41,7 +41,7 @@ deps-accept: ./scripts/deps-accept.sh # web-app: iteration 16's gate — the whole chain at run time, network-free: -# a temp git remote from docs/examples/writeonce-serve, file:// URL +# a temp git remote from docs/examples/porch, file:// URL # substituted into a temp copy of docs/examples/web-app, then fetch -> lock # -> build -> serve -> the storefront matrix (auth/CRUD/@unique/FK/404/400/ # pipelining) -> SIGTERM -> WAL restart persistence. @@ -49,7 +49,7 @@ web-app: ./scripts/web-app-accept.sh # site: the writeonce.de tutorial (docs/examples/site) — TWO deps -# (serve + view), server-rendered pages, page matrix -> 401/edit +# (porch + view), server-rendered pages, page matrix -> 401/edit # -> SIGTERM -> WAL restart persistence. `just site` runs it. site: ./scripts/site-accept.sh diff --git a/scripts/site-accept.sh b/scripts/site-accept.sh index 7e6c6ca..b3d61fe 100755 --- a/scripts/site-accept.sh +++ b/scripts/site-accept.sh @@ -27,7 +27,7 @@ cleanup() { trap cleanup EXIT # ---- both deps as git remotes; the app pointed at them ---- -cp -r "$ROOT/docs/examples/writeonce-serve" "$W/fw" +cp -r "$ROOT/docs/examples/porch" "$W/fw" cp -r "$ROOT/docs/examples/writeonce-view" "$W/lib" for d in "$W/fw" "$W/lib"; do git -C "$d" init -q @@ -36,7 +36,7 @@ for d in "$W/fw" "$W/lib"; do git -C "$d" tag v0.1.0 done cp -r "$ROOT/docs/examples/site" "$W/app" -sed -i "s|https://github.com/shoneyj/writeonce-serve|file://$W/fw|; s|https://github.com/shoneyj/writeonce-view|file://$W/lib|" "$W/app/wo.toml" +sed -i "s|https://github.com/shoneyj/porch|file://$W/fw|; s|https://github.com/shoneyj/writeonce-view|file://$W/lib|" "$W/app/wo.toml" printf '[build]\nruntime = "%s"\n' "$WOVM" >> "$W/app/wo.toml" # a stand-in release tarball so /dl can be exercised without running @@ -114,7 +114,7 @@ expect "chapter renders a code sample" "$(hit /ch/hello)" 200 "fn main" expect "escaped interpolation visible" "$(hit /ch/values)" 200 '${port}' expect "unknown chapter is a 404 page" "$(hit /ch/nope)" 404 "No such chapter" expect "install guide renders" "$(hit /install)" 200 "tar -C /usr/local" -expect "packages index lists both" "$(hit /packages)" 200 "/packages/serve" +expect "packages index lists both" "$(hit /packages)" 200 "/packages/porch" expect "package detail shows its dep" "$(hit /packages/view)" 200 "writeonce-view" expect "unknown package is a 404 page" "$(hit /packages/nope)" 404 "No such package" expect "favicon is served as svg" "$(hit /favicon.svg)" 200 " lock -> build -> serve -> # the storefront matrix -> SIGTERM -> restart persistence, plus iteration 17's # library-kind and internal/-boundary checks. The repo itself @@ -33,13 +33,13 @@ cleanup() { trap cleanup EXIT # ---- the framework as a git remote; the app pointed at it ---- -cp -r "$ROOT/docs/examples/writeonce-serve" "$W/fw" +cp -r "$ROOT/docs/examples/porch" "$W/fw" git -C "$W/fw" init -q git -C "$W/fw" add -A git -C "$W/fw" -c user.email=t@t -c user.name=t commit -qm v01 git -C "$W/fw" tag v0.1.0 cp -r "$ROOT/docs/examples/web-app" "$W/app" -sed -i "s|https://github.com/shoneyj/writeonce-serve|file://$W/fw|" "$W/app/wo.toml" +sed -i "s|https://github.com/shoneyj/porch|file://$W/fw|" "$W/app/wo.toml" printf '[build]\nruntime = "%s"\n' "$WOVM" >> "$W/app/wo.toml" # ---- 1. fetch + lock + build ---- @@ -63,7 +63,7 @@ fi # A consumer reaching past the privacy line is WO-E108 at its own `use`. cp -r "$W/app" "$W/app-internal" rm -rf "$W/app-internal/target" "$W/app-internal/wo.lock" "$W/app-internal/.wo-deps" -sed -i '1i use serve/internal' "$W/app-internal/main.wo" +sed -i '1i use porch/internal' "$W/app-internal/main.wo" out="$("$WOC" "$W/app-internal" 2>&1)"; rc=$? if [[ "$rc" == "1" ]] && printf '%s' "$out" | grep -q 'WO-E108'; then ok "dep boundary: importing serve/internal is WO-E108"