Commit graph

70 commits

Author SHA1 Message Date
c0b0dbb846 docs: audit all markdown against the code, fix findings, flatten status folders
- README: shipped concurrency/HTTP/WebSockets sat in the roadmap as "not yet
  available"; "no package manager" contradicted [deps]; the deps example
  would not have compiled (the key IS the module name)
- runtime/README: leads with wovm, wo-rt.c demoted to a historical section;
  dropped 2 nonexistent recipes, crates/rt, @gc refcounting, 13 suites -> 18
- employee + log-watcher READMEs claimed "does not compile"; both are gates
- error catalog: +10 emitted codes incl WO-E250, the only diagnostic the
  shipped query surface raises; recorded why the sweep rotted
- language-surface: group-by parses, then the typechecker refuses it
- 00-code-review + 00-link-audit re-run; history kept, not rewritten
- 48 dead Rust-era exploration links de-linked rather than re-pointed (their
  prose names the retired plan by number); successor map -> discarded.md
- 08-project-structure: compiler/plan/ never existed; corpus has 9 dirs, 5 empty
- releasing.md: dropped a --draft step the workflow never had
- new docs/00-doc-audit.md: findings + disposition, incl one row where the
  audit was wrong and the doc it accused was right
- status folders removed: 34 stories flat, status only in frontmatter; 252
  links recomputed from resolved paths; board/board-views/structure retaught
- story 24 -> in-progress, since frontmatter is now the only truth
- new iteration 38: fs mutation verbs + net.connect, the two capability
  families no iteration owned
- new iteration 39: gofiber/fiber v3.5.0 parity study. The ledger called
  CSRF/sessions unblocked by iteration 34's HMAC, but the runtime has no
  source of randomness at all
- linkcheck skips .dev/.superpowers: 0 broken paths, 0 bad anchors

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 19:20:22 +02:00
ef37b8ffa2 feat(serve+view): file serving, downloads, supported systems; rename
- rename the two libraries: writeonce-framework -> writeonce-serve
  (`use serve`), wo-html -> writeonce-view (`use view`). Names say the
  ROLE now; every sample, script, gate and live doc follows
- stories/specs/plans keep the old names: they are dated records, and
  both library READMEs carry a "renamed 2026-08-25" note
- serve/http/files.wo: StaticFiles { dir, max_bytes } — traversal
  refused not normalised, extension content types, attachment
  disposition for archives. Lifted out of the shop, which had said in
  a comment that it belonged in the framework
