Commit graph

6 commits

Author SHA1 Message Date
b5d862dcc5 feat(framework): form-encoded body parsing — media_type + form_values
- media_type(req): content-type lowercased, "; charset=..." stripped,
  "" when absent — the content-negotiation hook
- form_values(req): application/x-www-form-urlencoded body -> decoded
  pairs through the existing query decoder ('+' as space, %XX); nil on
  any other content-type so a JSON body is never misread as a form key
- web-app CreateProduct accepts form OR JSON; shared create_product
  insert path; field/number validation answers 400
- probe 7/7 (plus/pct decode, empty value, case + charset param, json
  and missing content-type nil, empty body, media_type strip) + ASan
- gate grows 17 -> 19: form create 201 with decoded name, non-numeric
  price 400; hit() gains a content-type argument
- README: checklist row form ✅ (multipart stays candidate), limits
  paragraph updated; story 16 + board record the landing
- gates: web-app 19/0, oop-e2e 89/0, deps-accept 8/0, log-watcher 7/0,
  employee 8/0, woc-test green

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:21:48 +02:00
c17a8a2558 feat(framework): auth in core — Bearer/Basic mechanism + principal slot
- http/auth.wo: auth_header (scheme split, case-insensitive, RFC 9110),
  bearer_token, basic_credentials (first-colon split, RFC 7617),
  pure-.wo base64_decode (RFC 4648, strict padding), ct_eq constant-time
  compare (no early exit, both Basic fields always compared)
- req.principal: the blessed "who is this" slot, "" until authenticated;
  Middleware.before now takes mut req so auth can write it
- BearerAuth { token, principal } and BasicAuth { user, pass, realm }
  middlewares; BasicAuth answers the WWW-Authenticate challenge; policy
  (routes/users/secrets) stays app-side on the exposed fns
- web-app dogfoods BearerAuth; its hand-rolled Auth class deleted
- probe matrix 26/26 (RFC 4648 vectors, rfc7617 pair, pass-with-colon,
  bad padding/chars/length, deny paths, challenge header) release+ASan
- gate grows 16 -> 17: wrong bearer token answers 401 over the wire
- README: auth bullet + the core CHECKLIST (done / candidate / parked
  behind 8-11 by design); story 16 + board record the landing
- all gates green: web-app 17/0, oop-e2e 89/0, deps-accept 8/0,
  log-watcher 7/0, employee 8/0, woc-test green

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:15:16 +02:00
3d33b7bf58 feat(framework): v1 polish — helpers, 405+Allow, HEAD, Logging, set_header
- App.get/post/put/delete_(pattern, take h: Handler) — the take-interface
  shape probe-proven release + ASan before landing; retires plan-16
  deviation 1; delete_ because delete is the query keyword
- dispatch matches path-first: wrong method on a known path answers 405
  with Allow in registration order; unknown path stays 404
- HEAD routed as GET, body suppressed, Content-Length names the body a
  GET would carry (serialize gains head_only)
- Logging middleware (request line to stderr) ships in router/
- set_header(mut r, name, value) — the builder escape hatch
- web-app registers through the helpers (dogfood); README documents all
- gate grows 14 -> 16: 405+Allow, HEAD-vs-GET content-length equality
- all gates green: web-app 16/0, woc-test 540/0, oop-e2e 89/0,
  deps-accept 8/0, log-watcher 7/0, employee 8/0
- board/story: iteration 17 parked (spec+plan ready on library-internal),
  16 carries the v1-polish landing, order list updated

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:04:57 +02:00
c1b73a3e6b docs: iteration 16 closeout (Task 6)
Board row 16 -> landed (web-app 14/0), pending row removed; story header
records the landing + the two as-built discoveries (idle-keep-alive
starvation policy; the two compiler gaps the chain exposed and fixed);
README gains the framework+web-app sample entry; plan checkboxes ticked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:58:13 +02:00
7405adf353 docs: implementation plan for iteration 16 (web framework + web-app)
6 tasks, words-only: (1) framework skeleton — Req/Resp records + builders,
standalone-typechecking project; (2) HTTP/1.1 parse/serialize + keep-alive
serve loop with the try-bounded dispatch seam (400-close on malformed, 500-
survive on handler traps, fd/stop clean); (3) router with :param captures +
Handler/Middleware interfaces + App.serve; (4) web-app storefront —
@table Product/Order, auth middleware, json routes, [deps] manifest carrying
the future GitHub URL; (5) scripts/web-app-accept.sh — temp git remote from
the framework dir, file:// substitution into a temp app copy, full curl
matrix + restart persistence + SIGTERM + opt-in soak, wired as just web-app;
(6) docs closeout. Both enabling risks retired pre-plan (interface-field
dispatch probe; owned-move container fix pinned by run/container-owned-move).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:38:21 +02:00
8789dcd482 docs: web framework + deps design — spec + iterations 15/16
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>
2026-08-19 19:07:16 +02:00