From 234bd43466b078d291426c63a7c6ba04c5f3b316 Mon Sep 17 00:00:00 2001 From: "shoney.arickathil" Date: Thu, 20 Aug 2026 04:07:39 +0200 Subject: [PATCH] docs: framework v1/v2 split + per-feature status ledger - framework README core checklist expanded into the v1 STATUS LEDGER: seven categories (transport, routing, request/response, context & middleware, storage integration, security, crypto), every item marked done / partial-with-named-gap / candidate / parked-behind-8-11 / needs-runtime-seam - verified before labeling: BODY_MAX caps headers AND body (size limits done); net has no timeout or unix-socket or peer-address surface (runtime seams); language has NO bitwise operators, so SHA/HMAC/CRC32 must be C runtime builtins or bit ops land first (fork to brainstorm); radix routing waits for 9e to measure the linear scan first - crypto hard stop recorded: HS256 unlocks and nothing past it - memory-rich features relabeled FRAMEWORK V2 = iteration 18 (story + spec banners + board rows); v1 gaps land as slices per the ledger Co-Authored-By: Claude Opus 5 (1M context) --- docs/00-status.md | 17 ++-- docs/examples/writeonce-framework/README.md | 91 ++++++++++++++++--- .../language-runtime-database/00-story.md | 2 +- .../18-memory-db-features.md | 8 +- .../2026-08-20-memory-db-features-design.md | 6 +- 5 files changed, 101 insertions(+), 23 deletions(-) diff --git a/docs/00-status.md b/docs/00-status.md index 3cb403f..07ec889 100644 --- a/docs/00-status.md +++ b/docs/00-status.md @@ -52,11 +52,16 @@ takes multipart/form/JSON; `just web-app` **21/0**. Surfaced + fixed the RETURN flavor of the interp-of-borrowed-place emitter bug (emit_return now sees through Interp; same corpus pin). Body-parsing hooks: all three โœ…. -Next: **iteration 18** (memory-rich framework features โ€” TTL cache, -@table flags, durable job queue with drain-on-request, `transaction { }` -over the WAL's staged batch; forks settled 2026-08-20, brainstormed the -same day) โ€” spec, then plan, then implementation on approval. After 18, -the order resumes at 9c/9d. +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-framework/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 +features are **framework v2** = iteration 18 (spec written, awaiting +review): TTL cache, @table flags, durable job queue with drain-on-request, +`transaction { }` over the WAL's staged batch. After 18, the order resumes +at 9c/9d. --- @@ -172,7 +177,7 @@ that sequences its tasks. Read one, approve, then the next starts. | 15 | [deps: `wo.toml [deps]`](stories/language-runtime-database/15-deps-package-manager.md) | โœ… **landed 2026-08-18** (branch web-framework): [deps] inline tables, git-binary fetch, wo.lock pinning, offline-when-locked, --update-deps, WO-E106/E107; `just deps-accept` 8/0 | | 16 | [web framework](stories/language-runtime-database/16-web-framework.md) | โœ… **landed 2026-08-19** โ€” writeonce-framework (HTTP/1.1 + router + Handler/Middleware) consumed by web-app through [deps]; h2c parked (ยงC) behind 8/9f/11. **v1 polish landed 2026-08-20** (branch framework-v1): get/post/put/delete_ helpers, 405+Allow, HEAD, Logging middleware, set_header; `just web-app` 16/0; fixed the interp-borrowed-field emitter crash en route. **Auth-in-core landed 2026-08-20**: http/auth.wo (Bearer/Basic, ct_eq, req.principal), web-app dogfoods BearerAuth, gate 17/0 | | 17 | [library projects + `internal/`](stories/language-runtime-database/17-library-projects-internal.md) | โธ **PARKED 2026-08-20** (developer directive; framework v1 first) โ€” forks settled, spec + plan approved and ready on branch `library-internal`: kind = "library" key; Go internal/ rule, dep-boundary-only; lib+bin dual; VM/GC untouched by design | -| 18 | [memory-rich framework features](stories/language-runtime-database/18-memory-db-features.md) | ๐Ÿ”„ **spec written 2026-08-20, awaiting review** ([spec](superpowers/specs/2026-08-20-memory-db-features-design.md)): TTL cache + @table flags + durable job queue (drain-on-request) + `transaction { }` over the WAL's staged batch; pub/sub REJECTED until 8/11 | +| 18 | [framework v2: memory-rich features](stories/language-runtime-database/18-memory-db-features.md) | ๐Ÿ”„ **spec written 2026-08-20, awaiting review** ([spec](superpowers/specs/2026-08-20-memory-db-features-design.md)): TTL cache + @table flags + durable job queue (drain-on-request) + `transaction { }` over the WAL's staged batch; pub/sub REJECTED until 8/11 | --- diff --git a/docs/examples/writeonce-framework/README.md b/docs/examples/writeonce-framework/README.md index 07e3f26..fdcdf26 100644 --- a/docs/examples/writeonce-framework/README.md +++ b/docs/examples/writeonce-framework/README.md @@ -63,22 +63,85 @@ writeonce-framework = { git = "https://github.com/shoneyj/writeonce-framework", fibers/shards) with `part_named` for fields; `media_type(req)` names the body's media type for content negotiation. -## The core checklist (what a framework core owes, and where this one is) +## The v1 surface โ€” status ledger (2026-08-20) -| Core concern | State | +The target surface of **framework v1**, tracked per item. The memory-rich +features (TTL cache, feature flags, durable job queue, `transaction { }`) +are **framework v2** โ€” iteration 18, spec written, NOT part of v1. +Legend: โœ… shipped ยท ๐Ÿ”ถ partial (gap named) ยท โฌœ candidate slice ยท +โธ parked behind a runtime iteration ยท ๐Ÿ”ง needs a runtime/compiler seam +first (pure `.wo` cannot express it yet). + +### Transport + +| Item | State | | --- | --- | -| HTTP parsing + connection lifecycle | โœ… `http/parse.wo`, `http/serve.wo` (keep-alive, 400-and-survive, fd-clean, SIGTERM) | -| Routing: path params, method dispatch, precedence | โœ… `:param` captures, first-match-wins, wrong-method = 405 + `Allow` | -| Middleware chain, ordering guarantee | โœ… registration order, `?Resp` short-circuits | -| Request/response types | โœ… `Req`/`Resp` + builders + `set_header` | -| Bearer/Basic auth mechanism + principal | โœ… `http/auth.wo`, `req.principal` | -| Body parsing hooks: JSON | โœ… the language's checked `json.decode` | -| Body parsing hooks: form-encoded | โœ… `form_values(req)` โ€” nil unless the content-type says form; `media_type(req)` exposed for content negotiation | -| Body parsing hooks: multipart | โœ… `multipart_parts(req)` (RFC 7578: fields + file parts, filename/mime kept) + `part_named` | -| Error handling โ†’ status mapping | ๐Ÿ”ถ trap = 500, builders per status; a per-error mapping hook is a candidate slice | -| Body streaming, backpressure | โธ needs fibers/shards (iterations 8/11) โ€” whole bodies until then, by design | -| Cancellation propagation | โธ process-level only (`env.stopping()`); per-request cancel needs fibers (11) | -| Configuration + graceful shutdown | ๐Ÿ”ถ SIGTERM drains and closes clean; config is ctor fields โ€” a config record is a candidate slice | +| HTTP/1.1 parsing | ๐Ÿ”ถ parses + 400-and-survive; STRICT ambiguity rejection (duplicate/conflicting `Content-Length`, oversize checks beyond BODY_MAX) not audited โ€” hardening slice | +| Keep-alive | โœ… pipelined-serve / close-when-idle (starvation-honest until 8/11) | +| Read/write/idle timeouts | ๐Ÿ”ง `net` has no timeout surface โ€” runtime seam, then a framework knob | +| Request size limits | โœ… BODY_MAX bounds headers AND body | +| Unix socket binding | ๐Ÿ”ง `net.listen` is TCP-only โ€” runtime seam | +| Graceful SIGTERM | โœ… in-flight request completes (blocking model), listener + fds closed, storage is per-commit durable (WAL fdatasync โ€” nothing to checkpoint) | + +### Routing + +| Item | State | +| --- | --- | +| Path matching | ๐Ÿ”ถ linear scan, first-match-wins; a radix tree is a performance slice that waits for iteration 9e to MEASURE it first | +| Method dispatch ยท path params ยท 404 ยท 405+`Allow` | โœ… | +| Wildcards | โฌœ only `:param` today; `*rest` capture is a candidate slice | +| Precedence rules | ๐Ÿ”ถ registration order IS the rule (documented); specificity-based precedence unneeded until wildcards exist | +| Route groups | โฌœ candidate slice (prefix + per-group middleware) | + +### Request/response + +| Item | State | +| --- | --- | +| Case-insensitive headers ยท query parsing | โœ… (names lowercased on read) | +| JSON ยท form-urlencoded ยท multipart | โœ… all three hooks (`json.decode`, `form_values`, `multipart_parts`) | +| Content negotiation | ๐Ÿ”ถ `media_type(req)` covers the request side; `Accept`-driven response negotiation โฌœ | +| Trusted-proxy client IP | ๐Ÿ”ถ `X-Forwarded-For/-Proto` parsing is expressible (candidate slice); VERIFYING the peer is the trusted proxy needs a peer-address runtime seam ๐Ÿ”ง | +| Status/header setting ยท redirects | โœ… builders + `set_header` | +| Lazy body streaming + backpressure ยท streaming responses ยท explicit commit point | โธ 8/11 โ€” whole bodies, one write, by design | +| ETag + conditional requests | โฌœ candidate; wants the crypto slice's hashing | + +### Context & middleware + +| Item | State | +| --- | --- | +| Ordered middleware chain | โœ… registration order, `?Resp` short-circuits | +| Request-scoped context | ๐Ÿ”ถ `req.params` + `req.principal` are the context today; a general `req.ctx` bag is a candidate slice | +| Guaranteed teardown | ๐Ÿ”ถ every fd closes on every path (gate-proven); no user teardown hooks yet | +| Cancellation into pending storage ops | โธ fibers (11) | +| Panic recovery | ๐Ÿ”ถ trap = 500 and the server survives โœ…; "rolls back the transaction" is framework v2 (needs `transaction { }`, iteration 18) | + +### Storage integration (the differentiator โ€” framework v2 territory) + +| Item | State | +| --- | --- | +| Transaction-per-request middleware (commit on 2xx, roll back otherwise) | โธ **v2** โ€” needs iteration 18's `transaction { }` | +| Cancellation โ†’ rollback | โธ fibers (11) + v2 | +| Migration generation + review workflow | โฌœ recorded future story (script-based destructive migrations) | +| Eager-loading API (N+1) | โฌœ query-surface work (9-series), not framework code | +| Tenant-scoped query roots | โฌœ future; wants the query surface to grow scoped roots first | + +### Security + +| Item | State | +| --- | --- | +| Constant-time comparison ยท Authorization parsing ยท Basic auth ยท principal | โœ… `http/auth.wo`, `req.principal` | +| CORS | โฌœ candidate slice (middleware + preflight answers) | +| Security headers | โฌœ candidate slice (one middleware, a header set) | +| Host validation | โฌœ candidate slice (middleware against a host allowlist) | +| Strict parsing | ๐Ÿ”ถ same item as Transport's hardening slice | + +### Crypto (self-written, hard-stop after JWT HS256) + +| Item | State | +| --- | --- | +| base64 | โœ… pure `.wo` (`http/auth.wo`) | +| SHA-256 ยท SHA-512 ยท HMAC ยท CRC32 | ๐Ÿ”ง the language has NO bitwise operators โ€” these are C runtime builtins (libc-only doctrine permits hand-rolled crypto in the runtime) or the language grows bit ops first; the fork goes to a brainstorm before the slice | +| Unlocks (signed cookies, CSRF, session integrity, webhook verification, JWT HS256) | โฌœ framework slices AFTER the hash primitives exist; **hard stop there** โ€” no RS256, no JOSE zoo | ## The consuming sample diff --git a/docs/stories/language-runtime-database/00-story.md b/docs/stories/language-runtime-database/00-story.md index 43ba647..d20ad1d 100644 --- a/docs/stories/language-runtime-database/00-story.md +++ b/docs/stories/language-runtime-database/00-story.md @@ -66,7 +66,7 @@ iterations); no commits by agents โ€” drafts go to `.dev/commit.md`. | 15 | [deps: `wo.toml [deps]`](15-deps-package-manager.md) | exact-rev git dependencies + `wo.lock` + `.wo-deps` cache; `use ` resolves a fetched project as a module root; flat-only, network-free when locked | | 16 | [web framework](16-web-framework.md) | a `.wo`-library framework (HTTP/1.1 keep-alive behind a TLS-terminating proxy): router, `Handler`/`Middleware` structural interfaces, `@table` data layer; `docs/examples/web-app` consumes it via `[deps]`; h2c parked behind 8/9f/11 | | 17 | [library projects + `internal/`](17-library-projects-internal.md) | first-class library projects (`wo.toml` kind = "library", checkable without an entry, dual lib+bin) and dependency privacy (Go's `internal/` rule at the [deps] boundary) โ€” forks settled 2026-08-20, spec/plan next | -| 18 | [memory-rich framework features](18-memory-db-features.md) | what the embedded store + one process buy for free: TTL cache class, @table feature flags with cached reads, a durable @table job queue with drain-on-request, and `transaction { }` exposing the WAL's staged batch (enqueue + write, one commit โ€” no outbox) โ€” forks settled 2026-08-20, spec/plan next | +| 18 | [framework v2: memory-rich features](18-memory-db-features.md) | what the embedded store + one process buy for free: TTL cache class, @table feature flags with cached reads, a durable @table job queue with drain-on-request, and `transaction { }` exposing the WAL's staged batch (enqueue + write, one commit โ€” no outbox) โ€” forks settled 2026-08-20, spec/plan next | Review protocol: the developer reads one iteration, approves or amends; the next starts only after approval. Each iteration is an unsplittable 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 8074b52..0104e53 100644 --- a/docs/stories/language-runtime-database/18-memory-db-features.md +++ b/docs/stories/language-runtime-database/18-memory-db-features.md @@ -1,4 +1,10 @@ -# Iteration 18 โ€” memory-rich framework features over the embedded database +# Iteration 18 โ€” framework v2: memory-rich features over the embedded database + +> **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-framework/README.md); +> v2 is what the embedded store adds on top. v1 gaps land before or +> alongside v2 as slices, per the ledger. > Format: `product/story-iteration-template`. Part of > [Story โ€” one language, one runtime, one database, one binary](00-story.md). diff --git a/docs/superpowers/specs/2026-08-20-memory-db-features-design.md b/docs/superpowers/specs/2026-08-20-memory-db-features-design.md index 70477d3..60d8b39 100644 --- a/docs/superpowers/specs/2026-08-20-memory-db-features-design.md +++ b/docs/superpowers/specs/2026-08-20-memory-db-features-design.md @@ -1,5 +1,9 @@ -# Iteration 18 โ€” memory-rich features over the embedded database: design +# Iteration 18 โ€” framework v2: memory-rich features over the embedded database (design) +> **Scope label: FRAMEWORK V2** โ€” framework v1 is the surface tracked in +> the framework README's status ledger; this spec is what the embedded +> store adds on top of it. +> > **Status: spec, awaiting review (2026-08-20).** Decisions were settled in > [the iteration](../../stories/language-runtime-database/18-memory-db-features.md); > this spec makes them buildable. The plan follows after review.