- shop drops its private copy and mounts the framework's
- site: /dl/*path over $WO_DIST (default ./dist), 16 MiB ceiling
- /install gains supported systems — Linux x86-64, glibc >= 2.38,
  not musl — read off `file` and the binaries' GLIBC_ symbol
  versions, not off a wish list; plus GitHub release as primary,
  /dl as mirror, and the sha256 verify step
- site-accept: 17 -> 21 checks (supported systems, gzip download with
  a binary-safe probe, checksum, /dl traversal 404)

Verified on 192.168.0.165: the real 960,820-byte tarball downloads
as application/gzip and its sha256 matches the published digest.

Gates: oop-accept MET, site 21/0, web-app 46/0, fibers 10/0,
db-actor 8/0; shop rebuilt and its /assets served by the framework.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 04:41:00 +02:00
23550e7021 feat(lang+wo-html): raw text literals, component layer, MVC samples
- lexer: backtick raw text literal — content verbatim, no escape
  processing, common source margin removed at lex time; `${ }` raw and
  `{{ }}` auto-escaping holes
- `{{ e }}` desugars to `esc(${e})` in parser.ml — a Call on the `esc`
  in scope, so types/owner/emit/.wob/VM are untouched
- WO-E004 unterminated raw literal; WO-E005 newline inside "..." —
  closes a hole where a missing quote silently ate the rest of the file
- wo-html: `Component` interface, `render_all`, `Layout`, README
- framework: `ok_html` joins ok_text/ok_json in http/types.wo
- site + shop restructured to one-feature-one-module MVC (view +
  controller per directory, model at the root, bootstrap-only main)
- removed the filler `pad: Int` convention — verified unnecessary for
  plain classes, interface dispatch, containers and actors
- corrected recorded claims: gap #1 blocks neither the build nor the
  layout; a class crosses module lines, only a free fn is scoped
- docs/guides/language-surface.md — the full grammar inventory
- story 37 landed and moved to done/

Gates: oop-accept MET, oop-e2e 116/0, woc-test 556/0, site 11/0,
web-app 46/0, fibers 10/0, db-actor 8/0

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 03:58:41 +02:00
bbf5fb66d3 feat(shop): 37 target = in-class raw template literals (developer form)
- separate view.html files dropped; every render() now carries its
  '-- 37 target:' literal above the hand-lowered body — the pair is
  the DX referendum in one file
- story 37 re-pointed: raw multi-line literal + {{ }} auto-escaped
  typed holes + {!! !!} raw slots; structural control stays if/for;
  w:if/w:for and .html files demoted to later; forks revised
- rebuild verified on untouched toolchain

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 00:15:38 +02:00
89df517613 feat(shop): the program template — MVC on disk; story 37 redirected
- docs/examples/shop: types.wo model, per-feature view modules
  (render() classes), root controller files, layout shell/header/
  footer, static assets controller + real style.css, README with
  Angular file map + run + DX referendum notes
- buy flow proven by hand: stock check/decrement, 409s, traversal
  404, css typed, WAL-durable; builds on the UNPATCHED toolchain
- two language gaps recorded, not fixed (per directive): pub+@table
  cannot combine (controllers forced into root module); @view
  projection classes absent
- story 37 REDIRECTED per Vue-SFC review: view.html compiled by woc
  ({{}} auto-escaped, w:if/w:for, typed against view class, no
  runtime engine); render()-as-concatenation failed the referendum;
  forks revised; shop named the acceptance consumer

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 23:57:44 +02:00
67cd039533 docs: fix stale story-35 links (file moved to done/ at landing)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 19:36:18 +02:00
8f96584682 docs: story 37 — wo-html components (MVC view layer, Angular format studied)
- Component interface (render->Text), layouts/slots, site migrates
  as acceptance; framework stays micro (view layer = library)
- Angular map recorded: inputs/templates/ngFor/projection translate,
  DI/bindings/client-side rejected by doctrine (no closures, no JS)
- four forks for the spec; unscheduled, off-chain; table + board rows

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 19:35:41 +02:00
a32550d968 feat: iteration 35 — net seams + the serving slice (fiber-per-connection)
- runtime ids 91-95: net.read_dl/accept_dl/write_dl (per-call deadline,
  nil/false = the EXPECTED timeout; ms<=0 = old behavior bit for bit),
  net.listen_unix (unlink-before-bind, O_NONBLOCK on the listener —
  probe-found: accept4's flag covers accepted sockets only), net.peer
- plane: one-op-per-park stays law — deadlines ride one per-shard
  TIMEOUT tick (sentinel user_data) + post-CQE expiry sweep +
  POLL_REMOVE tombstone; epoll's deadline scan grew the fd-park case;
  fibers POOL instead of freeing mid-run (stale-CQE UAF); plain parks
  zero park_deadline (no stale sleep deadlines)
- probe: all five seams verified on BOTH WO_IO backends (timeout
  timing exact, peer round-trip, unix rebind)
- framework: parse_request grows first_ms/read_ms; serve_conn — the
  keep-alive loop with deadlines where parked idle conns are LEGAL
  (close-when-idle RETIRED); App.handle_conn exposes it; plain serve()
  unchanged for simple apps
- web-app: app-owned accept_dl loop + ConnWorker actor per connection
  (each builds its own App; cross-shard placement rides the DB actor);
  WA_IDLE_MS knob; gate grows to 41 checks — two slow requests served
  in PARALLEL, stalled client evicted at the idle deadline, slow-loris
  torn at the read deadline (400)
- docs: story 35 -> done with banner; SQE/CQE design spec LANDED (was
  the review doc); ledger rows (timeouts/unix/keep-alive/peer), graph
  (NETSEAM cleared, KEEPAL done), builtin-surface rows, runtime
  CODE-LOGIC section, board entry
- battery 13/13 fresh-built

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 08:04:32 +02:00
64a4700190 docs: reconcile story 34 + gates with merged master
- story 34: premise fixed — iteration 36 landed bitwise/hex, digests
  and HMAC now expressible in pure .wo; C-builtin vs pure-.wo is the
  story's brainstorm call, not an impossibility
- dependency graph: crypto gate names story 34; net-seam gate names
  story 35; radix gate corrected — 22 benched the DB, router scan
  still unmeasured, perf-targets entry first
- framework README ledger: timeouts/unix/peer rows point at story 35;
  ETag row at story 34; path-matching row repointed off iteration 22

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 23:30:55 +02:00
ee018f06e2 Merge branch 'read-path-index' 2026-08-22 23:26:01 +02:00
dc3e5b7e5b Merge branch 'db-bench' (iteration 22 — durability/throughput baseline)
- brings time.ticks builtin (id 84), bench sample + campaign driver
  (scripts/db-bench.py), just db-bench/db-bench-quick recipes, first
  baseline recorded, story 22 to done/, postgres study cards
- conflicts resolved: board in-progress table (iteration 36 +
  framework rows kept, db-bench row now "22 landed"; dangling order
  anchor repointed); story 36 moved back to in-progress/ (dir-rename
  inference dragged it to done/ — 36 still awaits the manual pass)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 22:57:51 +02:00
4ec01c4c43 Merge branch 'concurrency-arc-stage3' (iteration 8 complete)
- brings arc stage 3: transparent DB actor (T7) + closeout (T8),
  db-actor sample + gate, board/story reorg (stories/00-status.md)
- conflicts resolved: runtime CODE-LOGIC (kept iteration 36 bitwise
  section AND stage-3 DB-actor section), board in-progress table
  (kept iteration 36 + framework rows AND db-bench row, links fixed
  for the moved board path)
- full battery fresh-built 11/11: woc-build wovm-build woc-test
  wovm-test oop-e2e deps-accept web-app log-watcher employee fibers
  db-actor (first run hit a stale pre-merge wovm — gates require
  built binaries and never rebuild; builds now run first)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 22:50:18 +02:00
ed6bfeea3d feat: iteration 36 task 5 — operators sample, docs closeout
- docs/examples/operators: manual-test workload (ok/FAIL lines per
  expression; trap mode proves WO_T_SHIFT); NO test fixtures by
  developer directive — acceptance is the manual pass
- 00-wob-format.md: v6 section (opcodes 42-46, T_SHIFT, header v6)
- CODE-LOGIC.md both sides: precedence-into-existing-rungs, Lua not,
  rewind-and-reparse compound assigns, trap-not-mask, 63-bit hex limit
- story 36 refine -> in-progress with landing blockquote; board updated
- gates: woc-test 543/0, wovm-test ASan, oop-accept ALL MET,
  deps-accept 8/0, web-app 26/0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 21:42:08 +02:00
6f7fc577c3 docs: story 36 + plan — operator parity (not, bitwise, hex literals, compound assigns)
- story: gap survey vs Go reference; forks settled (arithmetic >>, trap
  on out-of-range shift count, Lua-placement not)
- plan: 5 tasks, lexer -> parser -> checker -> emit/VM (.wob v6) -> closeout
- latent defect recorded: += / -= lex but never parse (dead tokens)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 21:18:33 +02:00
526a837102 docs: story 35 — net runtime seams (deadlines, unix sockets, peer addr)
- owns the framework ledger's three seam rows; deadlines compose with
  the arc's park plane (POLL_ADD+TIMEOUT fork recorded); framework
  knobs explicitly out of scope; stalled-client soak in acceptance
- board + table rows (held seqs bumped); pairs naturally with 24

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 17:37:12 +02:00
38457973c3 docs: story 34 — crypto builtins (digests + HMAC)
- SHA-1 (WS-handshake hard req, RFC 6455 worked example as acceptance),
  SHA-256, HMAC-SHA256 over Bytes; hand-rolled C per doctrine, FIPS/RFC
  vector fixtures; four forks recorded (namespace, shape, source, file)
- gates chain item 24; digest floor for held 21 + ETag row; 24's
  dependency note repointed; board + table rows (held seqs bumped)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 17:34:27 +02:00
b3baf6dd9a docs: story 33 — single-file store (WO_DATA=<path>.db)
- file path IS the wal; dir form byte-identical; one fork (nonexistent
  path semantics) leaning recorded; off-chain, driver-only
- board + story table rows (held tail seqs bumped)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 17:32:18 +02:00
5d6a72bb82 docs: iteration 22 landed — closeout (T6)
- story 22 to done/ with landing banner (numbers, deviations,
  standing multi<TableClass> finding); marker deleted
- board standup from measured numbers; next slice = 31 (has its
  mutex-inbox number now); spec/plan banners LANDED; graph node done
- msgrate floors value/8 (quick's small N spawn-dominated, grazed /4)
- full battery + db-bench-quick 87/0 green; links verified

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 16:57:27 +02:00
3a30b4ac3b feat(db-bench): first baseline — the measurement contract (T5)
- bench/baseline.json: 74 metrics from the first full campaign;
  tolerances tuned by a two-run repeatability check (mix* 50%,
  read/query 35%, rest 15% — rationale in _config)
- gate bites: --check mode; doctored copy fails, both real runs 74/0
- headline: durable seed 4.5k/s vs ram 297k/s (23's case); reads
  O(table) at ~1.5k/s; mixread 1280 vs 21 ops/s single-vs-multi
  (the arc's price); msgrate 13.4M vs 2.45M (mutex-inbox number)
- arc delta recorded in story 8; findings in sample README

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 16:54:13 +02:00
555a836d90 docs: iteration 22 plan ready; slice active
- plan 2026-08-21-db-bench.md: 6 tasks (time.ticks builtin, sample,
  concurrent modes, driver+gate, first baseline + gate-bites proof,
  closeout); words + verification commands per convention
- spec banner APPROVED; story 22 to in-progress/ (frontmatter synced);
  marker doc created; board standup/rows/pending updated

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 16:07:51 +02:00
49cc734ae8 docs: arc closeout (T8) — stage 3 landed, chain advances to 22
- stories 08+11 to done/ with banners (11: fs-park re-scoped out of
  v1, disclosed); guarantee-contract table re-homed in story 08;
  marker doc deleted per convention
- board standup: implemented/findings/learned/unblocked/next/.dev-ref
  for the landing; In-progress = nothing active, next = 22 spec
- arc plan status ARC COMPLETE, T7/T8 boxes checked with deviations;
  graph nodes done; framework ledger rows note arc-unblocked;
  18's pub/sub rejection expired note
- CODE-LOGIC: runtime DB-actor + ring-params section, database slot
  surface; oop-vm/03 contract gains the reply-park protocol
- 22 precursor recorded: remote insert ~8us/op RAM-only
- full battery + db-actor gate green after doc edits; links verified

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 13:16:25 +02:00
ca2ed96e49 docs: story frontmatter + Dataview board views
- 28 story files gain YAML frontmatter: iteration id, status
  (mirrors folder), chain position (7 files, positions 1-6)
- board-views.md: Dataview queries (not-done, by-status lanes,
  chain order, active); Kanban caveat — view only, frontmatter
  is source of truth, folder move + status key change together
- board points at the views

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 12:17:50 +02:00
e7ca2fdd7c docs: stage 3 refined with guarantee contract; story 32 born
- five-property map in marker doc: atomicity/durability/recovery
  proven or held (18); concurrency control = stage 3's property;
  space reclamation RAM done (slot reuse), disk = new story 32
- story 08: three stage-3 criteria (one commit per write RPC +
  ack-after-owner-fsync, workers WAL-free + replay-before-serve,
  no torn reads under TSan corpus); arc plan stage 3 carries them
- refine/32-wal-checkpoint.md: snapshot + truncate, bounded replay,
  crash-during-checkpoint safe; four forks; after 23
- chain now stage 3 -> 22 -> 31 -> 24 -> 23 -> 32 in all 10 docs;
  boards + seq bumps synced

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 11:26:45 +02:00
eacc7fe4f2 docs: oop-vm/03 — stackless coroutine contract (no async)
- normative reference for the concurrency chain: fiber = interpreter
  state, suspension only at VM boundaries, park/resume protocols
  (re-execute vs continue-past, park_wr_at), back-edge budget,
  no-coloring rule, rejected-alternatives table
- README slot 03 repointed (old shard-actor row rode discarded plan 4)
- story 11 links the contract

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 11:07:52 +02:00
299b448181 docs: active stories 08+11 into stories in-progress/ (slip fix)
- 08 landed in discarded/ by mis-drop, swept into prior commit with
  two dead links; corrected to stories/.../in-progress/ per intent
- 11 joins it (one arc, active slice)
- board doctrine: active stories bucket named; all links re-verified

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 06:21:33 +02:00
f691818c4b docs: in-progress/ marker — arc stage 3 is the active slice
- one marker doc, deleted on landing; board doctrine names the
  second folder exception
- board In-progress row was stale (nothing active + dead anchor);
  now points at marker + arc plan tasks 7-8

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 06:19:03 +02:00
d3f77d6850 docs: discard 2026-08-01 shard-actor plan (epoll-based)
- io_uring is a must; epoll approach discarded (developer decision)
- plan superseded by shard-fiber-arc plan of record; banner + row in
  plan/discarded.md; file kept as idea reference
- three live pointers repointed: status language-track row 8,
  principles enforced-by, story 08 note

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 05:59:21 +02:00
1cfcd6292a docs: stories 08+11 promoted to root — ready to implement
- code-verified ready: arc stages 1+2 merged to master; stage 3
  concrete in plan (tasks 7-8); rt.db set on primary only
  (main.c), worker_late_init memsets rt — WO_T_DB hole real
- 22/23/24/31 stay in refine/: open forks, no bench harness,
  no crypto builtins, chain-blocked
- links fixed both directions; board doctrine names hold/ bucket

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 05:10:39 +02:00
039cb9ba4f docs: concurrency chain re-refined + resequenced
- order now stage 3 -> 22 -> 31 -> 24 -> 23: correctness before
  measurement (multi-shard DB traps WO_T_DB today)
- stories 08/11 catch up to landed arc stages 1+2 (plan of record,
  deviations, settled open questions)
- 22 gains multi-shard + mutex-inbox targets; deltas owed retroactively
- 23 rides arc's per-shard ring (T4); old-id order string superseded
- 24 depends on 31; 19 landed so Bytes ready
- new story: refine/31-actor-lifecycle.md (request/response,
  bounded mailboxes, death/supervision, timers)
- 00-story table + 00-status pending resequenced; held rows link
  hold/; ids stay immutable, no renames

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 05:01:11 +02:00
b4d9d507a0 docs: sync superpowers specs/plans to hold decision
- iterations 18/25/26 marked hold in their spec + plan headers
- 25's story file removal committed; plan doc stays for resumption
- web-framework spec's relates-to flags 25 held

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 05:00:56 +02:00
26bfc42bfe hold few iterations 2026-08-21 04:11:10 +02:00
d24c705860 feat: iterations 19 + 17 — Float/Bytes scalars (.wob v5), library kind + internal/
- Float full stack: literals (fraction/exponent; `0..10` still a range), f64
  opcodes 34-41, @table column, WAL bit-exact replay, json fractions in and
  shortest-round-trip out. IEEE-quiet — FDIV never traps where DIV does.
- Bytes: a wo_str with its own class id, so alloc/free/copy are shared but no
  Text builtin accepts one; len/at/slice/eq/concat, base64 both ways, json
  boundary as base64; TEXT_COPY preserves the kind.
- No implicit Int/Float mixing (WO-E201 in the typechecker, not the emitter,
  which picks the opcode from one side and would misread the other).
- One IEEE deviation: float_cmp total order (NaN last, -0.0 == +0.0) for
  indexes and order-by, keys canonicalized to match. `?Float` nil is a
  reserved quiet NaN — the zero word is +0.0, WO_NIL_SCALAR's bits are -2.0.
- Renderer prefers fixed over exponential in 1e-6..1e21: pure shortest makes
  a price of 900.0 read `9e+02`. One renderer for interp/json/float_to_text.
- Fixed en route: lexer double-counted the leading digit; is_scalar_shaped
  took Float/Bytes as Int-shaped; Bytes ownership needed a shared heap-scalar
  predicate or temps never dropped; order-by bit-compared negatives backwards.
- Iteration 17: `kind = "library"` (absent = program; bad value = WO-E109),
  entry-less check mode retiring the `--emit` workaround, Go's `internal/` as
  WO-E108 at the consumer's `use`. Driver-only; VM/.wob/GC untouched.
- Framework reorg: internal/{parse,serve}.wo; http/form.wo split out to keep
  media_type/form_values public (parse.wo had grown public surface).
- Docs: link audit (97 -> 88 broken, conflict markers resolved, 2 duplicate
  stories removed), 00-code-review verified 26/27, iterations re-sequenced.
- Also carries the pre-staged pub(read)/using/#if work from the index.
- Gates: corpus 103/0, test_wal 156/0, web-app 26/0, oop-accept ALL MET.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 19:24:15 +02:00
5521d21a84 docs: pending iterations renumbered by dependency + priority
- developer directive: pending iteration IDs now ARE the priority order;
  LANDED iterations keep historical numbers (code comments and commit
  history cite them — records, not a queue); 8/11 (the half-landed
  arc), 17 (parked, artifacts on a branch), 18 (next, artifacts named)
  also frozen
- mapping (recorded in 00-story): 19<-20 Float+Bytes, 20<-9c attach,
  21<-9d keypair, 22<-9e benchmarks, 23<-9f io_uring WAL, 24<-19 chat,
  25<-10 services, 26<-12 blue-green, 27<-9g query corpus,
  28<-14 skillhost, 29<-13 metaprogramming
- 11 story files renamed; every doc reference re-numbered (word-boundary
  sweep for the lettered 9x ids, phrase-level for numeric ones); the
  iterations table rewritten with Seq == priority and "(was N)" notes;
  story-scoped link check: zero broken
- merge-recovery folded in: the partial master merge had dropped the
  chat story, the fibers exploration note, the arc spec+plan, the
  framework-v2 plan, and the iteration-17 spec+plan — all restored from
  their branches and renumbered consistently

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 14:31:09 +02:00
4c8a3bd2ed docs: iteration 20 — Float + Bytes, the missing scalars (forks settled)
- brainstorm settled four forks: Float FULL STACK in one iteration
  (literal, IEEE f64 VM ops via u64 bitcast, @table column + WAL slot,
  json fidelity — json.c's own comment names the hole: fractions are
  malformed because "the language has no [float]"); IEEE-754 QUIET
  semantics (division never traps, NaN flows; Int keeps DIV0; no
  implicit mixing — float(i)/trunc(f) bridges); BYTES ships alongside
  (binary carrier: multipart files, WS frames for 19, crypto digests;
  Text goes back to meaning text); iteration 20 + spec before code
  (.wob/WAL version bump earns a written spec)
- the rest of the missing-type survey recorded with reasons: Result/
  Option expressible today (?T + payload unions), tuples covered by
  records + doctrine, Decimal stays cents-until-a-workload, Char/
  Unicode its own future story, Set/ADTs parked post-12, scalar
  newtypes need the rejected `abstract`
- one indexed-storage deviation from raw IEEE spec'd loudly: a Float
  index needs a total order — NaN sorts last
- board row, story-table row (seq 26), graph node (9+16 -> 20 -> 19;
  crypto gate wants Bytes)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 14:21:58 +02:00
2a4c304378 docs: stories foldered by state — done/ and refine/
- done/ (11): 1, 2, 3, 4, 6, 7, 7b, 9, 9b, 15, 16 — landed iterations
  (9/9b remainders live in the post-12 drain list, not in the files)
- refine/ (8): 9c, 9d, 9e, 9f, 9g, 11, 13, 14 — everything marked
  "no spec yet / brainstorm before planning"
- root keeps: 00-story (index), 05 (partial, plan 8 open), 8/10/12
  (specs or plans exist), 17 (parked, spec+plan approved), 18 (next)
- every cross-reference re-pathed and VERIFIED resolving: board, specs,
  plans, employee-list README, story table, intra-story links (moved
  files' relative links deepened one level; done/7b's 9e pointer now
  crosses to refine/)
- pre-existing dead link noted, not touched: refine/11-fibers.md points
  at docs/plan/exploration/fibers/00-fibers.md which does not exist
  (predates the move)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 04:33:24 +02:00
ba428c362c docs: story iterations table re-sequenced by dependency
- 00-story.md iterations table rows reordered into implementation order
  with a Seq column; # stays an immutable ID (files never renumber —
  every board/spec/plan references by number)
- order: 1-7b, 9, 9b, 15, 16 (landed, landing order) -> 18 NEXT (spec
  approved) -> 9c -> 9d -> 9e -> 8 -> 9f -> 11 -> 10 -> 12 -> 9g -> 14
  -> 13; 17 parked row at the end, slots anywhere after 16 on directive
- story note + board implementation-order list synced (18 inserted as
  item 2 after the parked-17 note; 9g now explicitly before 14; list
  renumbered)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 04:25:43 +02:00
234bd43466 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) <noreply@anthropic.com>
2026-08-20 04:07:39 +02:00
deb2dc805c docs: iteration 18 — memory-rich features over the embedded DB (no code)
- brainstorm settled four forks same-day: scope = TTL cache + @table
  feature flags + durable @table job queue; jobs = drain-on-request
  (idle server drains nothing, disclosed); transaction { } ships in 18
  (WAL already stages batches, db.c merely commits per statement);
  pub/sub REJECTED until 8/11 (no WebSockets, starvation lesson)
- ground truths verified and recorded: time.now exists, no timers (lazy
  expiry only), accept blocks without timeout, state lives on wired
  instances, wal_append*/wal_commit is the txn seam
- headline: enqueue + business write in ONE commit — outbox dissolved
- draft acceptance incl. SIGKILL/restart transactional-jobs proof
- board row 18 + NEXT PLAN next-step + story roadmap row

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:52:59 +02:00
0dd5fda180 feat(framework): multipart/form-data parsing — Part, multipart_parts, part_named
- http/multipart.wo: RFC 7578 whole-body parsing within BODY_MAX —
  boundary from the raw content-type (quoted or bare, key
  case-insensitive), parts split on --boundary, each part = headers,
  blank line, content; filename + per-part content-type kept (lowercased)
- strict malformed-is-nil: no closing --boundary-- marker, a part
  without content-disposition, missing blank line, no boundary param,
  wrong media type — all nil, the caller's 400
- part_named(parts, name): first matching field's content, caller-owned
- web-app CreateProduct now accepts multipart/form/JSON (curl -F shape)
  into the shared insert path
- probe 13/13 + 3x reuse loop (fields, crlf-in-content, quoted boundary,
  file part, zero-part close, five malformed shapes) release + ASan
- gate grows 19 -> 21: multipart create 201, missing closing marker 400
- README: multipart row ✅ (all three body hooks done), limits updated;
  story 16 + board record the landing
- gates: web-app 21/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:33:14 +02:00
a5826495e9 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
fb86156d04 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
d84b72f0b4 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
2b5762500b docs: goal shift — log-watcher (met) to web framework as library
- NEXT PLAN rewritten: iteration 17 is the goal slice (merge branch, spec/
  plan, kind = "library", internal/ WO-E1xx, framework reorg, gate list)
- previous NEXT PLAN retitled "Landed 2026-08-15 — the executable milestone";
  all six measured items were already done, board rows were stale
- board row 7: in-progress -> landed 2026-08-15 (ASan-clean, SIGTERM, fd-flat,
  soak, just log-watcher 7/0); iteration 07 story banner updated to match
  its plan doc's done banner
- in-progress table now carries iteration 17 spec/plan
- implementation order re-sequenced for framework goal: 17, 9c/9d, 9e, 8,
  9f, 11 (+ h2c unparks), 10, 12, then 14/9g demoted (skillhost no longer
  the driving workload), 13 + parked drain last
- story notes record the shift and the new order

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 02:04:41 +02:00
d1aab85dbe docs: sequence pending iterations in implementation order
- new "Implementation order (sequenced 2026-08-20)" section in 00-status.md
  pending bucket: 7-finish, 17, 9g, 14, 9c/9d, 9e, 8, 9f, 11, 10, 12,
  13 + parked drain
- forcing rules recorded: 9f after 8+9e; 9c precedes 10; 9d folds into 9c;
  12 after 9+10; 11 rides 8's scheduler; h2c behind 8/9f/11; post-12 park
  directive unchanged
- 9e placed before 8 so restructure/perf work has a signed baseline
- 14 early as next driving workload (stdlib-shaped, shard-independent)
- story 00-story.md notes point at the sequenced list

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 01:50:03 +02:00
3e22e42da5 docs: iteration 17 forks settled — kind key, internal/ rule (no code)
- fork 1: library-ness manifest-declared, kind = "library", default program
- fork 2: privacy = Go internal/ directory rule, named diagnostic at use
- fork 3: dep-boundary-only scope; Go subtree rule recorded as later tightening
- fork 4: lib+bin dual — library default action is check, explicit build works
- Go-inherited rule pinned: internal type in public signature allowed, no check
- impact analysis added: framework loses --emit workaround, plumbing under
  internal/; compiler = two seams (driver kind + dep-use refusal WO-E1xx)
- VM zero impact by construction: no .wob change, libs compile whole-program
  into consumer image, internal modules still emitted (privacy strips nothing)
- GC zero mechanism impact; pinned: inference stays whole-program, app usage
  can promote dep classes, internal/ invisible to gcinfer — intended, not bug
- board + roadmap rows: needs-refinement -> forks settled, spec/plan next

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 01:45:06 +02:00
f430bff5c4 docs: iteration 17 — library projects + dependency privacy (needs refinement)
Brainstorm outcome, deliberately NOT implemented (developer decision: keep
as an iteration needing further refinement). Records:
- the two gaps iterations 15/16 exposed: library-ness is implicit (a
  no-main project fails woc <dir> build mode — the framework is verified
  via an --emit workaround) and the dep boundary leaks internals (pub has
  no dep-private tier: parse_request is as importable as Handler).
- the conventions corpus: Go (package decides program-ness; cmd/;
  internal/ = directory-shaped privacy, zero keywords) vs Rust ([lib]/
  [[bin]] manifest targets; pub(crate)-family keyword visibility). Doctrine
  fit points at Go's shape with an explicit manifest key (writeonce HAS a
  manifest; explicit beats inference in errors).
- four open forks for the spec: kind declaration form; internal/ vs
  pub(lib) vs export-allowlist; dep-boundary-only vs Go's subtree rule;
  lib+bin duality. Draft acceptance criteria; web-app 14/0 as the
  regression gate. Roadmap + board rows added.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 01:23:10 +02:00
d6025e131d 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
4c75ba4fbd 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
f6b5333d40 docs: iteration 15 closeout (Task 5)
- error catalog: WO-E106 (dependency fetch/shape failures, one code, message
  names dep + step) and WO-E107 (dep/local module-name collision) rows.
- README: a Dependencies subsection under the manifest docs — [deps] syntax,
  .wo-deps/wo.lock behavior, offline-when-locked, --update-deps, flat-only.
- board: iteration 15 row -> landed (deps-accept 8/0), pending row removed;
  story 15 header records the landing; 08-project-structure notes
  .wo-deps (gitignored) + wo.lock (committed); plan checkboxes all ticked.

(One self-inflicted casualty during this task, restored from git before
commit: a buggy doc-edit script truncated 08-project-structure.md; the file
was recovered intact and the intended one-liner applied by hand.)

Gates at closeout: deps-accept 8/0, woc-test 540/0, oop-e2e 87/0,
log-watcher 7/0, employee 8/0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:23:18 +02:00
8fcebe60f9 docs: implementation plan for iteration 15 (deps)
5 tasks, words-only per house rule, each with its verify step: (1) manifest
grows the [deps] section + one-line inline-table value (only under [deps]);
(2) resolver — git-binary fetch into .wo-deps/, wo.lock pinning, warm-path
offline guarantee, drift diagnostic, --update-deps, guard rails (transitive
refusal, non-writeonce dep, name collision WO-E107, all fetch failures
WO-E106); (3) multi-root discovery + module_of prefixing dep roots by dep
name + entry restricted to the app's own files; (4) scripts/deps-accept.sh
gate over file:// remotes (8 checks, network-free) + just recipe; (5) docs
closeout (catalog E106/E107, README deps subsection, board/story/structure).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:11:05 +02:00